Linux内核源码分析--内核启动之zImage自解压过程

zImage来历

顶层vmlinux ---->

arch/arm/boot/Image --->

arch/arm/boot/compressed/piggy.gz --->

arch/arm/boot/compressed/vmlinux --->

arch/arm/boot/zImage

如果要分析zImage的反汇编反汇编文件,可将arch/arm/boot/compressed/vmlinux进行反汇编,

arm-linux-xxx-objdump –d vmlinux > vmlinux.dis

对顶层的vmlinux反汇编得到的是未压缩的内核的反汇编文件,这个vmlinux才是真正的Linux内核。

piggy.gz压缩文件的特点

gzip -f -9 < Image > piggy.gz

在piggy.gz的结尾四个字节表示的是 Image 镜像的大小,并且是以小端格式存放的。下面我们验证一下:

可以看到,Image的大小是6806148B,十六进制值就是67DA84,接下来看看piggy.gz的结尾:

可以看到,确实是将0x67DA84以小端的格式存放在了piggy.gz的结尾四字节中了。

vmlinux.lds

1:  /*
   2:   *  linux/arch/arm/boot/compressed/vmlinux.lds.in
   3:   *
   4:   *  Copyright (C) 2000 Russell King
   5:   *
   6:   * This program is free software; you can redistribute it and/or modify
   7:   * it under the terms of the GNU General Public License version 2 as
   8:   * published by the Free Software Foundation.
   9:   */
  10:  OUTPUT_ARCH(arm)
  11:  ENTRY(_start)
  12:  SECTIONS
  13:  {
  14:    /DISCARD/ : {
  15:      *(.ARM.exidx*)
  16:      *(.ARM.extab*)
  17:      /*
  18:       * Discard any r/w data - this produces a link error if we have any,
  19:       * which is required for PIC decompression.  Local data generates
  20:       * GOTOFF relocations, which prevents it being relocated independently
  21:       * of the text/got segments.
  22:       */
  23:      *(.data)
  24:    }
  25:   
  26:    . = 0;
  27:    _text = .;
  28:   
  29:    .text : {
  30:      _start = .;
  31:      *(.start)
  32:      *(.text)
  33:      *(.text.*)
  34:      *(.fixup)
  35:      *(.gnu.warning)
  36:      *(.rodata)
  37:      *(.rodata.*)
  38:      *(.glue_7)
  39:      *(.glue_7t)
  40:      *(.piggydata)
  41:      . = ALIGN(4);
  42:    }
  43:   
  44:    _etext = .;
  45:   
  46:    _got_start = .;
  47:    .got            : { *(.got) }
  48:    _got_end = .;
  49:    .got.plt        : { *(.got.plt) }
  50:    _edata = .;
  51:   
  52:    . = ALIGN(8);
  53:    __bss_start = .;
  54:    .bss            : { *(.bss) }
  55:    _end = .;
  56:   
  57:    . = ALIGN(8);        /* the stack must be 64-bit aligned */
  58:    .stack        : { *(.stack) }
  59:   
  60:    .stab 0        : { *(.stab) }
  61:    .stabstr 0        : { *(.stabstr) }
  62:    .stab.excl 0        : { *(.stab.excl) }
  63:    .stab.exclstr 0    : { *(.stab.exclstr) }
  64:    .stab.index 0        : { *(.stab.index) }
  65:    .stab.indexstr 0    : { *(.stab.indexstr) }
  66:    .comment 0        : { *(.comment) }
  67:  }
  68:  

arch/arm/boot/compressed/head.S

1:  .section ".start", #alloc, #execinstr
   2:  /*
   3:  * 清理不同的调用约定
   4:  */
   5:  .align
   6:  .arm @ 启动总是进入ARM状态
   7:  start:
   8:  .type start,#function
   9:  .rept 7
  10:  mov r0, r0
  11:  .endr
  12:  ARM( mov r0, r0 )
  13:  ARM( b 1f )
  14:  THUMB( adr r12, BSYM(1f) )
  15:  THUMB( bx r12 )
  16:  .word 0x016f2818 @ 用于boot loader的魔数
  17:  .word start @ 加载/运行zImage的绝对地址(编译时确定), 在vmlinux.lds中可以看到,zImage的链接起始地址是0
  18:  .word _edata @ zImage结束地址,分析vmlinux.lds可以看到,_edata是 .got 段的结束地址,后面紧接的就是.bss段和.stack段
  19:  THUMB( .thumb )
  20:  1: mov r7, r1 @ 保存构架ID到r7(此前由bootloader放入r1)
  21:     mov r8, r2 @ 保存内核启动参数地址到r8(此前由bootloader放入r2)
  22:  #ifndef __ARM_ARCH_2__
  23:  /*
  24:  * 通过Angel调试器启动 - 必须进入 SVC模式且关闭FIQs/IRQs
  25:  * (numeric definitions from angel arm.h source).
  26:  * 如果进入时在user模式下,我们只需要做这些
  27:  */
  28:  mrs r2, cpsr @ 获取当前模式
  29:  tst r2, #3 @ 判断是否是user模式
  30:  bne not_angel
  31:  mov r0, #0x17 @ angel_SWIreason_EnterSVC
  32:  ARM( swi 0x123456 ) @ angel_SWI_ARM  swi会产生软中断,会跳入中断向量表,这个向量表用的是bootloader的,因为在head.S中并没有建立新的向量表
  33:  THUMB( svc 0xab ) @ angel_SWI_THUMB
  34:  not_angel:
  35:  mrs r2, cpsr @ 关闭中断
  36:  orr r2, r2, #0xc0 @ 以保护调试器的运作 关闭IRQ和FIQ
  37:  msr cpsr_c, r2
  38:  #else
  39:  teqp pc, #0x0c000003@ 关闭中断(此外bootloader已设置模式为SVC)
  40:  #endif
 

GOT表是什么?

GOT(Global Offset Table)表中每一项都是本运行模块要引用的一个全局变量或函数的地址。可以用GOT表来间接引用
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值