bzImage构成--pre-kexec linux2.6.27
时间:2009-03-30 来源:hylpro
2009/1/12 this is a magic how does bzImage include the compressed kernel arch/x86/boot/compressed/Makefile , 如下两行 LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE $(call if_changed,ld) arch/x86/boot/compressed/vmlinux.scr 内容如下 SECTIONS { .rodata.compressed : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) output_len = . - 4; input_data_end = .; } } 就是在修改后调用 ld -r --format binary --oformat elf32-i386 -T $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE (先不管FORCE吧) 其作用就是将 vmlinux.bin.gz 放到bzimage的自定义段 .rodata.compressed. 然后在bzimage程序内可以引用 input_data来知道压缩文件的起始地址和长度. 可以很方便的看个例子: echo "this is a magic" > bin arch/x86/boot/compressed/vmlinux.scr . ld -b binary --oformat elf64-x86-64 -T vmlinux.scr bin #file a.out a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped #grep -5 "this is a" 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000060 14 00 00 00 00 00 00 00 14 00 00 00 00 00 00 00 |................| 00000070 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 |.. .............| 00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00200000 10 00 00 00 74 68 69 73 20 69 73 20 61 20 6d 61 |....this is a ma| 00200010 67 69 63 0a 00 2e 73 79 6d 74 61 62 00 2e 73 74 |gic...symtab..st| 00200020 72 74 61 62 00 2e 73 68 73 74 72 74 61 62 00 2e |rtab..shstrtab..| 00200030 72 6f 64 61 74 61 2e 63 6f 6d 70 72 65 73 73 65 |rodata.compresse| 00200040 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |d...............| 00200050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| #readelf -a a.out ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) ............... Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .rodata.compresse PROGBITS 0000000000000000 00200000 0000000000000014 0000000000000000 WA 0 0 1 ........... Symbol table '.symtab' contains 9 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 SECTION LOCAL DEFAULT 1 2: 0000000000000014 0 NOTYPE GLOBAL DEFAULT 1 input_data_end 3: 0000000000000004 0 NOTYPE GLOBAL DEFAULT 1 input_data 4: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 1 input_len 5: 0000000000000004 0 NOTYPE GLOBAL DEFAULT 1 _binary_bin_start 6: 0000000000000010 0 NOTYPE GLOBAL DEFAULT ABS _binary_bin_size 7: 0000000000000014 0 NOTYPE GLOBAL DEFAULT 1 _binary_bin_end 8: 0000000000000010 0 NOTYPE GLOBAL DEFAULT 1 output_len No version information found in this file. bzImage access the compressed kernel 在arch/x86/boot/compressed/head_32.S内可以很方便的引用压缩后的内核image. /* * Do the decompression, and jump to the new kernel.. */ movl output_len(%ebx), %eax pushl %eax pushl %ebp # output address movl input_len(%ebx), %eax pushl %eax # input_len leal input_data(%ebx), %eax pushl %eax # input_data leal boot_heap(%ebx), %eax pushl %eax # heap area as third argument pushl %esi # real mode pointer as second arg call decompress_kernel 这个head_32.S是链接时候第一个.o文件, 因为最后bzImage是个binary文件, 入口就是文件偏移0. 这点由相应的makefile保证,这个bzImage的makfile是: arch/x86/boot/compressed/Makefile $(obj)/vmlinux: $(src)/vmlinux_$(BITS).lds $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/piggy.o FORCE $(call if_changed,ld) @: OBJCOPYFLAGS_vmlinux.bin := -R .comment -S $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) 清 楚表明第一个文件是arch/x86/boot/compressed/head-32.S (当然是32bit), 其中包含了压缩后的内核image.但在arch/x86/boot/compressed/Makefile这一级的makefile并没完全吧 vmlinux.bin做成一个binary的image.这个工作由 arch/x86/boot/Makefile 来完成: OBJCOPYFLAGS_vmlinux.bin := -O binary -R .note -R .comment -S $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE $(call if_changed,objcopy) 另外可以参考build 过程的输出: LD vmlinux SYSMAP System.map SYSMAP .tmp_System.map Building modules, stage 2. CC arch/x86/boot/version.o OBJCOPY arch/x86/boot/compressed/vmlinux.bin GZIP arch/x86/boot/compressed/vmlinux.bin.gz MODPOST 223 modules LD arch/x86/boot/compressed/piggy.o LD arch/x86/boot/compressed/vmlinux OFFSETS arch/x86/boot/offsets.h OBJCOPY arch/x86/boot/vmlinux.bin AS arch/x86/boot/header.o LD arch/x86/boot/setup.elf OBJCOPY arch/x86/boot/setup.bin BUILD arch/x86/boot/bzImage 生成bzImage bzImage构成: setup.bin vmlinux.bin(我们的情景是压缩后代码), 对应arch/x86/boot/Makefile quiet_cmd_image = BUILD $@ cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/setup.bin \ $(obj)/vmlinux.bin $(ROOT_DEV) > $@ $(obj)/zImage $(obj)/bzImage: $(obj)/setup.bin \ $(obj)/vmlinux.bin $(obj)/tools/build FORCE $(call if_changed,image) @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' 其 中用于构建最终bzimage的工具build, 就是arch/x86/boot/tools/build.c. 他的作用就是吧setup.bin, vmlinux.bin连接到一起: setup.bin 按照512字节对齐, 同时负责把rootdev 内核crc,以及setup和kernel的大小, patch到setup.bin开头的arch/x86/boot/head.S 中(不过已经不能直接从floppy启动了). dump具体的bzImage看看: 确定setup.bin 长度和signature: hexdump -C arch/x86/boot/setup.bin | tail -2 00002c10 00 0f 50 00 19 00 00 00 55 aa 5a 5a |..P.....U.ZZ| 00002c1c 确定vmlinux.bin (包含压缩内核和解压缩代码)的起始数据(指令) hexdump -C arch/x86/boot/vmlinux.bin | head -1 00000000 fc f6 86 11 02 00 00 40 75 10 fa b8 18 00 00 00 |.......@u.......| 看看bzImage头: (head.S in arch/x86/boot) hexdump -C arch/x86/boot/bzImage | more 00000000 ea 05 00 c0 07 8c c8 8e d8 8e c0 8e d0 31 e4 fb |.............1..| 00000010 fc be 2d 00 ac 20 c0 74 09 b4 0e bb 07 00 cd 10 |..-.. .t........| 00000020 eb f2 31 c0 cd 16 cd 19 ea f0 ff 00 f0 44 69 72 |..1..........Dir| 00000030 65 63 74 20 62 6f 6f 74 69 6e 67 20 66 72 6f 6d |ect booting from| 00000040 20 66 6c 6f 70 70 79 20 69 73 20 6e 6f 20 6c 6f | floppy is no lo| 00000050 6e 67 65 72 20 73 75 70 70 6f 72 74 65 64 2e 0d |nger supported..| 00000060 0a 50 6c 65 61 73 65 20 75 73 65 20 61 20 62 6f |.Please use a bo| 00000070 6f 74 20 6c 6f 61 64 65 72 20 70 72 6f 67 72 61 |ot loader progra| 00000080 6d 20 69 6e 73 74 65 61 64 2e 0d 0a 0a 52 65 6d |m instead....Rem| 00000090 6f 76 65 20 64 69 73 6b 20 61 6e 64 20 70 72 65 |ove disk and pre| 000000a0 73 73 20 61 6e 79 20 6b 65 79 20 74 6f 20 72 65 |ss any key to re| 000000b0 62 6f 6f 74 20 2e 20 2e 20 2e 0d 0a 00 00 00 00 |boot . . .......| 000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 000001f0 00 16 01 00 cb 7c 02 00 00 00 ff ff 07 08 55 aa |.....|........U.| 00000200 eb 56 48 64 72 53 09 02 00 00 00 00 00 10 b0 28 |.VHdrS.........(| 00000210 00 01 00 80 00 00 10 00 00 00 00 00 00 00 00 00 |................| bzImage包含的vmlinux.bin,先确定地址: hexdump -C arch/x86/boot/bzImage | grep "fc f6 86 11 02 00 00 40" 00002e00 fc f6 86 11 02 00 00 40 75 10 fa b8 18 00 00 00 |.......@u.......| 最后看bzImae的构成: hexdump -C arch/x86/boot/bzImage | grep "00002e00" -3 00002c10 00 0f 50 00 19 00 00 00 55 aa 5a 5a 00 00 00 00 |..P.....U.ZZ....| 00002c20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00002e00 fc f6 86 11 02 00 00 40 75 10 fa b8 18 00 00 00 |.......@u.......| 00002e10 8e d8 8e c0 8e e0 8e e8 8e d0 8d a6 e8 01 00 00 |................| 00002e20 e8 00 00 00 00 5d 81 ed 25 00 00 00 89 eb 81 c3 |.....]..%.......| |
相关阅读 更多 +