我试图通过浏览源代码来了解 BeagleBone Black 的启动过程。假设我将 MLO 和 u-boot.img 文件保存在 micro-SD 卡中,并使 BeagleBone 从 SD 卡启动。
据我了解,ROM 代码首先执行,并将 MLO 文件从 MMC 加载到 SOC 的内部 SRAM 中。MLO 文件包含 x-loader 的代码,这是一个第二阶段程序加载器 (SPL)。然后 SPL 设置 DRAM 并将第三阶段 Program Loader(U-boot 正确)复制到 DRAM 中。U-boot 直接从 DRAM 开始执行。
U-boot 本身的体系结构相关部分位于 U-boot 源的 arch/arm/ 目录中。与 SPL 有关的代码位于 spl/ 目录中。(在执行 make mrproper 后跟 make SPL 时,*.o 文件仅在 spl/ 目录中创建)
对于 U-boot 本身,我猜这是执行流程 - arch/arm/cpu/armv7/start.S 位于重置向量处(因此它首先运行),经过一些初始化后,它调用位于拱/臂/lib/crt0.S 。
在 crt0.S 中,board_init_f() 被调用,它设置 DRAM(和其他东西),然后返回到它离开的地方(在 main_ 中)。它稍后调用函数 relocate_code 将其再次重新定位到 DRAM。
ENTRY(_main)
/*
* Set up initial C runtime environment and call board_init_f(0).
*/
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
ldr r0, =(CONFIG_SPL_STACK)
#else
ldr r0, =(CONFIG_SYS_INIT_SP_ADDR)
#endif
bic r0, r0, #7 /* 8-byte alignment for ABI compliance */
mov sp, r0
bl board_init_f_alloc_reserve
mov sp, r0
/* set up gd here, outside any C code */
mov r9, r0
bl board_init_f_init_reserve
mov r0, #0
bl board_init_f
#if ! defined(CONFIG_SPL_BUILD)
/*
* Set up intermediate environment (new sp and gd) and call
* relocate_code(addr_moni). Trick here is that we'll return
* 'here' but relocated.
*/
ldr r0, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */
bic r0, r0, #7 /* 8-byte alignment for ABI compliance */
mov sp, r0
ldr r9, [r9, #GD_BD] /* r9 = gd->bd */
sub r9, r9, #GD_SIZE /* new GD is below bd */
adr lr, here
ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */
add lr, lr, r0
#if defined(CONFIG_CPU_V7M)
orr lr, #1 /* As required by Thumb-only */
#endif
ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
b relocate_code
here:
如果这已经由 SPL 完成,为什么 U-boot 正确需要再次设置 DRAM 并再次重新定位?我在这里错过了什么吗?