Android arm linux 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?
- /*
- +-----------------+
- |bootheader|1page
- +-----------------+
- |kernel|npages
- +-----------------+
- |ramdisk|mpages
- +-----------------+
- |secondstage|opages
- +-----------------+
- 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.allentitiesarepage_sizealignedinflash
- 1.kernelandramdiskarerequired(size!=0)
- 2.secondisoptional(second_size==0->nosecond)
- 3.loadeachelement(kernel,ramdisk,second)at
- thespecifiedphysicaladdress(kernel_addr,etc)
- 4.preparetagsattag_addr.kernel_args[]is
- appendedtothekernelcommandlineinthetags.
- 5.r0=0,r1=MACHINE_TYPE,r2=tags_addr
- 6.ifsecond_size!=0:jumptosecond_addr
- else:jumptokernel_addr
- */
关于boot header这个数据结构我们需要重点注意,在这里我们关注其中几个比较重要的值,这些值定义在boot/boardconfig.h里面,不同的芯片对应vendor下不同的boardconfig,在这里我们的值分别是(分别是kernel/ramdis/tags载入ram的物理地址):
view plainprint?
- #definePHYSICAL_DRAM_BASE0x00200000
- #defineKERNEL_ADDR(PHYSICAL_DRAM_BASE+0x00008000)
- #defineRAMDISK_ADDR(PHYSICAL_DRAM_BASE+0x01000000)
- #defineTAGS_ADDR(PHYSICAL_DRAM_BASE+0x00000100)
- #defineNEWTAGS_ADDR(PHYSICAL_
Androidarmlinuxkernel启动流 相关文章:
- Android arm linux kernel启动流程一(11-09)
- Android arm linux kernel启动流程二(11-09)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)