Android arm linux kernel启动流程
拟地址都是相对的,没有绝对地址。这里的 vmlinx.lds可以对照着后面的head.s稍微看一下~得到压缩以后的vmlinx以后再将这个vmlinx经过objcopy以后就得到我们的 zImage了,然后拷贝到out目录下就是我们的kernel了~~
在这里要强调几个地址,这些地址定义在arch/arm/mach-msm/makefile.boot里面,被arch/arm/boot /Makefile调用,其中zreladdr-y就是我们的kernel被解压以后要释放的地址了,解压代码跑完以后就会跳到这个地址来执行 kernel的启动。不过这里还有其他两个PHYS,跟前面定义在boardconfig.h里面的值重复了,不知道这两个值在这里定义跟前面的值是一种什么关系???
好啦,讲到这里我们基本就知道boot.img的构成了,下面我们就从解压的代码开始看看arm linux kernel启动的一个过程,这个解压的source就是/arch/arm/boot/compressed/head.S。要看懂这个汇编需要了解 GNU ASM以及ARM汇编指令,ARM指令就不说了,ARM RVCT里面的文档有得下,至于GNU ASM,不需要消息了解的话主要是看一下一些伪指令的含义(http://sources.redhat.com/binutils/docs-2.12 /as.info/Pseudo-Ops.html#Pseudo%20Ops)
那么我们现在就开始分析这个解压的过程:
1)bootloader会传递2个参数过来,分别是r1=architecture ID, r2=atags pointer。head.S从哪部分开始执行呢,这个我们可以看看vmlinx.lds:
view plainprint?
- ENTRY(_start)
- SECTIONS
- {
- .=0;
- _text=.;
- .text:{
- _start=.;
- *(.start)
- *(.text)
- *(.text.*)
- *(.fixup)
- *(.gnu.warning)
- *(.rodata)
- *(.rodata.*)
- *(.glue_7)
- *(.glue_7t)
- *(.piggydata)
- .=ALIGN(4);
- }
可以看到我们最开始的section就是.start,所以我们是从start段开始执行的。ELF对程序的入口地址是有定义的,这可以参照*.lds 的语法规则里面有描述,分别是GNU LD的-E ---> *.lds里面的ENTRY定义 ---> start Symbol ---> .text section --->0。在这里是没有这些判断的,因为还没有操作系统,bootloader会直接跳到这个start的地址开始执行。
在这里稍微带一句,如果觉得head.S看的不太舒服的话,比如有些跳转并不知道意思,可以直接objdump vmlinx来看,dump出来的汇编的流程就比较清晰了。
view plainprint?
- 1:movr7,r1@savearchitectureID
- movr8,r2@saveatagspointer
- #ifndef__ARM_ARCH_2__
- /*
- *BootingfromAngel-needtoenterSVCmodeanddisable
- *FIQs/IRQs(numericdefinitionsfromangelarm.hsource).
- *Weonlydothisifwewereinusermodeonentry.
- */
- mrsr2,cpsr@getcurrentmode
- tstr2,#3@notuser?
- bnenot_angel@如果不是
- movr0,#0x17@angel_SWIreason_EnterSVC
- swi0x123456@angel_SWI_ARM
- not_angel:
- mrsr2,cpsr@turnoffinterruptsto
- orrr2,r2,#0xc0@preventangelfromrunning
- msrcpsr_c,r2
上面首先保存r1和r2的值,然后进入超级用户模式,并关闭中断。
view plainprint?
- .text
- adrr0,LC0
- ldmiar0,{r1,r2,r3,r4,r5,r6,ip,sp}
- subsr0,r0,r1@calculatethedeltaoffset
- @ifdeltaiszero,weare
- beqnot_relocated@runningattheaddresswe
- @werelinkedat.
这里首先判断LC0当前的运行地址和链接地址是否一样,如果一样就不需要重定位,如果不一样则需要进行重定位。这里肯定是不相等的,因为我们可以通过 objdump看到LC0的地址是0x00000138,是一个相对地址,然后adr r0, LC0 实际上就是将LC0当前的运行地
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)