点击(此处)折叠或打开
- linux-2.6.30.4/Makefile
- 284 #config-targets=0, mixed-targets=0, dot-config=1,不会进入L285
- 285 ifeq ($(mixed-targets),1) #不成立跳过
- ...
- 291 ifeq ($(config-targets),1) #不成立跳过
- 304 else
- 305
- 306 ifeq ($(KBUILD_EXTMOD),)
- ......
- 354 include $(srctree)/arch/$(SRCARCH)/Makefile
在 arch/arm/Makefile中包含了zImage
点击(此处)折叠或打开
- linux-2.6.30.4/arch/arm/Makefile
-
174 ifeq ($(CONFIG_XIP_KERNEL),y)
-
175 KBUILD_IMAGE := xipImage
-
176 else
-
177 KBUILD_IMAGE := zImage
-
178 endif
-
179
-
180 all: $(KBUILD_IMAGE)
-
181
-
182 boot := arch/arm/boot
-
183
-
193 zImage Image xipImage bootpImage uImage: vmlinux
- 194 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
- #zImage依赖于vmliux, vmliux在linux-2.6.30.4/Makefile中
1. linux-2.6.30.4/Makefile 中包含了arch/arm/Makefile
2. 在 arch/arm/Makefile中找到目标zImage
3. zImage依赖linux-2.6.30.4中的Makefile中vmlinux
4. 分析 linux-2.6.30.4/Makefile中vmlinux的依赖
5.
就第4步进行具体分析
点击(此处)折叠或打开
-
306 ifeq ($(KBUILD_EXTMOD),)
-
307 PHONY += scripts
-
308 scripts: scripts_basic include/config/auto.conf
-
309 $(Q)$(MAKE) $(build)=$(@)
-
310
-
311 init-y := init/
-
312 drivers-y := drivers/ sound/ firmware/
-
313 net-y := net/
-
314 libs-y := lib/
-
315 core-y := usr/
-
316 endif # KBUILD_EXTMOD
-
317
-
318 ifeq ($(dot-config),1)
-
319 -include include/config/auto.conf
-
320
-
321 ifeq ($(KBUILD_EXTMOD),)
-
322 -include include/config/auto.conf.cmd
-
323
-
324 $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
-
325
-
326 include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
-
327 $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
-
328 else
-
329 PHONY += include/config/auto.conf
-
330
-
331 include/config/auto.conf:
-
332 $(Q)test -e include/linux/autoconf.h -a -e $@ || ( \
-
333 echo; \
-
334 echo " ERROR: Kernel configuration is invalid."; \
-
335 echo " include/linux/autoconf.h or $@ are missing."; \
-
336 echo " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
-
337 echo; \
-
338 /bin/false)
-
339
-
340 endif # KBUILD_EXTMOD
-
- #vmliux的依赖vmlinux-lds=arch/arm/kernel/vmlinux.lds vmlinux-init=arch/arm/kernel/head-nommu.o arch/arm/ kernel/init_task.o init/built-in.o vmlinux-main= usr/built-in.o arch/arm/kernel/built-in.o arch/arm/mm/built-in.o arch/arm/common/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o security/ built-in.o crypto/built-in.o block/built-in.o arch/arm/lib/lib.a lib/lib.a arch/arm/lib/built-in.o lib/ built-in.o drivers/built-in.o sound/built-in.o firmware/built-in.o net/built-in.o kallsyms=
-
576 vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE
- #vmlinux-lds等 依赖于vmlinux-dirs
-
598 $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
-
-
601 PHONY += $(vmlinux-dirs)
-
602 $(vmlinux-dirs): prepare scripts
-
603 $(Q)$(MAKE) $(build)=$@
-
-
636 prepare3: include/config/kernel.release
-
649
-
650 prepare2: prepare3 outputmakefile
-
651
-
652 prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \
-
653 include/asm include/config/auto.conf
-
654 $(cmd_crmodverdir)
-
655
-
656 archprepare: prepare1 scripts_basic
-
657
-
658 prepare0: archprepare FORCE
-
659 $(Q)$(MAKE) $(build)=.
-
660 $(Q)$(MAKE) $(build)=. missing-syscalls
-
661
- 662 prepare: prepare0
- 整理一下上述的各个依赖关系,如下图所示
- 下面按照执行的顺序详细分析一下,各个步骤:
- 4.1 首先执行的是scripts的过程:
-
这个过程类似于make menuconfig的过程,只不过最后调用的是:conf -s ,不产生图形界面。
点击(此处)折叠或打开
-
scrpts的过程:
-
326 include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
-
327 $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
-
即: make -f /root/kernel/linux-2.6.30.4/Makefile silentoldconfig
-
make -f scripts/Makefile.build obj=scripts/basic
-
mkdir -p include/linux include/config
-
make -f scripts/Makefile.build obj=scripts/kconfig silentoldconfig
- scripts/kconfig/conf -s arch/arm/Kconfig
-
scrpts的过程:
- 4.2 其次执行的是prepare的过程:
-
4.3 vmlinux-dirs的依赖执行完了之后,再去执行vmlinux-dirs的命令了
点击(此处)折叠或打开
-
linux-2.6.30.4/Makefile 中archprepare: prepare1 scripts_basic
-
而在
-
arch/arm/Makefile中archprepare: maketools
-
这地方有点没有看明白,在Makefile和arch/arm/Makefile中都有archprepare的规则,
-
什么这两个都执行了,而不是一个覆盖另一个?
-
-
linux-2.6.30.4/Makefile
-
714 include/linux/version.h: $(srctree)/Makefile FORCE
-
715 $(call filechk,version.h)
-
这将会调用linux-2.6.30.4/scripts/Kbuild.include中的filechk函数,主要作用是:用Makefile中的版本信息更新include/linux/version.h中的版本信息。
-
-
arch/arm/Makefile
-
$(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h
-
即: make -f scripts/Makefile.build obj=arch/arm/tools include/asm-arm/mach-types.h
-
这会调用arch/arm/tools/Makefile中的规则产生include/asm-arm/mach-types.h 文件
-
-
linux-2.6.30.4/Makefile
-
628 include/config/kernel.release: include/config/auto.conf FORCE
-
629 $(Q)rm -f $@
-
630 $(Q)echo $(kernelrelease) > $@
-
这会产生kernel.release文件: echo 2.6.30.4-EmbedSky > include/config/kernel.release
-
-
linux-2.6.30.4/Makefile
-
717 include/linux/utsrelease.h: include/config/kernel.release FORCE
-
718 $(call filechk,utsrelease.h)
- 这将会调用linux-2.6.30.4/scripts/Kbuild.include中的filechk函数,主要是检查include/config/kernel.release中的kernel版本信息是否超过64字节,超过则报错。
-
-
linux-2.6.30.4/Makefile
-
693 include/asm: FORCE
-
694 $(Q)$(check-symlink)
-
695 $(Q)$(create-symlink)
-
#刚生出来(下载)的内核代码是不存在include/asm目录的,check-symlink是检查include/asm是存在并指向asm-arm,如果不存在asm-arm的符号连接则创建,存在但不正确就打印出错信息。
-
-
linux-2.6.30.4/Makefile
-
prepare1的最后执行 $(cmd_crmodverdir)
-
1146 cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \
-
1147 $(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*)
-
即:mkdir -p .tmp_versions
-
-
linux-2.6.30.4/Makefile
-
archprepare的第二个依赖 scripts_basic
-
即:make -f scripts/Makefile.build obj=scripts/basic
-
-
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
- :
- 这将会编译kernel/bounds.c 和 arch/arm/kernel/asm-offsets.c两个文件
4.4 vmlinux的两个依赖: vmlinux.o与$(kallsyms.o)点击(此处)折叠或打开
-
linux-2.6.30.4/Makefile
-
880 PHONY += $(vmlinux-dirs)
-
881 $(vmlinux-dirs): prepare scripts
-
882 $(Q)$(MAKE) $(build)=$@
-
由于命令中用到$@即vmlinux-dirs先转到vmlinux-dirs的定义处:
-
- linux-2.6.30.4/Makefile
-
653 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
-
654 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
-
655 $(net-y) $(net-m) $(libs-y) $(libs-m)))
-
可以看到vmlinux-dirs是:
-
vmlinux-dirs=init usr arch/arm/kernel arch/arm/mm arch/arm/common arch/arm/mach-s3c2410 arch/arm/mach-s3c2400 arch/arm/mach-s3c2412 arch/arm/mach-s3c2440 arch/arm/mach-s3c2442 arch/arm/mach-s3c2443 arch/arm/plat-s3c24xx arch/arm/plat-s3c kernel mm fs ipc security crypto block drivers sound firmware net arch/arm/lib lib
-
这就是要去内核的每一个目录下面去编译需要的每一个源文件了
-
-
make -f scripts/Makefile.build obj=init
-
#builtin-target=init/built-in.o lib-target= extra-y= subdir-ym= always=
-
-
linux-2.6.30.4/scripts/Makefile.build
-
93 __build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
-
94 $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
-
95 $(subdir-ym) $(always)
-
96 @:
-
#此时只有builtin-target=init/built-in.o有定义,下一步生成目标builtin-target
-
-
linux-2.6.30.4/scripts/Makefile.build
-
286 ifdef builtin-target
-
287 quiet_cmd_link_o_target = LD $@
-
288 # If the list of objects to link is empty, just create an empty built-in.o
-
289 cmd_link_o_target = $(if $(strip $(obj-y)),\
-
290 $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^) \
-
291 $(cmd_secanalysis),\
-
292 rm -f $@; $(AR) rcs $@)
-
293
-
294 $(builtin-target): $(obj-y) FORCE
-
295 $(call if_changed,link_o_target)
-
-
#先去执行builtin-target的依赖obj-y,将所以.c编译为.o, .s编译为.o
-
obj-y=init/main.o init/version.o init/mounts.o init/noinitramfs.o init/calibrate.o
-
ld
-
把obj-y链接成init/built-in.o
-
目标vmlinux-dirs执行完成后,built-in.o
-
-
$(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
- 因为这个指令是一个空指令,所以当vmlinux-dirs执行完成之后,vmlinux的依赖$(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds)都准备好了。
点击(此处)折叠或打开
-
4.4.1 vmlinux的一个依赖是:vmlinux.o
-
linux-2.6.30.4/Makefile
-
866 vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE
-
867 $(call if_changed_rule,vmlinux-modpost)
-
-
linux-2.6.30.4/scripts/Kbuild.include
-
208 if_changed_rule = $(if $(strip $(any-prereq) $(arg-check) ), \
-
209 @set -e; \
-
210 $(rule_$(1)))
-
#如果目标有更新则执行rule_vmlinux-modpost
-
linux-2.6.30.4/Makefile
-
838 define rule_vmlinux-modpost
-
839 :
-
840 +$(call cmd,vmlinux-modpost)
-
841 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
-
842 $(Q)echo 'cmd_$@ := $(cmd_vmlinux-modpost)' > $(dot-target).cmd
-
843 endef
-
-
linux-2.6.30.4/Makefile
-
834 quiet_cmd_vmlinux-modpost = LD $@
-
835 cmd_vmlinux-modpost = $(LD) $(LDFLAGS) -r -o $@ \
-
836 $(vmlinux-init) --start-group $(vmlinux-main) --end-group \
-
837 $(filter-out $(vmlinux-init) $(vmlinux-main) FORCE ,$^)
-
#首先链接生成vmlinux.o: L834 arm-linux-ld -EL -r -o vmlinux.o
-
然后执行:make -f /root/kernel/linux-2.6.30.4/scripts/Makefile.modpost vmlinux.o,
-
最后把链接生成vmlinux.o的过程打印到.cmd文件中
-
-
linux-2.6.30.4/scripts/Makefile.modpost
-
103 vmlinux.o: FORCE
-
104 @rm -fr $(kernelmarkersfile)
-
105 $(call cmd,kernel-mod)
-
然后执行:
-
101 cmd_kernel-mod = $(modpost) $@
-
即:scripts/mod/modpost -o /root/kernel/linux-2.6.30.4/Module.symvers -S -c vmlinux.o
- 用scripts/mod/modpost处理vmlinux.o,得到Module.symvers,这个具体有什么作用现在还没有搞清楚。
-
-
-
4.4.2 vmlinux的一个依赖是:$(kallsyms.o)=.tmp_kallsyms2.o
-
801 .tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
-
802 $(call if_changed_dep,as_o_S)
-
-
.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
-
依赖中又含有%.o: %.S ? 没看明白
-
看到打印中: /opt/EmbedSky/4.3.3/bin/arm-none-linux-gnueabi-nm -n .tmp_vmlinux2 | scripts/kallsyms > .tmp_kallsyms2.S
-
然后通过: arm-linux-gcc $(a_flags) -c -o .tmp_kallsyms2.o .tmp_kallsyms2.S
-
-
linux-2.6.30.4/scripts/Kbuild.include
-
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)
-
-
#执行cmd_as_o_S
-
linux-2.6.30.4/scripts/Makefile
- 1580 cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
-
linux-2.6.30.4/Makefile 中archprepare: prepare1 scripts_basic
-
4.5 当vmlinux的所有依赖都ok之后,执行vmlinux的命令
5. 生成最终的zImage点击(此处)折叠或打开
-
845 # vmlinux image - including updated kernel symbols
-
846 vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE
-
847 ifdef CONFIG_HEADERS_CHECK
-
848 $(Q)$(MAKE) -f $(srctree)/Makefile headers_check
-
849 endif
-
850 ifdef CONFIG_SAMPLES
-
851 $(Q)$(MAKE) $(build)=samples
-
852 endif
-
853 ifdef CONFIG_BUILD_DOCSRC
-
854 $(Q)$(MAKE) $(build)=Documentation
-
855 endif
-
856 $(call vmlinux-modpost)
-
857 $(call if_changed_rule,vmlinux__)
-
858 $(Q)rm -f .old_version
-
-
#CONFIG_HEADERS_CHECK CONFIG_SAMPLES CONFIG_BUILD_DOCSRC都为空,所以
-
4.5.1 $(call vmlinux-modpost) ;没找到定义
-
4.5.2 $(call if_changed_rule,vmlinux__) ;具体分析
- 4.5.3 $(Q)rm -f .old_version
-
-
- linux-2.6.30.4/scripts/Kbuild.include
- 208 if_changed_rule = $(if $(strip $(any-prereq) $(arg-check) ), \
- 209 @set -e; \
- 210 $(rule_$(1)))
- #如果目标有更新则执行rule_vmlinux__
-
- linux-2.6.30.4/Makefile
- 731 define rule_vmlinux__
- 732 :
- 733 $(if $(CONFIG_KALLSYMS),,+$(call cmd,vmlinux_version))
- 734
- 735 $(call cmd,vmlinux__)
- 736 $(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
- 737
- 738 $(Q)$(if $($(quiet)cmd_sysmap), \
- 739 echo ' $($(quiet)cmd_sysmap) System.map' &&) \
- 740 $(cmd_sysmap) $@ System.map; \
- 741 if [ $$? -ne 0 ]; then \
- 742 rm -f $@; \
- 743 /bin/false; \
- 744 fi;
- 745 $(verify_kallsyms)
- 746 endef
- L733行 CONFIG_KALLSYMS=y,所以不做任何操作
- L735行 在linux-2.6.30.4/scripts/Kbuild.include L160 cmd = @$(echo-cmd) $(cmd_$(1)),打印并执行cmd_vmlinux__
-
- linux-2.6.30.4/Makefile
- 704 quiet_cmd_vmlinux__ ?= LD $@
- 705 cmd_vmlinux__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ \
- 706 -T $(vmlinux-lds) $(vmlinux-init) \
- 707 --start-group $(vmlinux-main) --end-group \
- 708 $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o FORCE ,$^)
- #链接生成vmlinux的过程:
-
L735 arm-linux-ld
-o vmlinux -Tarch/arm/kernel/vmlinux.lds - L736 将链接生成vmlinux的过程写入到.cmd中
- L738 在linux-2.6.30.4/Makefile中 L724 cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap
-
- .scripts/mksysmap System.map
- ./scripts/mksysmap vmlinux System.map
- if [ $? -ne 0 ];
- then rm -f vmlinux;
- /bin/false;
- fi
-
- L858 rm -f .old_version
终于完成了,zImage的过程,不容易啊!点击(此处)折叠或打开
-
终于zImage的依赖vmlinux执行完了,下面回到arch/arm/Makefile中执行zImge的命令过程:
- linux-2.6.30.4/arch/am/Makefile
-
230 zImage Image xipImage bootpImage uImage: vmlinux
-
231 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
-
#make -f scripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/mach-s3c2410/ arch/arm/boot/zImage
-
-
#执行arch/arm/boot/Makefile中的zImage
-
linux-2.6.30.4/arch/arm/boot/Makefile
-
56 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
-
57 $(call if_changed,objcopy)
-
58 @cp -f arch/arm/boot/zImage zImage.bin
-
59 @echo ' Kernel: $@ is ready'
-
首先生成arch/arm/boot/compress/vmlinux
-
-
linux-2.6.30.4/arch/arm/boot/Makefile中
-
53 $(obj)/compressed/vmlinux: $(obj)/Image FORCE
-
54 $(Q)$(MAKE) $(build)=$(obj)/compressed $@
-
make -f scripts/Makefile.build obj=arch/arm/boot/compressed arch/arm/boot/compressed/vmlinux
-
-
执行arch/arm/boot/compress/Makefile
-
linux-2.6.30.4/arch/arm/boot/compressed/Makefile
-
94 $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
-
95 $(addprefix $(obj)/, $(OBJS)) FORCE
-
96 $(call if_changed,ld)
-
97 @:
-
-
#arm-linux-gcc
-c -o arch/arm/boot/compressed/head.o arch/arm/boot/compressed/hea d.S
-
linux-2.6.30.4/arch/arm/boot/compressed/Makefile
-
102 $(obj)/piggy.o: $(obj)/piggy.gz FORCE
-
gzip -f -9 < arch/arm/boot/compressed/../Image > arch/arm/boot/compressed/piggy.gz
-
piggy.o
-
#arm-linux-gcc
-c -o arch/arm/boot/compressed/piggy.o arch/arm/boot/compressed/piggy.S
-
-
#arm-linux-gcc
-c -o arch/arm/boot/compressed/misc.o arch/arm/boot/compressed/misc.c
-
-
#arm-linux-ld
-T arch/arm/boot/compressed/vmlinux.lds compressed/head.o piggy.o misc.o -o arch/arm/boot/compressed/vmlinux
-
-
linux-2.6.30.4/arch/arm/boot/Makefile
-
56 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
-
57 $(call if_changed,objcopy)
-
58 @cp -f arch/arm/boot/zImage zImage.bin
-
59 @echo ' Kernel: $@ is ready'
-
#好了compressed/vmlinux也生成了,最后一步$(call if_changed, objcopy)
-
-
linux-2.6.30.4/scripts/Kbuild.include
-
192 if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
-
193 @set -e; \
-
194 $(echo-cmd) $(cmd_$(1)); \
-
195 echo 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)
-
#打印并执行$(cmd_objcopy),最后把$(cmd_objcopy)写到.cmd文件中
-
-
linux-2.6.30.4/scripts/Makefile.lib
-
184 quiet_cmd_objcopy = OBJCOPY $@
-
185 cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
-
即:arm-linux-objcopy -O binary -R .note -R .note.gnu.build-id -R .comment -S arch/arm/boot/compressed/vmlinux arch/arm/boot/zImage
- 将vmlinux这个elf的二进制文件,转换为raw二进制文件。
-
845 # vmlinux image - including updated kernel symbols
- 【参考文章】:
- 1. linux zImage生成过程详解 http://blog.csdn.net/boyskung/article/details/3616211
- 2. gnu make manual
- 3. 曲径通幽论坛的大作