bzImage构成--pre-kexec linux2.6.27

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  |.....]..%.......|



你可能感兴趣的:(bzImage构成--pre-kexec linux2.6.27)