3.2.6 bzImage的组合过程

一级推进系统和包括有效载荷的二级推进系统都已就绪,这一节,我们就来讨论一级推进系统和二级推进系统的组合。组合的规则定义在平台的“顶层”Makefile中:

3.2.6 bzImage的组合过程 - 图1

在将各个变量进行替换后,构建bzImage的命令展开为:

3.2.6 bzImage的组合过程 - 图2

Makefile.build将包含在arch/x86/boot目录下的Makefile文件组成为最终的Makefile。构建目标arch/x86/boot/bzImage的规则在arch/x86/boot下的Makefile中:

3.2.6 bzImage的组合过程 - 图3

我们来看看构建bzImage的命令cmd_image,其在arch/x86/boot/Makefile中定义:

3.2.6 bzImage的组合过程 - 图4

根据cmd_image的定义,表面上就是执行程序build,并传递给程序build两个参数,分别是arch/x86/boot目录下的setup.bin和vmlinux.bin,同时将程序build的标准输出stdout重定向到规则的目标($@),即bzImage。那么程序build究竟做了什么呢?我们来看看它的源码:

3.2.6 bzImage的组合过程 - 图5

3.2.6 bzImage的组合过程 - 图6

1)argv[1]对应的是setup.bin,所以第9行代码就是将文件setup.bin打开,第11行代码是将其内容读到数组buf中。由第1行的注释可见,数组buf就是用来存放setup.bin的。

2)argv[2]对应的是vmlinux.bin,所以第13行代码是将文件vmlinux.bin打开。因为vmlinux.bin尺寸较大,build并没有使用与setup.bin相同的方式读取vmlinux.bin,而是将vmlinux.bin映射到build的进程空间中,变量kernel指向了vmlinux.bin映射的基址,如代码第15行所示。也就是说,build通过内存映射的方式读取文件vmlinux.bin。

3)第17行代码是将读取到buf中的setup.bin写入到标准输出(stdout)。而根据cmd_image的定义,build程序已经将其标准输出重定向为bzImage,所以这里并不是将setup.bin显示到屏幕上,而是写入到文件bzImage中。

4)同理第19行代码是将vmlinux.bin写入到文件bzImage中。

可见,程序build就是将setup.bin和vmlinux.bin简单地连接为bzImage。