我们以前写裸机程序时:
- 初始化:关看门狗,初始化时钟,初始化SDRAM;
- 把程序从nand拷贝到SDRAM;
- 设置sp,调用C语言函数;
- 继续执行…
uboot作为一个裸机程序的集大成者,这些都会做,而且还要读出内核并启动内核。
之前分析过,uboot上电会先调用cpu/arm920t/start.S,我们就从这个文件来入手分析。
首先会跳到reset段。
然后将CPU设为SVC32模式(管理模式)并关闭看门狗。
第四步设置时钟,视频里面是用了函数调用,但是我本地打完补丁使用的是汇编,这里不做深究,理解为主。
从这里,我们就可以看到栈是怎么划分的,从0x33F80000开始,依次是堆,bdinfo,中断使用的栈,3字节中断栈。其中,0x33F80000到0x34000000这片内存放的是uboot,有512字节。
然后是调用时钟初始化函数。
然后把代码重定位到链接地址去。
最后,调用start_armboot函数,该函数为一个C语言函数,更复杂的功能就在这里面实现。
从上到下分析,start.S做了这些操作:
- 设为SVC模式;
- 关看门狗;
- 屏蔽中断;
- 初始化SDRAM;
- 设置栈;
- 时钟配置;
- 重定位,代码从Flash拷到SDRAM;
- 清bss段(初始值为0或未初始化的全局变量和静态变量);
- 调用start_armboot;
上面都是硬件相关的初始化,最后一步是一个C函数,更复杂的功能就在这个函数中实现,1到8称为第一阶段,start_armboot之后的就是第二阶段。