-
OpenSBI平台固件
OpenSBI提供了针对特定平台的固件构建。支持不同类型的固件来处理不同平台早期启动阶段的差异。所有的固件都会根据平台特定的代码以及OpenSBI通用库代码执行平台硬件的相同的初始化过程。所支持的固件类型将因平台早期引导阶段传递的参数的处理方式以及固件之后的引导阶段的处理和执行方式而有所不同。
早期的启动阶段将通过RISC-V CPU的以下寄存器传递信息:
-
hardid通过a0寄存器传递。
-
通过a1寄存器在内存中的设备树blob地址。地址必须对齐到8个字节。
OpenSBI目前支持三种不同类型的固件
-
带有动态信息的固件(FW_DYNMIC)
流程:
FW_DYNAMIC固件在运行时从上一个引导阶段获取下一个引导阶段入口的信息,例如引导加载程序或操作系统内核。
-
下一个启动阶段(如bootloader)和FW_DYNAMIC被上一个启动阶段加载(如LOADER)
-
上一个启动阶段(即LOADER)通过' a2 '寄存器将struct fw_dynamic_info的位置传递给FW_DYNAMIC
-
之前的启动阶段(即LOADER)需要知道struct fw_dynamic_info
struct fw_dynamic_info {
/** Info magic */
unsigned long magic;
/** Info version */
unsigned long version;
/** Next booting stage address */
unsigned long next_addr;
/** Next booting stage mode */
unsigned long next_mode;
/** Options for OpenSBI library */
unsigned long options;
/**
* Preferred boot HART id
*
* It is possible that the previous booting stage uses same link
* address as the FW_DYNAMIC firmware. In this case, the relocation
* lottery mechanism can potentially overwrite the previous booting
* stage while other HARTs are still running in the previous booting
* stage leading to boot-time crash. To avoid this boot-time crash,
* the previous booting stage can specify last HART that will jump
* to the FW_DYNAMIC firmware as the preferred boot HART.
*
* To avoid specifying a preferred boot HART, the previous booting
* stage can set it to -1UL which will force the FW_DYNAMIC firmware
* to use the relocation lottery mechanism.
*/
unsigned long boot_hart;
} __packed;
-
带跳转地址的固件(FW_JUMP)
FW_JUMP固件假设下一个引导阶段入口的地址是固定的,例如引导加载程序或操作系统内核,而不直接包含下一个阶段的二进制代码。
-
下一个启动阶段(bootloader), 上一个启动阶段(LOADER)加载FW_JUMP
-
这对QEMU非常有用,因为我们可以使用预编译的FW_JUMP
-
上一个启动阶段(即LOADER)必须在一个固定的位置加载下一个启动阶段(即bootloader)
-
没有机制将参数从之前的启动阶段(即LOADER)传递给FW_JUMP
-
带负载的固件(FW_PAYLOAD)
FW_PAYLOAD固件直接包含了OpenSBI固件执行后启动阶段的二进制代码。通常,这个有效负载将是一个引导加载程序或一个OS内核。
-
OpenSBI FW_PAYLOAD可以是任何 S-mode的 bootloader/os 镜像文件。
-
允许重写设备树blob(即DTB)
-
非常适合sifve unmached板子
-
每当OpenSBI或BOOTLOADER (U-Boot)改变时,我们必须重新创建FW_PAYLOAD映像
-
上一个启动阶段(LOADER)不会传递参数给下一个启动阶段
-
固件配置和编译
所有固件类型都支持以下通用编译时配置参数:
-
FW_TEXT_ADDR -定义OpenSBI固件的执行地址。必选参数。
-
FW_FDT_PATH -外部扁平设备树二进制文件的路径,该文件将被嵌入到最终固件的.rodata部分中。如果没有提供这个选项,那么固件将期望FDT作为参数在之前的引导阶段传递。
-
FW_FDT_PADDING- FW_FDT_PATH选项指定嵌入式扁平设备树二进制文件,可选零字节填充。
-
FW_PIC - "FW_PIC=y"生成位置独立的可执行固件镜像。OpenSBI可以运行在任意地址,并保持适当的对齐。因此,原有的迁移机制(FW_PIC=n)将被跳过。换句话说,OpenSBI将直接运行在加载地址,而不需要任何代码移动。这个选项需要一个支持PIE的工具链,默认情况下是开启的。
-
为OpenSBI提供不同的负载
OpenSBI固件可以使用编译时选项接受各种有效负载。通常,这些有效负载指的是下一阶段引导加载程序(例如U-Boot)或操作系统内核映像(例如Linux)。默认情况下,如果在编译时没有指定特定的负载,那么OpenSBI会自动提供一个测试负载。
要在编译时指定有效负载,需要使用make变量FW_PAYLOAD_PATH。
make PLATFORM=<platform_subdir> FW_PAYLOAD_PATH=<payload path>
-
OpenSBI固件行为选项
一个可选的编译时标志FW_OPTIONS可以用来控制OpenSBI固件的运行时行为。
make PLATFORM=<platform_subdir> FW_OPTIONS=<options>
FW_OPTIONS是不同选项的按位值,例如:FW_OPTIONS=0x1代表OpenSBI库禁止启动打印。
对于所有支持的选项,请查看include/sbi/sbi_scratch.h头文件中的“enum sbi_scratch_options”。