为什么代码重定位在 U-boot 中完成?
Why is code relocation done in U-boot proper?
我试图通过浏览源代码来了解 BeagleBone Black 的启动过程。假设我将 MLO 和 u-boot.img 文件保存在 micro-SD 卡中,并使 BeagleBone 从 SD 卡启动。
据我了解,ROM 代码首先执行,它将 MLO 文件从 MMC 加载到 SOC 的内部 SRAM 中。 MLO 文件包含 x-loader 的代码,这是一个第二阶段程序加载器 (SPL)。然后 SPL 设置 DRAM 并将第三阶段程序加载器(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 位于重置向量(因此它首先运行),并且在一些初始化之后它调用位于 arch/arm/ 的'_main'过程库/crt0.S .
在 crt0.S 中,调用 board_init_f(),它设置 DRAM(和其他东西),然后 returns 回到它停止的地方(在 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 并重新定位?我在这里遗漏了什么吗?
Why U-boot proper needs to setup DRAM again and relocate itself again if this was already done by SPL?
重定位到内存顶部是为了最大化连续空闲space。
您可以 build/link 并在这个高端内存地址加载 U-Boot(以保存在副本上)。但是每当你用添加的功能重建 U-Boot 并且图像变大时,就必须重新计算加载地址。
这也意味着必须更改 SPL。
顺便说一句 "setup DRAM" 通常会被认为是初始化 DRAM 控制器,在这个阶段还没有完成。
除了重新定位其代码,U-Boot 还必须移动堆栈和堆,即 C 运行时环境。
Am i missing something here?
把U-Boot加载到主存中间,然后让U-Boot自己重新定位到高端内存,这样比较方便。
我试图通过浏览源代码来了解 BeagleBone Black 的启动过程。假设我将 MLO 和 u-boot.img 文件保存在 micro-SD 卡中,并使 BeagleBone 从 SD 卡启动。
据我了解,ROM 代码首先执行,它将 MLO 文件从 MMC 加载到 SOC 的内部 SRAM 中。 MLO 文件包含 x-loader 的代码,这是一个第二阶段程序加载器 (SPL)。然后 SPL 设置 DRAM 并将第三阶段程序加载器(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 位于重置向量(因此它首先运行),并且在一些初始化之后它调用位于 arch/arm/ 的'_main'过程库/crt0.S .
在 crt0.S 中,调用 board_init_f(),它设置 DRAM(和其他东西),然后 returns 回到它停止的地方(在 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 并重新定位?我在这里遗漏了什么吗?
Why U-boot proper needs to setup DRAM again and relocate itself again if this was already done by SPL?
重定位到内存顶部是为了最大化连续空闲space。
您可以 build/link 并在这个高端内存地址加载 U-Boot(以保存在副本上)。但是每当你用添加的功能重建 U-Boot 并且图像变大时,就必须重新计算加载地址。
这也意味着必须更改 SPL。
顺便说一句 "setup DRAM" 通常会被认为是初始化 DRAM 控制器,在这个阶段还没有完成。
除了重新定位其代码,U-Boot 还必须移动堆栈和堆,即 C 运行时环境。
Am i missing something here?
把U-Boot加载到主存中间,然后让U-Boot自己重新定位到高端内存,这样比较方便。