微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Android arm linux kernel启动流程

Android arm linux kernel启动流程

时间:11-09 来源:互联网 点击:

址,而我们直接跳到ZTEXTADDR跑的,实际上PC里面现在的地址肯定是0x00208000以后的一个值,adr r0, LC0编译之后实际上为addr0, pc, #208,这个208就是LC0到.text段头部的偏移。

view plainprint?

  1. addr5,r5,r0
  2. addr6,r6,r0
  3. addip,ip,r0

add r5, r5, r0 add r6, r6, r0 add ip, ip, r0

然后就是重定位了,即都加上一个偏移,经过重定位以后就都是绝对地址了。

view plainprint?

  1. not_relocated:movr0,#0
  2. 1:strr0,[r2],#4@clearbss
  3. strr0,[r2],#4
  4. strr0,[r2],#4
  5. strr0,[r2],#4
  6. cmpr2,r3
  7. blo1b
  8. /*
  9. *TheCruntimeenvironmentshouldnowbesetup
  10. *sufficiently.Turnthecacheon,setupsome
  11. *pointers,andstartdecompressing.
  12. */
  13. blcache_on

not_relocated: mov r0, #0 1: str r0, [r2], #4 @ clear bss str r0, [r2], #4 str r0, [r2], #4 str r0, [r2], #4 cmp r2, r3 blo 1b /* * The C runtime environment should now be setup * sufficiently. Turn the cache on, set up some * pointers, and start decompressing. */ bl cache_on

重定位完成以后打开cache,具体这个打开cache的过程咱没仔细研究过,大致过程是先从C0里面读到processor ID,然后根据ID来进行cache_on。

view plainprint?

  1. movr1,sp@mallocspaceabovestack
  2. addr2,sp,#0x10000@64kmax

mov r1, sp @ malloc space above stack add r2, sp, #0x10000 @ 64k max

解压的过程首先是在堆栈之上申请一个空间

view plainprint?

  1. /*
  2. *Checktoseeifwewilloverwriteourselves.
  3. *r4=finalkerneladdress
  4. *r5=startofthisimage
  5. *r2=endofmallocspace(andthereforethisimage)
  6. *Webasicallywant:
  7. *r4>=r2->OK
  8. *r4+imagelength<=r5->OK
  9. */
  10. cmpr4,r2
  11. bhswont_overwrite
  12. subr3,sp,r5@>compressedkernelsize
  13. addr0,r4,r3,lsl#2@allowfor4xexpansion
  14. cmpr0,r5
  15. blswont_overwrite
  16. movr5,r2@decompressaftermallocspace
  17. movr0,r5
  18. movr3,r7
  19. bldecompress_kernel
  20. addr0,r0,#127+128@alignment+stack
  21. bicr0,r0,#127@alignthekernellength

/* * Check to see if we will overwrite ourselves. * r4 = final kernel address * r5 = start of this image * r2 = end of malloc space (and therefore this image) * We basically want: * r4 >= r2 -> OK * r4 + image length <= r5 -> OK */ cmp r4, r2 bhs wont_overwrite sub r3, sp, r5 @ > compressed kernel size add r0, r4, r3, lsl #2 @ allow for 4x expansion cmp r0, r5 bls wont_overwrite mov r5, r2 @ decompress after malloc space mov r0, r5 mov r3, r7 bl decompress_kernel add r0, r0, #127 + 128 @ alignment + stack bic r0, r0, #127 @ align the kernel length

这个过程是判断我们解压出的vmlinx会不会覆盖原来的zImage,这里的final kernel address就是解压后的kernel要存放的地址,而start of this image则是zImage在内存中的地址。根据我们前面的分析,现在这两个地址是重复的,即都是0x00208000。同样r2是我们申请的一段内存空间,因为他是在sp上申请的,而根据vmlinx.lds我们知道stack实际上处与vmlinx的最上面,所以r4>=r2是不可能的,这里首先计算zImage的大小,然后判断r4+r3是不是比r5小,很明显r4和r5的值是一样的,所以这里先将r2的值赋给r0,经kernel先解压到s 申请的内存空间上面,具体的解压过程就不描述了,定义在misc.c里面。(这里我所说的上面是指内存地址的高地址,默认载入的时候从低地址往高地址写,所以从内存低地址开始运行,stack处于最后面,所以成说是最上面)

view plainprint?

  1. *r0=decompressedkernellength
  2. *r1-r3=unused
  3. *r4=kernelexecutionaddress
  4. *r5=decompressedkernelstart
  5. *r6=processorID
  6. *r7=architectureID
  7. *r8=atagspointer
  8. *r9-r14=corrupted
  9. */
  10. addr1,r5,r0@endofdecompressedkernel
  11. adrr2,reloc_start
  12. ldrr3,LC1
  13. addr3,r2,r3
  14. :ldmiar2!,{r9-r14}@copyrelocationcode
  15. stmiar1!,{r9-r14}
  16. ldmiar2!,{r9-r14}
  17. stmiar1!,{r9-r14}
  18. cmpr2,r3
  19. blo1b
  20. addsp,r1,#128@relocatethestack
  21. blcache_clean_flush
  22. addpc,r5,r0@callrelocationcode
* r0 = decompressed kernel length * r1-r3 = unused * r4 = kernel execution address * r5 = decompressed kernel start * r6 = processor ID * r7 = architecture ID * r8 = atags pointer * r9-r14 = corrupted */ add r1, r5, r0 @ end of decompressed kernel adr r2, reloc_start ldr r3, LC1 ad

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top