bzImage是怎么来的

 

以x86架构32位机为例,即i386

 

从经典的helloworld程序开始

理解程序的编辑、编译、连接、运行的四个阶段

内核也是使用gcc、ld等工具编译连接出来的,并没有什么神秘之处

只不过文件繁多,代码树庞大而已,超出了大多数人的理解范围

就好像一般人对支配几千或几万块钱还是没有问题的

但是若突然让其支配上亿元时,一般人都是没有概念的

 

使用的工具make、gcc、ld、objdump、readelf、nm、objcopy、gzip等

一些程序的具体参数可以使用man查看具体含义

 

简单的浏览一下Documentation/kbuild目录中的几个文件

这几个文件介绍了内核的构建系统、Makefile的组织层次和一些特殊的命令等

阅读make的手册,了解基本的目标规则

 

编译之前先敲下make help,了解内核提供的一些参数

通过V=1参数显示具体的编译命令

 

内核在编译之前利用Kbuild系统提供的config机制解析各目录的Kconfig文件以便对内核进行剪裁

以make menuconfig为例

由顶层的Makefile开始匹配目标文件%config

解决完一些依赖后会进入scripts/kconfig目录执行子make

匹配scripts/kconfig/Makefile中的menuconfig目标

其依赖为scripts/kconfig/mconf小程序

编译出小程序mconf后,便运行该程序解析各个Kconfig文件

提供一个配置接口

配置完成后mconf便会在顶层目录生成一个.config文件

在编译内核的时候使用该.config文件生成

auto.conf供Makefile决定编译哪些目录

autoconf.h供代码预处理

这也是config机制的2个主要作用

 

使用make的- n、-p选项查看编译命令、变量等

以make bzImage为例

使用内核Makefile提供的参数V=1屏蔽@以便查看编译使用的参数和命令等

 

顶层的Makefile定义一些常用的变量、目录信息等

会包含对应架构下的目录下的Makefile,如arch/x86/Makefile

这样便找到目标bzImage,其依赖为顶层Makefile里的目标vmlinux

 

看下vmlinux的依赖$(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE

1. vmlinux.lds为对应架构的连接脚本,由arch/x86/kernel/vmlinux.lds.S生成

2. $(vmlinux-init)和$(vmlinux-main) 即各个.o与built-in.o文件

3. 这些vmlinux所依赖的.o目标文件由这2条规则

$(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;

$(vmlinux-dirs): prepare scripts

$(Q)$(MAKE) $(build)=$@

通过命令make -f scripts/Makefile.build obj=XXX/XXX编译所有的目录和子目录

总目录的控制由顶层Makefile定义

各个子目录的控制由其所在总目录下的Makfile和scripts/Makefile.lib控制

$(subdir-ym):

$(Q)$(MAKE) $(build)=$@

编译具体代码时都是使用scripts/Makefile.build这个Makefile

各个目录的built-in.o由对应目录下的.o文件连接而成

4. 顶层Makefile的目标vmlinux由rule_vmlinux__ => cmd_vmlinux__中的命令连接而成

 

5 . 解决完依赖vmlinux后

便执行arch/x86/Makefile中的目标bzImage的命令

make -f scripts/Makefile.build obj=arch/x86/boot arch/x86/boot/bzImage


6. 匹配arch/x86/boot/Makefile中的

规则$(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE

依赖2个2进制文件setup.bin和vmlinux.bin

 

7. 使用连接脚本arch/x86/boot/setup.ld生成setup.elf

setup.elf中的.o目标也在arch/x86/boot/Makefile中定义

使用objcopy得到依赖setup.bin

 

8. 含有压缩映像的arch/x86/boot/compressed/vmlinux

由顶层Makefile得到的vmlinux经objcopy得到arch/x86/boot/compressed/vmlinux.bin

使用gzip压缩vmlinux.bin得到vmlinux.bin.gz

使用arch/x86/boot/compressed/mkpiggy小程序得到arch/x86/boot/compressed/piggy.S

由arch/x86/boot/compressed/piggy.S经gcc编译后得到piggy.o

使用连接脚本arch/x86/boot/compressed/vmlinux.lds连接head_32.o、解压代码、…、piggy.o等

得到arch/x86/boot/compressed/vmlinux

 

9. 目标vmlinux.bin则会依赖arch/x86/boot/compressed/vmlinux

即需要先得到含有压缩过的vmlinux映像的连接合成文件

然后使用objcopy得到arch/x86/boot/vmlinux.bin

 

10. 最后使用小程序arch/x86/boot/tools/build将setup.bin和vmlinux.bin合并为bzImage

 

详细的注释请参考git://github.com/kernel-digger/linux-2.6.git

错漏之处还望不吝指出

你可能感兴趣的:(gcc,cmd,脚本,Build,工具,makefile)