UBOOT源码分析的第一阶段start.S分析
最近半个月在研究UBOOT与系统移植,现在就分享一下自己的学习经验。(我自己用的是4412开发板)
首先我们要做的就是找到整个uboot项目的入口。这个入口在uboot.lds当中有定义的。就是ENTRY(_start),因此_start符号所在的文件就是整个程序的起始文件。
_start所在的代码就是起始代码。
我们把uboot源码导入到source inside(注意一下,这里的话可以删除掉与自己开发板不相关的文件)
搜索start.S文件,就可以看到有以下的内容了。
整个uboot的启动代码就在第57行。
现在我们来分析start.S文件来分析uboot第一阶段。
1、头文件分析
include<config.h>
config.h文件是在include目录下面的。不是uboot源代码中存在的文件,而是在配置文件中生成的文件,我们可以看看里面到底有什么内容
可见这个文件是自动生成的,可以看我之前的一篇文章。就有讲到这些。
#include<version.h>
下面的内容就是version.h中包含的,里面还包含了一个version_autogenerated.h文件(这个是自动生成的)使用前要看条件编译。
#if defined(CONFIG_ENABLE_MMU)
#include <asm/proc/domain.h>
#endif
条件编译:注意这里有个关键,还知道我们之前是不是提过一个符号链接呢?
这里的asm目录不是uboot的原来有的目录,asm目录是在编译链接过程中创建的符号符号链接,符号链接指向asm-arm
实际的文件时include/asm-arm/proc-arm/domain.h
今晚就到这里,明天继续。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
继续更新
第53行到56行,其实就是一个16字节的填充对齐。这个有什么用呢?
这16个字节只是保证填充Image的开头部分,当中的内容是不对的。还是需要后面去计算校验和然后重新填充的。当然有些uboot当中的代码,是没有这部分的。
第57行,定义了一个全局变量,_start
之后的第59行到65行:异常向量表
定义了那些异常呢?
其实也就是这些异常。
对应的就是上面的那些。
其实异常向量表当中最重要的还是表中的第一个复位异常。因为cpu复位后,真正去执行的有效代码就是 b reset
当然异常向量表当中的异常都应该被处理,不然程序就跑飞了,你都不知道它跑到哪里去了。但是uboot当中不用处理这部分,感觉运行速度太快了。
下面的第68行到85行定义了一些变量
格式相当于下面的
.word _undefined_instuction = undefined_instruction
第87行定义的 .balignl 16 ,0xdeadbeef
这一句话是然当前地址对齐排布,如果没有对齐的话,就要自动向后面走,直到对齐。
并且向后走的内存要用0xdeadbeef来填充
为什么要使用这个呢?有时候可能是为了效率方面(这个我也不太清除是不是这样的)
第101到102行,定义了一个字长的变量
.word _TEXT_BASE = TEXT_BASE
这个在uboot当中不能找到。
这个TEXT_BASE是链接地址当中,在某个开发板的目录下面的config.mk中见到过。
就是这个。
所以自己总结一下,一开始一定要对uboot的目录结构有清晰的认识才行。
第109行(不知道为什么自己的没有定义,之前我把uboot代码删除过一些),
.word _TEXT_PHY_BASE = CFG_PHY_UBOOT_BASE
这里的CFG_PHY_UBOOT_BASE其实就是uboot在DDR当中的物理地址,物理地址是多少。我下来看看,然后补上去。
之后定义了全局变量,_armboot_start 这个是uboot的第二阶段。我们之后介绍。
下面的这些代码我们暂时不用管(These are defined in the board-specific linker script.)
下面的代码段是条件编译,显然我们没有定义CONFIG_USE_IRQ
所以不执行这些代码
真正的复位代码:在这里。
可以看到只执行193行,这里的第189行到192行,我在看其他人的写的uboot时,他们这里的做法都是将CPU设置成SVC32模式,然后禁止IRQ 和 FIQ
这里补充一下两个指令:
MRS和MSR指令
MRS指令:用于将程序状态寄存器的内容送入到通用寄存器。
MSR指令: 用于将操作数的内容传送到程序寄存器当中
这个是4412开发板的Uboot启动代码。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------下午继续更新