启动参数的传递
4 Dec 2024
Read time: 3 minute(s)
启动过程中,不同的启动流程会用到不同启动参数,用于将当前一级程序的信息传递给下一级程序, 辅助下一级程序的执行,详情如下:
| 参数名称 | 寄存器 | 说明 |
|---|---|---|
| boot device | R0,bit[3:0] | 启动的存储介质 ID |
| boot reason | R0,bit[7:4] | 启动的原因,如:冷启动、热启动 |
| image id | R0,bit[11:8] | 使用的备份镜像 ID |
| boot time | R1 | BROM 启动所使用的时间(us) |
| 参数名称 | 寄存器 | 说明 |
|---|---|---|
| boot device | a0,bit[3:0] | 启动的存储介质 ID |
| boot reason | a0,bit[7:4] | 启动的原因,如:冷启动、热启动 |
| image id | a0,bit[11:8] | 使用的备份镜像 ID |
| boot time | a1 | BROM 启动所使用的时间(us) |
| 参数名称 | 寄存器 | 说明 |
|---|---|---|
| boot device | R0,bit[3:0] | 启动的存储介质 ID,BROM 传递过来的值 |
| boot reason | R0,bit[7:4] | 启动的原因,BROM 传递过来的值 |
| image id | R0,bit[11:8] | 暂时没有使用 |
| boot time | R1 | SPL 启动所使用的时间(us) |
SPL 和 U-Boot 跳转到内核时传递的参数相同,分别是:
-
R0: zero
-
R1: mach id
-
R2: FDT address
无论是 SPL 还是 U-Boot,在执行时的第一步动作就是保存这些启动参数, 具体实现可参考 arch/arm/cpu/armv7/start.S
reset:
/* Allow the board to save important registers */
b save_boot_params
save_boot_params_ret:save_boot_params 的实现在源文件 arch/arm/mach-artinchip/lowlevel_init.S
ENTRY(save_boot_params)
stmfd sp!, {r4} /* Backup r4 on caller's stack */
ldr r4, =boot_params_stash
stmia r4!, {r0 - r3} /* Save r0 ~ r3 to boot_params_stash */
mov r0, r4
ldmfd sp!, {r4} /* Restore r4 */
stmia r0!, {r4 - r13, lr} /* Save r4 ~ r14 to boot_params_stash */
b save_boot_params_ret
ENDPROC(save_boot_params)传递的参数被保存在全局变量 boot_params_stash 中,SPL 或者 U-Boot 可从中获取相关信息。 在保存参数时,不仅将 R0,R1 寄存器保存起来,还将其他重要寄存器一起保存。 原因是这里不仅要传递参数,还为了实现 SPL 返回 BROM 的功能。将其他寄存器一起保存, 相当于保存了调用现场,需要返回时可以 boot_params_stash 中恢复相应的寄存器参数。
无论是 SPL 还是 U-Boot,在执行时的第一步动作就是保存这些启动参数, 具体实现可参考 arch\riscv\cpu\start.S
_start:
/* Allow the board to save important registers */
j save_boot_params
save_boot_params_ret:save_boot_params 的实现在源文件 arch\riscv\mach-artinchip\lowlevel_init.S
ENTRY(save_boot_params)
la t0, boot_params_stash
SREG a0, REGBYTES * 0(t0)
SREG a1, REGBYTES * 1(t0)
SREG a2, REGBYTES * 2(t0)
SREG a3, REGBYTES * 3(t0)
SREG a4, REGBYTES * 4(t0)
SREG a5, REGBYTES * 5(t0)
SREG a6, REGBYTES * 6(t0)
SREG a7, REGBYTES * 7(t0)
SREG s0, REGBYTES * 8(t0)
SREG s1, REGBYTES * 9(t0)
SREG s2, REGBYTES * 10(t0)
SREG s3, REGBYTES * 11(t0)
SREG s4, REGBYTES * 12(t0)
SREG s5, REGBYTES * 13(t0)
SREG s6, REGBYTES * 14(t0)
SREG s7, REGBYTES * 15(t0)
SREG s8, REGBYTES * 16(t0)
SREG s9, REGBYTES * 17(t0)
SREG s10, REGBYTES * 18(t0)
SREG s11, REGBYTES * 19(t0)
SREG sp, REGBYTES * 20(t0)
SREG ra, REGBYTES * 21(t0)
j save_boot_params_ret
ENDPROC(save_boot_params)传递的参数被保存在全局变量 boot_params_stash 中,SPL 或者 U-Boot 可从中获取相关信息。具体用法参考上一节。
相关宏定义的实现在源文件 arch\riscv\cpu\mtrap.S
#define LREG ld #define SREG sd #define REGBYTES 8
