UBOOT源码分析的第一阶段start.S分析(3)

之前我们更新到了lowlevel_init代码处了。

看到lowlever_init这里的代码还是有点多哈。

但是看英语的注释我们也能看懂每一部分的代码到底是干什么的。

第42行 push {lr},先将lr压栈

之后检测复位状态,这里为什么要检测复位状态呢?

(1)复杂的cpu允许多种复位状态,比如直接冷上电,热启动,睡眠状态下唤醒,所以我们要在复位代码中检测复位状态,来判断到底是哪种状态。

(2)判断哪种状态的意义在于:冷上电时DDR时需要初始化才能使用的,而热启动或者低功耗状态下复位则不再需要初始化DDR

然后就是IO状态恢复、关闭看门狗、供电锁存、一些SRAM,SROM相关的设置(这个不是我们关注的

我们关注的代码是下面的这个

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

继续更新

上面的110-115行是判断当前代码的执行位置,因为BL1在SRAM中有一份,在DDR中也用一份,因此如果是冷启动,那么当前代码应该在SRAM中,如果低功耗,复位状态的话,当前代码就在DDR中运行。

判断当前代码的执行位置就是要不要执行之后的

时钟初始化和内存初始化。

就是上面的几个内容。这些都比较简单。

进入bl system_clock_init

我们可以发现

很多和时钟配置有关的项目

这些决定了开发板的时钟配置是多少。

mem_ctrl_asm_init就是初始化DDR的,这个暂时不用研究(自己还没有研究的那么深入,只知道大概的内容,等我研究透了,我在发一篇文章)

只有就是初始化串口和tzpc_init(ARM的trust zone, 用于安全保护)

之后检查复位状态, 然后打印出K

最后弹栈,结束这些操作。

总结一下:我们之前我们在调用lowlever_init之前设置过一次栈

因为那个时候DDR尚未初始化,因此执行都在SRAM中,所以在SRAM中分配了一部分内存作为栈,本次因为DDR已经被初始化了,因此要把栈搬到DDR中,所以要重新设置栈。

看下面的代码,

我们翻译一下英语:

当我们已经运行在RAM中了,我们不需要重定位U_BOOT,实际上,在uboot运行在RAM之前,内存控制器必须被配置

306行:R0中当前代码的执行地址

307行:R1在RAM中的原始基地址,R2当中的是链接地址

308行:做一些处理

之后比较R1和R2的值,

我们309行的注释都是错的(看到没有,哈哈,其实是比较R1和R2)然后决定是不是跳转程序 执行after_copy

猜你喜欢

转载自blog.csdn.net/zaqxsw12580/article/details/82346932