1 执行流程
am5728的cpu上电后,执行流程:ROM->MLO(SPL)->u-boot.img
第一级bootloader:引导加载程序,板子上电后会自动执行这些代码,如启动方式(SDcard、SPI、NOR),然后跳转至第二级bootloader。这些代码应该是存放在 176KB 的 ROM 中
第二级bootloader:MLO(SPL),用于硬件初始化,关看门狗,关中断,设置CPU时钟频率、速度、加载uboot.img、dts等操作,MLO文件应该会被映射到 64 KB的 Internal SRAM 中。
第三级bootloader:u-boot.img, C代码的入口
2. SPL代码走读
(参考:https://blog.csdn.net/kl1125290220/article/details/75013028/)
MLO作为Uboot的一级bootloader。在SPL代码的最后阶段就是去加载内核镜像或者加载Uboot镜像。
首先是在spl.c中的board_init_r函数中调用boot_from_devices()函数来进行加载镜像。
AM57xx\u-boot\common\spl\spl.c
该函数作用主要是【完成u-boot.img dts加载】
进入boot_from_devices查看:
spl_ll_find_loader 函数就是用来寻找相应的image_loader的。
首先我们来分析下第一行。
drv的值是通过ll_entry_start宏进行获取的。现在我们先不管这个宏是干嘛的。
让我们来接着看下去:
n_ents是通过ll_entry_count宏,进行判断的。我们可以通过这个函数名初步判断,这个是获取image_loader的数量。
最后,就到了我们一个for循环,我们先进行猜测,这个函数是干嘛的。
这个函数的目标就是获取一个对应设备的的image_loader。那么肯定会涉及到对每个image_loader进行遍历比较。而比较的一个关键点就是,image_loader的一个成员变量boot_device。
那么根据我们的猜测来去分析下面的for循环可能就能有着事半功倍的效果。
首先,我们的for循环开始,
entry 等于我们一开始通过ll_entry_start宏获取的一个image_loader。我们可以判断,这是drv是第一个image_loader。
然后判断为true条件就是entry 不等于 第一个image_loader加上所有的image_loader的总数。
并且,在for循环里面,进行对比的正是通过boot_device进行对比。
仍然有一个十分关键的地方没有摸清楚。
那就是,我们是在哪里定义各个设备对应的image_loader的呢?只有找到这个,我们才能够知道,SPL是来加载镜像的。
在函数
现在卡在
AM57xx\u-boot\lib\hang.c
spl_load_simple_fit() 函数在AM57xx\u-boot\common\spl\spl_fit.c
fdt_path_offset 函数:(暂时没了,后续继续更新)