3.2.4 vmlinux.bin的构建过程(3)
mkpiggy向屏幕打印了一堆文本。习惯上,我们会认为标准输出就是屏幕,但是回头再仔细观察一下cmd_mkpiggy的定义,其将标准输出重定向到了文件piggy.S,所以这里printf实际上是在组织汇编语句,然后输出到piggy.S中。也就是说,mkpiggy就是在“写”一个汇编程序。
根据代码可见,这个piggy.S非常简单,其使用汇编指令incbin将压缩的有效载荷vmlinux.bin.gz不加更改地直接包含进来。除了包含了压缩的内核映像外,piggy.S中还定义了解压vmlinux.bin.gz时需要的各种信息,包括压缩映像的长度、解压后的长度等,在解压内核时,解压代码将需要这些信息。下面是mkpiggy生成的一个具体的piggy.S示例:
.section ".rodata..compressed","a",@progbits
.globl z_input_len
z_input_len=1721557
.globl z_output_len
z_output_len=3421472
.globl z_extract_offset
z_extract_offset=0x1b0000
.globl z_extract_offset_negative
z_extract_offset_negative= -0x1b0000
.globl input_data, input_data_end
input_data:
.incbin "arch/x86/boot/compressed/vmlinux.bin.gz"
input_data_end:
终于结束了这个让人眩晕的过程,让我们来回顾一下vmlinux.bin的构建过程:
1)kbuild使用objcopy,将顶层Makefile构建好的内核映像vmlinux复制到arch/x86/boot/compressed目录下,删除了“.comment”段、符号表和重定位表,并命名为vmlinux.bin;
2)kbuild压缩内核映像vmlinux.bin,笔者采用默认的压缩方式gzip,所以压缩后的内核映像为vmlinux.bin.gz;
3)kbuild借助内核自带的程序mkpiggy构建一个汇编程序piggy.S,该汇编程序就是vmlinux.bin.gz加上一些解压内核时需要的信息;
4)kbuild将head_32.o、misc.o以及包含压缩映像的piggy.o等目标文件链接为vmlinux.bin,保存到arch/x86/boot目录下。
可见,vmlinux.bin由压缩的vmlinux加上以head_32.o为代表的一小部分非压缩代码组成。vmlinux就是我们提到的有效载荷,而这部分非压缩代码就是我们所谓的二级推进系统。
【责任编辑:book TEL:(010)68476606】
点赞 0