您的位置:首页 > 其它

二十一.UBOOT工作流程

2014-12-04 00:42 176 查看
1.程序入口
(1)从顶层目录的Makefile入手
(2)在Makefile搜索smdk2440得到



其中阴影部分代表u-boot/board/samsung目录下的子目录名称

(3)进入上述子目录可以看到



其中阴影部分是链接器脚本文件
(4)打开它可以看到



阴影部分指明了代码段最开始部分对应的的文件是在u-boot/cpu/s3c24xx/start.o,且程序入口在_start(ENTRY(_start))。
那么这个.o文件有可能是start.c编译得到的,也有可能是start.S文件编译得到的。
(5)进入u-boot/cpu/s3c24xx/,发现只有start.S文件,所以执行的第一个文件就是start.S,然后在该文件找到_start(阴影部分)



2.第一阶段(BL1)
(1)目前只关心他做了什么,而不关心如何实现

(2)从start.S的_start标号处开始



3.第二阶段(BL2)

(0)在清除BSSd以后有



阴影部分指明了要进入BL2阶段,即从stepp stone 跳转到内存执行
(1)通过配置和编译u-boot得到elf格式和bin格式的文件 ,然后对elf格式的进行反汇编,查找_start_armboot
#make clean
#make smdk2440_config
#make
#arm-linux-objdump -D -S u-boot >ubootdump
可以得到



黑色部分指明了该函数的入口地址,亦即_start_armboot的地址,就是BL2的入口地址,(而该地址和链接器脚本有关,但是在顶层config.mk文件中出现两个起始地址,这个时候以Ttext指定的TEXTBASE为基地址,将-T 关联的链接器脚本指定的起始地址覆盖掉。而TEXTBASE则是在板级目录的config.mk文件中定义的。)故可知道PC将要跳转到内存中执行

(2)至于为何一开始的链接地址就大于等于3000000,是因为和相对跳转有关。B只是相对跳转,而且PC指针的值和链接地址并非保持相等关系。上电就复制前4KB,与它链接的时候指定的地址无关。一开始PC必然是0,之后的跳转就看是B还是LDR,前者看两个链接地址的差值是多少,就在当前PC上加多少,后者则是直接把实际的链接地址赋给PC进行绝对跳转。

(3)第二阶段既有软件初始化,又有硬件初始化,暂时不考虑纯软件的初始化。

(4)



(5)不管哪一种平台。第二阶段都会进入到这个地方执行

4.对于6410
第一阶段的不同:
(1)外设基地址的初始化
(2)点亮LED,方便调试
(3)关闭看门狗,2440的看门狗是在系统时钟初始化的时候进行关闭的,而且在时钟初始化中屏蔽了所有中断。理论上这两项是放在时钟初始化之前的。6410则是分开执行的,并没有将这两项放在系统时钟初始化中。

5.对于210:
(1)BL1和BL2是划分开的,不像2440和6410是合并在一起的bin文件
(2)连接器脚本在spl子目录中
(3)查看脚本文件找到入口地址(start.S的_start标号处)
(4)要使L1的I/D cache 失效
(5)要检查reset状态,如果为唤醒状态,则很多工作可以省去
(6)对I/O引脚初始化(在关闭看门口之前)
(7)对sram和srom初始化(紧接(8))
(8)判断是否在内存中执行uboot,不是的话,先进行时钟初始化,再内存初始化,最后串口初始化
(9)紧接着是取消存储保护区(后面紧接nand简单初始化)
(10)接下来紧接的是disable ABB
(11)接下来是设置堆栈
(12)判断是否在内存中运行,进行不同的跳转
(13)判断启动方式,进入相应的boot函数
(14)复制代码到内存,并且PC跳转到内存中执行
(15)把BL2复制到内存中什么位置?可以查看nand_cp.C和smart210.h文件得到该config_text_base宏定义
(16)如何在nand中找到BL2?BL1虽然是16KB但是保留8KB间隔(前16KB有效),所以BL2从24KB处开始存放,故就从24KB开始对其进行复制。复制时还制订了要复制代码的大小。
(17)跳转到内存中执行BL2.在2440和 6410中用LDR,但是在210中直接去取BL2的地址,然后运行(因为是C代码,可以直接像调用函数一样调用地址):
uboot = (void *)config_text_base(字样);
(*uboot)();
(18)第一阶段到此结束

第二阶段:
(1)找到BL2的入口函数和标号,通过链接器脚本arch/arm/cpu/armv7子目录下面:u-boot.lds
(2)入口文件和标号和BL1是一样的,有重复,待修改
(3)在判断是否在内存执行的时候,跳转的位置发生了变化,会跑到arch/arm/lib子目录下的board.c文件执行board_init_f()函数(真正的BL2入口函数),就是老版本的start_armboot()函数。
(4)arch/arm/cpu/armv7子目录下面的cpu.c文件的save_boot_params()函数,他没有函数体,具有weak属性(两个同名函数的情况,遇到较强的函数,若函数自动失效,若函数使用的函数体是他的别名函数的函数体)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: