- U-Boot 阶段
1.概述
介绍u-boot启动流程中和具体版型(board)有关的部分,也即board_init_f/board_init_r所代表的、board有关初始化过程。该过程将持续u-boot的整个生命周期,直到main_loop(即命令行)。
u-boot的基本策略,就是声明一系列的API(如low_level_init、board_init_f、board_init_r等等),并在u-boot的核心逻辑中调用它们。平台的移植和开发者,所需要做的,就是根据实际情况,实现它们。
与此同时,为了减少开发的工作量,u-boot为大部分API提供了通用实现(一般通过CONFIG配置项或者若定义去控制是否编译)。以board_init_f和board_init_r两个板级的初始化接口为例,u-boot分别在common/board_f.c和common/board_r.c两个文件中提供了通用实现。
U-Boot 在 ZX 平台上承担两个功能角色:
- 引导内核
- 镜像烧录
1.1.前初始化
U-Boot 的前初始化是指执行代码重定位之前的初始化,此时 U-Boot 在 DRAM 的前端空间执行。
前初始化分为两个阶段:
- 芯片架构相关的初始化代码
- 板子相关的前初始化代码
1.1.1. 芯片架构相关初始化
这个阶段主要是对 CPU 进行了基本的初始化,并且将上一级引导程序传递过来的参数保存起来。 ZX 平台上实现了对应的 save_boot_params 处理函数,并且将调用现场的关键寄存器信息保存到 boot_params_stash 全局变量中。
_start // arch/riscv/cpu/start.S
|-> save_boot_params // arch/riscv/mach-zx/lowlevel_init.S
| // BROM 或者 SPL 跳转到 U-Boot 执行的时候,传递了一些参数,这里首先将这
| // 些参数保存起来。
|
|-> la t0, trap_entry // 设置异常处理
|-> li t1, CONFIG_SYS_INIT_SP_ADDR // 设置初始栈
|-> jal board_init_f_alloc_reserve
|-> jal harts_early_init
1.1.2. 板子相关的前初始化
_start // arch/riscv/cpu/start.S
|-> save_boot_params // arch/riscv/mach-zx/lowlevel_init.S
|-> ...
|-> la t5, board_init_f
board_init_f() 函数内逐个调用初始化函数列表 init_sequence_f 中的函数:
common/board_f.c:
static const init_fnc_t init_sequence_f[] = {
setup_mon_len,
#ifdef CONFIG_OF_CONTROL
fdtdec_setup,
#endif
initf_malloc,
log_init,
initf_bootstage, /* uses its own timer, so does not need DM */
setup_spl_handoff,
initf_console_record,
arch_cpu_init, /* basic arch cpu dependent setup */
mach_cpu_init, /* SoC/machine dependent CPU setup */
initf_dm,
arch_cpu_init_dm,
#if defined(CONFIG_BOARD_EARLY_INIT_F)
board_early_init_f,
#endif
env_init, /* initialize environment */
init_baud_rate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
display_options, /* say that we are here */
display_text_info, /* show debugging info if required */
INIT_FUNC_WATCHDOG_INIT
#if defined(CONFIG_MISC_INIT_F)
misc_init_f,
#endif
INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_SYS_I2C)
init_func_i2c,
#endif
announce_dram_init,
dram_init, /* configure available RAM banks */
setup_dest_addr,
reserve_round_4k,
#ifdef