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

Android arm linux kernel启动流程

时间:11-09 来源:互联网 点击:
虽然这里的Arm Linux kernel前面加上了Android,但实际上还是和普遍Arm linux kernel启动的过程一样的,这里只是结合一下Android的Makefile,讲一下bootimage生成的一个过程。这篇文档主要描述 bootimage的构造,以及kernel真正执行前的解压过程。

在了解这些之前我们首先需要了解几个名词,这些名词定义在/Documentation/arm/Porting里面,这里首先提到其中的几个,其余几个会在后面kernel的执行过程中讲述:

1)ZTEXTADDR boot.img运行时候zImage的起始地址,即kernel解压代码的地址。这里没有虚拟地址的概念,因为没有开启MMU,所以这个地址是物理内存的地址。解压代码不一定需要载入RAM才能运行,在FLASH或者其他可寻址的媒体上都可以运行。

2)ZBSSADDR 解压代码的BSS段的地址,这里也是物理地址。

3)ZRELADDR 这个是kernel解压以后存放的内存物理地址,解压代码执行完成以后会跳到这个地址执行kernel的启动,这个地址和后面kernel运行时候的虚拟地址满足:__virt_to_phys(TEXTADDR) = ZRELADDR。

4)INITRD_PHYS Initial Ram Disk存放在内存中的物理地址,这里就是我们的ramdisk.img。

5)INITRD_VIRT Initial Ram Disk运行时候虚拟地址。

6)PARAMS_PHYS 内核启动的初始化参数在内存上的物理地址。

下面我们首先来看看boot.img的构造,了解其中的内容对我们了解kernel的启动过程是很有帮助的。首先来看看Makefile是如何产生我们的boot.img的:

out/host/linux-x86/bin/mkbootimg-msm7627_ffa --kernel out/target/product/msm7627_ffa/kernel --ramdisk out/target/product/msm7627_ffa/ramdisk.img --cmdline "mem=203M console=ttyMSM2,115200n8 androidboot.hardware=qcom" --output out/target/product/msm7627_ffa/boot.img

根据上面的命令我们可以首先看看mkbootimg-msm7627ffa这个工具的源文件:system/core/mkbootimg.c。看完之后我们就能很清晰地看到boot.img的内部构造,它是由boot header /kernel /ramdisk /second stage构成的,其中前3项是必须的,最后一项是可选的。

view plainprint?

  1. /*
  2. +-----------------+
  3. |bootheader|1page
  4. +-----------------+
  5. |kernel|npages
  6. +-----------------+
  7. |ramdisk|mpages
  8. +-----------------+
  9. |secondstage|opages
  10. +-----------------+
  11. n=(kernel_size+page_size-1)/page_size
  12. m=(ramdisk_size+page_size-1)/page_size
  13. o=(second_size+page_size-1)/page_size
  14. 0.allentitiesarepage_sizealignedinflash
  15. 1.kernelandramdiskarerequired(size!=0)
  16. 2.secondisoptional(second_size==0->nosecond)
  17. 3.loadeachelement(kernel,ramdisk,second)at
  18. thespecifiedphysicaladdress(kernel_addr,etc)
  19. 4.preparetagsattag_addr.kernel_args[]is
  20. appendedtothekernelcommandlineinthetags.
  21. 5.r0=0,r1=MACHINE_TYPE,r2=tags_addr
  22. 6.ifsecond_size!=0:jumptosecond_addr
  23. else:jumptokernel_addr
  24. */

/* +-----------------+ | boot header | 1 page +-----------------+ | kernel | n pages +-----------------+ | ramdisk | m pages +-----------------+ | second stage | o pages +-----------------+ n = (kernel_size + page_size - 1) / page_size m = (ramdisk_size + page_size - 1) / page_size o = (second_size + page_size - 1) / page_size 0. all entities are page_size aligned in flash 1. kernel and ramdisk are required (size != 0) 2. second is optional (second_size == 0 -> no second) 3. load each element (kernel, ramdisk, second) at the specified physical address (kernel_addr, etc) 4. prepare tags at tag_addr. kernel_args[] is appended to the kernel commandline in the tags. 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr 6. if second_size != 0: jump to second_addr else: jump to kernel_addr */

关于boot header这个数据结构我们需要重点注意,在这里我们关注其中几个比较重要的值,这些值定义在boot/boardconfig.h里面,不同的芯片对应vendor下不同的boardconfig,在这里我们的值分别是(分别是kernel/ramdis/tags载入ram的物理地址):

view plainprint?

  1. #definePHYSICAL_DRAM_BASE0x00200000
  2. #defineKERNEL_ADDR(PHYSICAL_DRAM_BASE+0x00008000)
  3. #defineRAMDISK_ADDR(PHYSICAL_DRAM_BASE+0x01000000)
  4. #defineTAGS_ADDR(PHYSICAL_DRAM_BASE+0x00000100)
  5. #defineNEWTAGS_ADDR(PHYSICAL_

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

网站地图

Top