linux 解压安卓kernel,linux内核启动解压过程分析

http://chxxxyg.blog.163.com/blog/static/150281193201072603030285/

文件arch/arm/boot/compressed/head.S是linux内核启动过程执行的第一个文件。

119                 .align

120                 .arm                            @ Always enter in ARM state

121 start:

122                 .type   start,#function  @type指定start这个符号是函数类型

123                 .rept   7         @重复7次 mov r0, r0,

124                 mov     r0, r0    @空操作,让前面所取指令得以执行。

125                 .endr

126    ARM(         mov     r0, r0          ) @空操作,让前面所取指令得以执行。

127    ARM(         b       1f              )   @跳转

128  THUMB(         adr     r12, BSYM(1f)   )

129  THUMB(         bx      r12             )

130

/*

魔数0x016f2818是在bootloader中用于判断zImage的存在,

而zImage的判别的magic number为0x016f2818,这个也是内核和bootloader约定好的。

*/

131                 .word   0x016f2818              @ Magic numbers to help the loader

132                 .word   start                   @ absolute load/run zImage address

133                 .word   _edata                  @ zImage end address

134  THUMB(         .thumb                  )

r1和r2中分别存放着由bootloader传递过来的architecture ID和指向标记列表的指针。

135 1:              mov     r7, r1                  @ save architecture ID

136                 mov     r8, r2                  @ save atags pointer

/*

这也标志着u-boot将系统完全的交给了OS,bootloader生命终止。之后会读取

cpsr并判断是否处理器处于supervisor模式——从u-boot进入kernel,系统已经处于SVC32模式;

而利用angel进入则处于user模式,还需要额外两条指令。之后是再次确认中断关闭,并完成cpsr写入

*/

137

138 #ifndef __ARM_ARCH_2__

139                 /*

140                  * Booting from Angel - need to enter SVC mode and disable

141                  * FIQs/IRQs (numeric definitions from angel arm.h source).

142                  * We only do this if we were in user mode on entry.

143                  */

144                 mrs     r2, cpsr                @ get current mode

145                 tst     r2, #3                  @ not user?

146                 bne     not_angel

147                 mov     r0, #0x17               @ angel_SWIreason_EnterSVC 0x17是angel_SWIreason_EnterSVC半主机操作

148  ARM(           swi     0x123456        )       @ angel_SWI_ARM 0x123456是arm指令集的半主机操作编号

149  THUMB(         svc     0xab            )       @ angel_SWI_THUMB

150 not_angel:

151                 mrs     r2, cpsr                @ turn off interrupts to

152                 orr     r2, r2, #0xc0           @ prevent angel from running

153                 msr     cpsr_c, r2  @这里将cpsr中I、F位分别置“1”,关闭IRQ和FIQ

154 #else

155                 teqp    pc, #0x0c000003         @ turn off interrupts

156 #endif

/*LC0表是链接文件arch/arm/boot/compressed/vmlinux.lds

(这个lds文件是由arch/arm/boot/compressed/vmlinux.lds.in生成的)的各段入口。

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

展开如下表:

假定zImage在内存中的初始地址为0x30008000(这个地址由bootloader决定,位置不固定)1、初始状态

链接文件arch/arm/boot/compressed/vmlinux.lds中的连接地址都是位置无关的,即都是以0地址为偏移的。

而此时内核已被bootloader搬移到了SDRAM中。链接地址应该加上这个偏移。

*/

.........前面是注释

168                 .text

169

170 #ifdef CONFIG_AUTO_ZRELADDR

171                 @ determine final kernel image address

172                 mov     r4, pc

173                 and     r4, r4, #0xf8000000

174                 add     r4, r4, #TEXT_OFFSET

175 #else

176                 ldr     r4, =zreladdr

177 #endif

178

179                 bl      cache_on

180

181 restart:        adr     r0, LC0

指令adr是基于PC的值来获取标号LC0 的地址的,由于内核已被搬移,标号LC0的地址不是以地址0为偏移的,这中间就存在一个固定的地址偏移,在s3c2410中是0x30008000.

182                 ldmia   r0, {r1, r2, r3, r6, r10, r11, r12}

183                 ldr     sp, [r0, #28]

184

185                 /*

186                  * We might be running at a different address.  We need

187                  * to fix up various pointers.

188                  */

189                 sub     r0, r0, r1       @ calculate the delta offset这里获得当前运行地址与链接地址的偏移量,存入r0中为0x30008000.

190                 add     r6, r6, r0              @ _edata

191                 add     r10, r10, r0            @ inflated kernel size location

192

193                 /*

194                  * The kernel build system appends the size of the

195                  * decompressed kernel at the end of the compressed data

196                  * in little-endian form.

197                  */

198                 ldrb    r9, [r10, #0]

199                 ldrb    lr, [r10, #1]

阅读(1232) | 评论(0) | 转发(0) |

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值