内核映像的形成——制作bzImage

本文详细介绍了Linux内核构建过程中制作bzImage的步骤,包括从vmlinux链接生成、去除不必要的ELF头和section、压缩、解压缩以及setup.bin和vmlinux.bin的组合。重点讨论了setup.bin的作用和vmlinux.bin的生成过程,解析了链接脚本和makefile的规则。最终,bzImage由setup.bin和vmlinux.bin拼接而成,前者包含实模式转换代码,后者包含压缩的内核和解压缩程序。

2.2.6 制作bzImage

回到顶层Makefile849行,随着vmlinux的链接工作结束,在主目录下生成了vmlinux文件,vmlinux目标也就结束了。那么就会来到arch/x86/Makefile155bzImage目标。看到这个目标,就知道后面的工作就算打包压缩vmlinux并制作bzImage了。看到156行,因为CONFIG_X86_DECODER_SELFTEST没有设置,所以会直接执行159行以后的命令:

159        $(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)

160        $(Q)mkdir -p $(objtree)/arch/$(UTS_MACHINE)/boot

161        $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/$(UTS_MACHINE)/boot/$@

 

160行是建立一个arch/i386/boot目录,161行是建立一个符号链接,重中之重是159行,其中$(boot)宏来自143行,$(KBUILD_IMAGE)宏来自153所以翻译159行:

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

 

前面提到vmlinux 的入口地址为phys_startup_32,该函数是工作在32-bit 段寻址的保护模式,但是问题是系统自加电那一刻起,就运行于16-bit 实模式。所以我们需要一些辅助程序从16-bit 实模式转到32-bit64-bit保护模式,设置好必须的参数后才能开启分页模式转到32-bit64-bit分页保护模式。前半部分是由arch/x86/boot/setup.bin 实现的,后半部分则是由arch/x86/kernel/head.o实现的。setup.bin除了向保护模式转换外,还有很多其它的事情要做。

 

vmlinux 的链接过程来看vmlinux 是一个已编好的kernel,和普通的ELF 可执行文件没有什么区别:

[root@localhost linux-2.6.34.1]# file ./vmlinux

vmlinux: ELF 32-bit LSB executable, Intel i386, version 1 (SYSV), statically linked, not stripped

 

我们知道,C和汇编源文件被编译成ELF 文件后,通常会包含有连接器(Linker)或加载器(Loader)所需要的ELF headerProgram header tableSection header table。这些ELF header 和一些section 的作用是告诉内核ELF Loader 如何载入ELF 可执行文件。但是, Linux内核作为一种特殊的ELF 文件,没有ELF Loader的帮助,需要特殊辅助程序去装载它。它的装载地址是固定的,前面讲了的,0xC0100000

 

这时,为了保证通用性而存在的ELF header 和一些section对内核的装载就没有意义了。为了使内核尽可能小,可以把这些信息去掉。所以通常采用objcopy命令来去掉原来ELF文件中的headersection,同时转化为raw binary格式的文件。即便如此,通过objcopy 处理过的vmlinux 一般需要压缩以后再重新链接,当然必须把解压缩的程序也同时链接进来。

 

这个压缩的过程着实奇怪:压缩后,然后再解压缩,岂不是浪费启动时间?这还是因为当x86系列处理器启动初期,处于实模式状态,可以寻得的地址空间十分有限,仅仅是1MB,如果内核过大,就无法加载。更新的内核(从2.6.30开始)甚至提供了更高压缩率的格式:bzipLZMA

 

由上面的分析可以看出, bzImage 至少包含kernel booting 辅助程序和压缩的vmlinux。这可以从bzImage 的规则链得到验证:

刚才看到了,arch/x86/Makefile中关于bzImage的规则调用命令为:

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

 

注意:这个命令为Makefile.build 指定了目标arch/x86/boot/bzImage ,而不是使用缺省的__build

 

arch/x86/boot/MakefilebzImage的规则如下:

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

82         $(call if_changed,image)

83         @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'

 

其中obj= arch/x86/boot,所以arch/x86/boot/bzImage 依赖的目标是:arch/x86/boot/setup.binarch/x86/boot/vmlinux.binarch/x86/boot/tools/buildtools/build 已加到<

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值