从boot到bootstrap

do_bootm函数及其所调用的函数,根据头部的定位地址(mkimage –a的参数)

将zImage搬移到指定的内存处),根据头部的入口地址(mkimage –e的参数)

获得head.o在内存中的地址,设置r0、r1、r2跳到此处执行。

boot传入r0=0,r1=machine_ID,r2=taglist  (r0为0, r1为machine type, r2位参数列表的物理地址)

在次过程中会开启Icache、Dcache,来加速开机过程

 

程序中有一段称为 LC0的表,其中根据链接脚本确定了got段的起始和结束地址,bss段的起始和结束地址,栈的地址(比链接脚本中的指定的stack大于4),解压的内核存放于物理内存的起始地址。

还有一个LC0标号记录了链接时的LC0标号地址,以及一个链接脚本中程序的链接起始地址_start

 

如何计算一个程序的在物理内存中运行的起始地址:

1、取运行是LC0的地址(PC加相对地址);设为r0

2、取链接程序的起始地址_start;设为r5

3、区链接是LC0标号的值;设为r1

4、r0-r1+r5即为程序在物理内存中的起始地址

注:一般将链接程序起始地址设为0,故_start=0,实际是unicore也是这么干的

 

根据r0-r1修正got表的内容(即got表的中每一项+(ro-r1)),同时建立bss段。

 

判定若将内核解压是否会覆盖掉自身:

1、r5=r0-r1+r5  zImage在物理内存中的起始地址

2、r2=sp+64K

3、r4=解压存放地址

4、r3=sp-r5

5、若r4>r2显然不会覆盖,执行解压

若r4+2r3显然不会覆盖,执行解压

否则挂掉。

 

在实际应用中出现了这样的问题:

为加速测试音频,没有启动android,而只是挂载了ramdisk,alsa所需的库名、配置文件名(通过objdump、hexdump、strings都可以获得),但是做出的uImage大概4.5M,而image为9M多,现在指定的内核搬移到了40808000,而解压到的地址是400080000,结果40008000+9M>40808000,因此head及misc被冲掉,所以内核不能正常解压,修正的方法是改正kernel/arch/unicore/boot/Makefile下的LOADADDR,使得zImage在内存的地址>40008000+9M,例如师兄修正的41808000

 

还有个问题,我们可以在将zImage制成uImage时将解压到的地址写入头部,这样boot可以将获取的信息放在合适的位置,感觉这样更好,但是实际上头部没有还有这个信息。

posted on 2012-04-26 21:06  阿加  阅读(514)  评论(0编辑  收藏  举报

导航