Linux内核---9.prepare0流程
2016-07-02 14:36
781 查看
linux-2.6.30.4/Makefile中,prepare0的依赖执行完之后,执行:
make -f scripts/Makefile.build obj=.
#执行scripts/Makefile的__build目标,此处只执行always依赖,(KBUILD_BUILTIN=1,但是$(builtin-target) $(lib-target) $(extra-y)都为空,KBUILD_MODULES=0)
always=./include/linux/bounds.h ./include/asm/asm-offsets.h
__build: ./include/linux/bounds.h ./include/asm/asm-offsets.h
:
./include/linux/bounds.h 与./include/asm/asm-offsets.h 这两个依赖的处理过程基本相似。
下面只分析./include/linux/bounds.h的过程。
点击(此处)折叠或打开
linux-2.6.30.4/Kbuild
11 bounds-file := include/linux/bounds.h
38 $(obj)/$(bounds-file): kernel/bounds.s
Kbuild
39
$(Q)mkdir -p $(dir
$@)
40
$(call cmd,bounds)
34 kernel/bounds.s: kernel/bounds.c
FORCE
35
$(Q)mkdir -p $(dir
$@)
36
$(call if_changed_dep,cc_s_c)
目标include/linux/bounds.h在linux-2.6.30.4/Kbuild中,它的执行流程如下:
1. L34 mkdir -p kernel
2. L36 $(call if_changed_dep, cc_s_c),如果kernel/bounds.c有更新,则重新编译kernel/bounds.c,并将编译命令显示在终端,最后将编译命令写到文件.bounds.s.cmd.o中
3. kernel/bounds.s依赖完成之后,执行include/linux/bounds.h目标
4. L39 mkdir -p include/linux
5. $(call cmd, bounds) ,生成include/linux/bounds.h头文件
下面分析一下第2步: $(call if_changed_dep,cc_s_c)
点击(此处)折叠或打开
linux-2.6.30.4/scripts/Kbuild.include
197 # Execute the command and also postprocess generated .d dependencies file.
198 if_changed_dep = $(if $(strip
$(any-prereq) $(arg-check) ), \
199 @set -e; \
200 $(echo-cmd) $(cmd_$(1)); \
201 scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;\
202 rm -f $(depfile); \
203 mv -f $(dot-target).tmp
$(dot-target).cmd)
2.1 $(if $(strip $(any-prereq) $(arg-check) ) #如果目标有更新,则执行条件后面的东东
2.2 $(echo-cmd) 打印编译命令
2.3 $(cmd_cc_s_c) 在linux-2.6.30.4/scripts/Makefile.build中定义cmd_cc_s_c = $(CC) $(c_flags) -fverbose-asm
-S -o $@ $<,这里面有-S,是将c文件转为.s文件,也就是常说的汇编阶段。
2.4 将kernel/bounds.c的汇编和编译所需的头文件统统写进文件kernel/.bounds.s.d.tmp中
2.5 删除kernel/.bounds.s.d
2.6 将kernel/.bounds.s.d.tmp 重命名为kernel/.bounds.s.d.cmd
2.1.1 突然想起小学时写作文老师说的总分方式:
点击(此处)折叠或打开
linux-2.6.30.4/scripts/Kbuild.include
L189 any-prereq = $(filter-out
$(PHONY),$?) $(filter-out
$(PHONY) $(wildcard $^),$^)
#检查目标代码是否有更新,如果有更新返回值不为空
177 arg-check = $(strip $(filter-out
$(cmd_$(1)), $(cmd_$@)) \
178 $(filter-out $(cmd_$@), $(cmd_$(1))) )
#检查参数是否改变,若有改变,返回值不为空
2.2.1 $(echo-cmd)
打印编译命令
点击(此处)折叠或打开
linux-2.6.30.4/scripts/Kbuild.include
24 # Escape single quote for use in echo statements
25 escsq = $(subst $(squote),'\$(squote)',$1)
155 # Short version is used, if $(quiet) equals `quiet_', otherwise full one.
156 echo-cmd = $(if $($(quiet)cmd_$(1)),\
157 echo ' $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)
linux-2.6.30.4/Makefile控制quiet的值,此处为空,1是指cc_s_c,如果cmd_cc_s_c执行成功,就打印$(cmd_cc_s_c)即具体的编译过程到命令行。
这地方有点想不明白,if后面 $(cmd_cc_s_c)要执行一次,$(echo-cmd)执行完后又有一个$(cmd_$(1)),难不成$(cmd_cc_s_c)要执行两次?
噢,想错了!下面是GNU
`make'对if的说明 “$(if condition,then-part[,else-part]) The first argument, condition,
first has all preceding and trailing whitespace stripped, then is expanded. If it expands to any non-empty string, then the condition is considered to be true. If it expands to an empty string, the condition is considered to be false.” 对于第一个参数:condition,首先去掉前面和尾部的空格,然后把条件语句展开。如果展开后是一个不为空的string,那么这个条件就被认为是true,反之是一个空string,
认为是false.
2.3.1 $(cmd_cc_s_c) 即$(CC)
$(c_flags) -fverbose-asm -S -o $@ $<,具体的编译过程
2.4.1 scripts/basic/fixdep这个东东在make
menuconfig/silentconfig中己经生成,具体是什么作用没有看,感觉是把.c文件需要的include重定向到另一个文件中。
5.1 $(call cmd, bounds)的过程
点击(此处)折叠或打开
linux-2.6.30.4/scripts/Kbuild.include
154 # echo command.
155 # Short version is used,if $(quiet)
equals `quiet_', otherwise full one.
156 echo-cmd
= $(if $($(quiet)cmd_$(1)),\
157 echo ' $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)
158
159 # printing commands
160 cmd = @$(echo-cmd)
$(cmd_$(1))
cmd= @$(echo-cmd)
$(cmd_$(1))
先是打印命令这个,然后执行$(cmd_bounds)
点击(此处)折叠或打开
linux-2.6.30.4/Kbuild
17 define cmd_bounds
18 (set -e; \
19 echo "#ifndef __LINUX_BOUNDS_H__"; \
20 echo "#define __LINUX_BOUNDS_H__"; \
21 echo "/*"; \
22 echo " * DO NOT MODIFY."; \
23 echo " *"; \
24 echo " * This file was generated by Kbuild"; \
25 echo " *"; \
26 echo " */"; \
27 echo ""; \
28 sed -ne $(sed-y) $<; \
29 echo ""; \
30 echo "#endif" ) > $@
31 endef
$@ 是 include/linux/bounds.h
$< 是 kernel/bounds.s
这个宏简单一点就是: echo "something" > include/linux/bounds.h,将一些文本写入到include/linux/bounds.h中
点击(此处)折叠或打开
linux-2.6.30.4/Kbuild
54 define sed-y
55 "/^->/{s:->#\(.*\):/* \1 */:; \
56 s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
57 s:->::; p;}"
58 endef
sed将kernel/bounds.s中以->开头的行进行处理,将行
->NR_PAGEFLAGS #21 __NR_PAGEFLAGS @ 替换为
#define NR_PAGEFLAGS 21 /* __NR_PAGEFLAGS @ */
make -f scripts/Makefile.build obj=.
#执行scripts/Makefile的__build目标,此处只执行always依赖,(KBUILD_BUILTIN=1,但是$(builtin-target) $(lib-target) $(extra-y)都为空,KBUILD_MODULES=0)
always=./include/linux/bounds.h ./include/asm/asm-offsets.h
__build: ./include/linux/bounds.h ./include/asm/asm-offsets.h
:
./include/linux/bounds.h 与./include/asm/asm-offsets.h 这两个依赖的处理过程基本相似。
下面只分析./include/linux/bounds.h的过程。
点击(此处)折叠或打开
linux-2.6.30.4/Kbuild
11 bounds-file := include/linux/bounds.h
38 $(obj)/$(bounds-file): kernel/bounds.s
Kbuild
39
$(Q)mkdir -p $(dir
$@)
40
$(call cmd,bounds)
34 kernel/bounds.s: kernel/bounds.c
FORCE
35
$(Q)mkdir -p $(dir
$@)
36
$(call if_changed_dep,cc_s_c)
目标include/linux/bounds.h在linux-2.6.30.4/Kbuild中,它的执行流程如下:
1. L34 mkdir -p kernel
2. L36 $(call if_changed_dep, cc_s_c),如果kernel/bounds.c有更新,则重新编译kernel/bounds.c,并将编译命令显示在终端,最后将编译命令写到文件.bounds.s.cmd.o中
3. kernel/bounds.s依赖完成之后,执行include/linux/bounds.h目标
4. L39 mkdir -p include/linux
5. $(call cmd, bounds) ,生成include/linux/bounds.h头文件
下面分析一下第2步: $(call if_changed_dep,cc_s_c)
点击(此处)折叠或打开
linux-2.6.30.4/scripts/Kbuild.include
197 # Execute the command and also postprocess generated .d dependencies file.
198 if_changed_dep = $(if $(strip
$(any-prereq) $(arg-check) ), \
199 @set -e; \
200 $(echo-cmd) $(cmd_$(1)); \
201 scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;\
202 rm -f $(depfile); \
203 mv -f $(dot-target).tmp
$(dot-target).cmd)
2.1 $(if $(strip $(any-prereq) $(arg-check) ) #如果目标有更新,则执行条件后面的东东
2.2 $(echo-cmd) 打印编译命令
2.3 $(cmd_cc_s_c) 在linux-2.6.30.4/scripts/Makefile.build中定义cmd_cc_s_c = $(CC) $(c_flags) -fverbose-asm
-S -o $@ $<,这里面有-S,是将c文件转为.s文件,也就是常说的汇编阶段。
2.4 将kernel/bounds.c的汇编和编译所需的头文件统统写进文件kernel/.bounds.s.d.tmp中
2.5 删除kernel/.bounds.s.d
2.6 将kernel/.bounds.s.d.tmp 重命名为kernel/.bounds.s.d.cmd
2.1.1 突然想起小学时写作文老师说的总分方式:
点击(此处)折叠或打开
linux-2.6.30.4/scripts/Kbuild.include
L189 any-prereq = $(filter-out
$(PHONY),$?) $(filter-out
$(PHONY) $(wildcard $^),$^)
#检查目标代码是否有更新,如果有更新返回值不为空
177 arg-check = $(strip $(filter-out
$(cmd_$(1)), $(cmd_$@)) \
178 $(filter-out $(cmd_$@), $(cmd_$(1))) )
#检查参数是否改变,若有改变,返回值不为空
2.2.1 $(echo-cmd)
打印编译命令
点击(此处)折叠或打开
linux-2.6.30.4/scripts/Kbuild.include
24 # Escape single quote for use in echo statements
25 escsq = $(subst $(squote),'\$(squote)',$1)
155 # Short version is used, if $(quiet) equals `quiet_', otherwise full one.
156 echo-cmd = $(if $($(quiet)cmd_$(1)),\
157 echo ' $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)
linux-2.6.30.4/Makefile控制quiet的值,此处为空,1是指cc_s_c,如果cmd_cc_s_c执行成功,就打印$(cmd_cc_s_c)即具体的编译过程到命令行。
这地方有点想不明白,if后面 $(cmd_cc_s_c)要执行一次,$(echo-cmd)执行完后又有一个$(cmd_$(1)),难不成$(cmd_cc_s_c)要执行两次?
噢,想错了!下面是GNU
`make'对if的说明 “$(if condition,then-part[,else-part]) The first argument, condition,
first has all preceding and trailing whitespace stripped, then is expanded. If it expands to any non-empty string, then the condition is considered to be true. If it expands to an empty string, the condition is considered to be false.” 对于第一个参数:condition,首先去掉前面和尾部的空格,然后把条件语句展开。如果展开后是一个不为空的string,那么这个条件就被认为是true,反之是一个空string,
认为是false.
2.3.1 $(cmd_cc_s_c) 即$(CC)
$(c_flags) -fverbose-asm -S -o $@ $<,具体的编译过程
2.4.1 scripts/basic/fixdep这个东东在make
menuconfig/silentconfig中己经生成,具体是什么作用没有看,感觉是把.c文件需要的include重定向到另一个文件中。
5.1 $(call cmd, bounds)的过程
点击(此处)折叠或打开
linux-2.6.30.4/scripts/Kbuild.include
154 # echo command.
155 # Short version is used,if $(quiet)
equals `quiet_', otherwise full one.
156 echo-cmd
= $(if $($(quiet)cmd_$(1)),\
157 echo ' $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)
158
159 # printing commands
160 cmd = @$(echo-cmd)
$(cmd_$(1))
cmd= @$(echo-cmd)
$(cmd_$(1))
先是打印命令这个,然后执行$(cmd_bounds)
点击(此处)折叠或打开
linux-2.6.30.4/Kbuild
17 define cmd_bounds
18 (set -e; \
19 echo "#ifndef __LINUX_BOUNDS_H__"; \
20 echo "#define __LINUX_BOUNDS_H__"; \
21 echo "/*"; \
22 echo " * DO NOT MODIFY."; \
23 echo " *"; \
24 echo " * This file was generated by Kbuild"; \
25 echo " *"; \
26 echo " */"; \
27 echo ""; \
28 sed -ne $(sed-y) $<; \
29 echo ""; \
30 echo "#endif" ) > $@
31 endef
$@ 是 include/linux/bounds.h
$< 是 kernel/bounds.s
这个宏简单一点就是: echo "something" > include/linux/bounds.h,将一些文本写入到include/linux/bounds.h中
点击(此处)折叠或打开
linux-2.6.30.4/Kbuild
54 define sed-y
55 "/^->/{s:->#\(.*\):/* \1 */:; \
56 s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
57 s:->::; p;}"
58 endef
sed将kernel/bounds.s中以->开头的行进行处理,将行
->NR_PAGEFLAGS #21 __NR_PAGEFLAGS @ 替换为
#define NR_PAGEFLAGS 21 /* __NR_PAGEFLAGS @ */
相关文章推荐
- Linux内核---8.filechk函数分析
- 探索linux管道的容量
- Linux内核---7.Makefile学习笔记
- Linux内核---6.make menuconfig 流程分析
- Linux内核---5.Makefile显示打印信息
- Linux内核---4.产生内核head.s反汇编文件
- Linux内核---3.linux 内核zImage生成过程
- Linux内核---2.TQ2440系统移植出现的问题总结
- Linux内核---1.TQ2440使用总结
- Linux netstat命令
- Linux(Ubuntu)下MySQL的安装与配置
- Linux 下五个顶级的开源命令行 Shell
- 交叉编译环境
- linux 学习 设置固定网Ip
- 31.每日一个Linux命令----wc
- windows下安装linux/ubantu
- linux 备份工具
- centos升级python
- 你应该丢弃 Windows,选择 Linux 的五大理由
- python之window编译脚本在Linux执行