们不能现在就编译它,因为这个目标依赖于下面两个头文件:
第一个头文件 voffset.h 是使用 sed 脚本生成的,包含用 nm 工具从 vmlinux 获取的两个地址:
这两个地址是内核的起始和结束地址。第二个头文件 zoffset.h 在 arch/x86/boot/compressed/Makefile 可以看出是依赖于目标 vmlinux的:
目标 $(obj)/compressed/vmlinux 依赖于 vmlinux-objs-y —— 说明需要编译目录 arch/x86/boot/compressed 下的源代码,然后生成 vmlinux.bin、vmlinux.bin.bz2,和编译工具 mkpiggy。我们可以在下面的输出看出来:
vmlinux.bin 是去掉了调试信息和注释的 vmlinux 二进制文件,加上了占用了 u32 (LCTT 译注:即4-Byte)的长度信息的 vmlinux.bin.all 压缩后就是 vmlinux.bin.bz2。其中 vmlinux.bin.all 包含了 vmlinux.bin 和vmlinux.relocs(LCTT 译注:vmlinux 的重定位信息),其中 vmlinux.relocs 是 vmlinux 经过程序 relocs 处理之后的 vmlinux 镜像(见上文所述)。我们现在已经获取到了这些文件,汇编文件 piggy.S 将会被 mkpiggy 生成、然后编译:
这个汇编文件会包含经过计算得来的、压缩内核的偏移信息。处理完这个汇编文件,我们就可以看到 zoffset 生成了:
现在 zoffset.h 和 voffset.h 已经生成了,arch/x86/boot 里的源文件可以继续编译:
所有的源代码会被编译,他们最终会被链接到 setup.elf :
或者:
最后的两件事是创建包含目录 arch/x86/boot/* 下的编译过的代码的 setup.bin:
以及从 vmlinux 生成 vmlinux.bin :
最最后,我们编译主机程序 arch/x86/boot/tools/build.c,它将会用来把 setup.bin 和 vmlinux.bin 打包成 bzImage:
实际上 bzImage 就是把 setup.bin 和 vmlinux.bin 连接到一起。最终我们会看到输出结果,就和那些用源码编译过内核的同行的结果一样:
全部结束。
?
这就是本文的结尾部分。本文我们了解了编译内核的全部步骤:从执行 make 命令开始,到最后生成 bzImage。我知道,linux 内核的 makefile 和构建 linux 的过程第一眼看起来可能比较迷惑,但是这并不是很难。希望本文可以帮助你理解构建 linux 内核的整个流程。
?
via: https://github.com/0xAX/linux-insides/blob/master/Misc/how_kernel_compiled.md
译者:oska874 校对:wxy
本文由 LCTT 原创翻译,Linux中国 荣誉推出
?