当前位置: > 华清远见教育科技集团 > 嵌入式学习 > 讲师博文 > Linux内核的编译流程简析
Linux内核的编译流程简析
时间:2016-12-12作者:华清远见

在内核的 Makefile 中会在多处地方看到 FORCE ,比如:
        # vmlinux image - including updated kernel symbols
        vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE

实际上它是一个伪目标:
     nbsp;   PHONY +=FORCE
        FORCE:
        # Declare the contents of the .PHONY variable as phony. We keep that
        # information in a variable so we can use it in if_changed and friends.
        .PHONY: $(PHONY)

从上面看到,FORCE 既没有依赖的规则,其底下也没有可执行的命令。

如果一个规则没有命令或者依赖,而且它的目标不是一个存在的文件名,在执行此规则时,目标总会被认为是新的。也就是说,这个规则一旦被执行,make 就认为它所表示的目标已经被更新过。当将这样的目标(FORCE)作为一个规则的依赖时(如上的 vmlinux: ),由于依赖总被认为是被更新过的,所以作为依赖所在的规则定义的命令总会被执行。

比如上面的 vmlinux: 在每次 make 时,它下面的这些命令总会被执行:
        ifdef CONFIG_HEADERS_CHECK
        $(Q)$(MAKE)-f $(srctree)/Makefile headers_check
        endif
        ifdef CONFIG_SAMPLES
                $(Q)$(MAKE) $(build)=samples
        endif
        ifdef CONFIG_BUILD_DOCSRC
                $(Q)$(MAKE) $(build)=Documentation
        endif
                $(call vmlinux-modpost)
                $(call if_changed_rule,vmlinux__)
                $(Q)rm -f .old_version

zImage是ARM Linux常用的一种压缩映像文件,uImage是U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的"头",说明这个映像文件的类型、加载位置、生成时间、大小等信息。换句话说,如果直接从uImage的0x40位置开始执行,zImage和uImage没有任何区别。另外, Linux2.4内核不支持uImage,Linux2.6内核加入了很多对嵌入式系统的支持,但是uImage的生成也需要设置。

先分析一下zImage的组成。在内核编译完成后会在arch/arm/boot/下生成zImage。

在arch/arm/boot/Makefile中:
        $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
        $(call if_changed,objcopy)
        由此可见,zImage的是elf格式的arch/arm/boot/compressed/vmlinux二进制化得到的
        在arch/armboot/compressed/Makefile中:
        HEAD = head.o
        OBJS = misc.o decompress.o
        $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o /
        $(addprefix $(obj)/, $(OBJS)) FORCE
        $(call if_changed,ld)
        $(obj)/piggy.gz: $(obj)/../Image FORCE
        $(call if_changed,gzip)
        $(obj)/piggy.o: $(obj)/piggy.gz FORCE

piggy.o依赖piggy.gz
        piggy.gz依赖arch/arm/boot/Image
        查看arch/arm/boot/Makefile,得知
        $(obj)/Image: vmlinux FORCE
                $(call if_changed,objcopy)
                @echo ' Kernel: $@ is ready'

其中Image是由内核顶层目录下的vmlinux二进制化后得到的。注意:

arch/arm/boot/compressed/vmlinux是位置无关的,这个有助于理解后面的代码,链接选项中有个 –fpic参数:
        EXTRA_CFLAGS := -fpic

总结一下zImage的组成,它是由一个压缩后的内核piggy.o,连接上一段初始化及解压功能的代码(head.o misc.o decompress.o)组成的。

发表评论
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)