Edit online

启动参数的传递

3 Mar 2025
Read time: 4 minute(s)
启动过程中,不同的启动流程会用到不同启动参数,用于将当前一级程序的信息传递给下一级程序, 辅助下一级程序的执行,详情如下:
1. BROM 跳转到 SPL 或者 U-Boot 时传递的参数

参数名称

寄存器

说明

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)

2. BROM RISCV 跳转到 SPL 或者 U-Boot 时传递的参数

参数名称

寄存器

说明

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)

3. SPL 跳转 U-Boot 时传递的参数

参数名称

寄存器

说明

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