0%

opensbi 介绍

opensbi 介绍

背景

RISC-V指令集的SBI标准规定了类Unix平台下,操作系统运行环境的规范。这个规范拥有多种实现,OpenSBI是它的一种实现.
这个运行环境不仅将引导启动RISC-V下的操作系统, 还将常驻后台,为操作系统提供一系列二进制接口,以便其获取和操作硬件信息。 RISC-V给出了此类环境和二进制接口的规范,称为“操作系统二进制接口”,即“SBI”。
SBI是在M模式下运行的特定于平台的固件,它将管理S、U等特权上的程序或通用的操作系统。

RISCV 模式

  • Machine-Level ISA

    • 处理器内核被复位后,默认处于 Machine Mode
    • machine mode读写的寄存器,如mhartid、mstatus、mtvec、mcause
    • machine特权指令,如ecall(所有模式)、mret、sret、wfi(所有模式、U模式可选)
    • 复位、NMI发生后hart状态
    • PMA物理内存属性,原子、order、一致性
    • PMP物理内存保护机制和寄存器
  • Supervisor-Level ISA

    • Supervisor mode读写的寄存器,如sstaus、stvec、scause、satp
    • Supervisor特权指令,如ecal、sret、sfence.vma
    • Page-Based 32/39/48/57-bit Virtual-Memory Systems
  • User-Level ISA

  • Hypervisor Extension (扩展 H-extension)

    • hypervisor 虚拟化读写的寄存器,如hstatus、vstvec、vepc
    • hypervisor特权指令,load/store、fence

RISV 特权模式演进

  • AEE: application execution environment
  • ABI: application binary interface
  • The ABI includes the supported user-level ISA plus a set of ABI calls to interact with the AEE. The ABI hides details of the AEE from the application to allow greater flexibility in implementing the AEE.
  • SEE: supervisor execution environment
  • SBI: supervisor binary interface
  • HEE: hypervisor execution environment
    • isolate the hypervisor from details of the hardware platform.
  • HBI: hypervisor binary interface

所有硬件必须提供M-mode,因为它拥有访问整个机器的能力,最简单的RISC-V实现只有M-mode,但是不能抑制恶意APP。

  • 未扩展前,不支持hypervisor模式
  • hypervisor扩展模式,V标识当前hart是否处于虚拟化模式

  • 为操作系统层(S-mode) 提供 SBI 接口的高特权级别的软件被称为SBI 实现或 特权执行环境(SEE).
  • SBI 实现或SEE工作在M层, 带H扩展的 Host S层 os 也可以实现相关的sbi 接口用来与Guest os 交互通信.

​ 1) 不带H 扩展的 RISCV 系统

​ 2) 带 H 扩展的 RISCV 系统

MIPS 架构

Each Hart can host an application under the same or different guest OS

Allows efficient utilization of pipeline hardware and local cache

With RISC-V H-extension, each hart is a Virtual Machine (RV64GHC)

image-20220915113342870

MIPS UDI (User Defined Instructions)

image-20220915114512140

image-20220915114428090

MIPS (MIPS64r6) User Defined Instructions fills the gap

  • Performance – Prefetch, Paired load/store
  • Coherency – Cache Maintenance
  • Multi-core, multi-cluster – Global Invalidates, Cache Maintenance
  • Diagnostic capabilities – Diagnostic Read/Write

SBI 的作用

  • 可以为多个os提供公共driver
  • 可以避免为每个不同os 适配平台相关的功能, 将功能做到sbi层, 其他的各种os 只需要ecall 调用, 访问sbi层来实现平台的功能
  • 在S层工作的OS 可以通过ecall sbi 来访问或修改受限在M层的硬件资源 (如只能m层访问的CSR)
  • 多个OS之间的通信媒介, 限制不同OS的可以访问的硬件资源 (如PMP限制os可以使用哪些内存地址)

SBI CALL EXTENSION

    1. Base Extension (EID #0x10)

      image-20220909172228003

      Machine Implementation ID Register (mimpid) 提供了处理器实现版本的唯一编码
      Machine Architecture ID Register (marchid) 处理器核架构编号
      Machine Vendor ID Register (mvendorid) 用于指示供应商 ID 的寄存器
    1. Legacy Extensions (EIDs #0x00 - #0x0F)

      image-20220909172256304

      image-20220909172309159

    1. Timer Extension (EID #0x54494D45 “TIME”)

    image-20220909172416146

    1. IPI Extension (EID #0x735049 “sPI: s-mode IPI”)

      image-20220909172449621

    1. RFENCE Extension (EID #0x52464E43 “RFNC”)

      image-20220909172508242

    1. Hart State Management Extension (EID #0x48534D “HSM”)

      The Hart State Management (HSM) Extension introduces a set of hart states and a set of functions which allow the supervisor-mode software to request a hart state change.

      image-20220909172529437

      image-20220909172654319

    1. System Reset Extension (EID #0x53525354 “SRST”)

      The System Reset Extension provides a function that allow the supervisor software to request system-level reboot or shutdown.

      The term “system” refers to the world-view of supervisor software and the underlying SBI implementation could be machine mode firmware or hypervisor.

      image-20220909172720658

    1. Performance Monitoring Unit Extension (EID #0x504D55 “PMU”)

      image-20220909172749677

    1. Experimental SBI Extension Space (EIDs #0x08000000 - #0x08FFFFFF)
    1. Vendor-Specific SBI Extension Space (EIDs #0x09000000 - #0x09FFFFFF)
    1. Firmware Specific SBI Extension Space (EIDs #0x0A000000 - #0x0AFFFFFF)

ecall 初始化过程及调用过程

opensbi_chart.drawio

mtvec 寄存器用于配置m-mode 中断和异常处理程序的入口地址

mscratch 寄存器用于 Machine Mode 下的程序临时保存某些数据

opensbi_trap.drawio

OPENSBI 集成模式

OpenSBI提供了几种类型的参考固件, 都是平台相关的

  • FW_PAYLOAD: Firmware with the next booting stage as a payload
  • FW_JUMP: Firmware with static jump address to the next booting stage
  • FW_DYNAMIC: Firmware with dynamic information on the next booting stage

vendor 厂商可以选择下面的策略定制opensbi:

  • 参考上面的三个模型里的一个定制M层 runtime SEE

  • 使用opensbi的静态库 弹性定制M-mode runtime SEE

  • 使用opensbi静态库扩展 M-mode 的spl

FW_PAYLOAD

image-20220915144648455

优点:

  • opensbi的前一级只需要加载opensbi
  • 允许opensbi 覆盖设备树

缺点:

  • 每次下级镜像改动, 都需要重新编译opensbi
  • opensbi的前一级无法给opensbi的下一级传递参数

FW_JUMP

image-20220915145051827

优点:

  • opensbi不需要加载下一级镜像
  • opensbi的体积小, 下一级镜像变动时, 只要固定地址不变, 就不需要重新编译

缺点:

  • opensbi的前一级需要同时加载opensbi 和 opensbi的下一级, 加载的地址也必须是固定的, opensbi需要提前知道这个固定地址
  • opensbi的前一级无法给opensbi传参

FW_DYNAMIC

image-20220915145516339

优点:

  • opensbi不需要加载下一级镜像
  • opensbi的前一级可以给opensbi传递参数
  • opensbi 的下一级变动后不需要重新编译

缺点:

  • opensbi的前一级需要同时加载opensbi 和 opensbi的下一级

image-20220915145816145

使用opensbi 扩展spl

image-20220915145854140

M-mode spl 和 opensbi的静态库链接起来, spl承接SEE runtime

ex: open-source EDK2 (UEFI implementation) OpenSBI integration

引导过程

RISC-V芯片的启动流程演变历程:

ZSBL(第0阶段Bootloader)

处于M-mode的ZSBL保存在bootrom中,它负责从GPT中加载更为复杂的spl(寻找uuid的GPT分区)。通过先加载GPT的头文件,然后一块一顺序地扫描GPT。加载过程结束后,spl被加载进地址为sram中,随后,将执行spl阶段。

SPL(第1阶段Bootloader)

处于M-mode的SPL从SRAM上执行,它负责为在DDR上运行系统做准备,可大概分为如下的这些任务:

  • 配置芯片上的PLL 核心频率
  • 配置DDR PLL,PHY和DDR控制器
  • 外部PHY,重置
  • 从编号为uuid的GTP分区下载 SEE(opensbi 实现)
  • 扫描OTP获取的芯片序列号
  • 将DTB(硬件设备树)复制到DDR,填写SPL版本,内存大小和MAC地址
  • 跳转到DDR上, 启动SEE (opensbi 实现)

SEE (opensbi 实现)

OpenSBI的初始化流程如下:

(1)底层初始化:
1. 判断hart(Hardware Thread) id
2. 代码重定位(判断_load_start与_start函数是否一致)
3. 清除除保存设备树地址的寄存器的值
4. 清除bss段
5. 设置栈指针(预留栈空间)
6. 读取设备树中的设备信息
7. 设备树重定位,为U-Boot提供信息
8. 至此,底层初始化结束,执行sbi_init,进行正式的初始化程序

(2)设备初始化:
1. sbi_domain_init 初始化动态加载的镜像的模块
2. sbi_platform_early_init 平台的早期初始化
3. sbi_console_init 控制台初始化,从这里开始,就可以使用串口输出了。
4. sbi_platform_irqchip_init        irq中断初始化
5. sbi_ipi_init    核间中断初始化
6. sbi_tlb_init    mmu的tlb表的初始化
7. sbi_timer_init    timer初始化
8. sbi_hsm_prepare_next_jump   准备下一级的boot

(3)二级boot跳转,跳转Uboot, PAYLOAD 模式中, uboot的代码会装载到 SEE的特定位置 (汇编中使用.incbin 实现), 跳转时, 不再需要从GPT 加载uboot, 只需要跳转到 uboot 起始地址即可

uboot(第2阶段的Bootloader)

uboot 从gpt分区中加载kernel到DDR, 解压, 验证kernel, 跳转到kernel

U-Boot属于一种bootloader,简单来说,其作用就是从flash中读出内核,随后加载在内存中,最终初始化并启动操作系统内核。
具体来说,可以分为下述几个方面:

  1. U-Boot主要作用是用来启动操作系统内核。体现在uboot最后一句代码就是启动内核。
  2. U-Boot还要负责部署操作系统内核。体现在uboot最后的传参。
  3. U-Boot中还有操作Flash等板子上硬件的驱动。例如串口要打印,ping网络,擦除、烧写flash等。提供烧写功能等
  4. U-Boot还得提供一个命令行界面供人来操作。如果kernel 起不来, uboot命令行可以提供操作界面, 让用户来手动加载kernel

opensbi 软件栈层级

image-20220915150631597

  1. 通用平台抽象 libsbi.a

    抽象出平台无关的feature 接口, 供外界组件使用, 生成libsbi.a, 外界组件link

  2. 平台相关实现 (硬件依赖驱动实现) libplatsbi.a

    实现特定平台特定硬件驱动的 sbi_platform 的hook

    libplatsbi.a = libsbi.a + struct sbi_platform instance

    image-20220915152353528

  3. 平台自定集成固件

    厂商自定义添加ecall extension

    ex: SBI_EXT_EXPERIMENTAL_KEYSTONE_ENCLAVE 0x08424b45

    image-20220915152730792

    image-20220915153005588

ARM架构中的Hypervisor与OpenSBI的对比

在ARM架构中,Hypervisor层承担了虚拟化的作用,承担了如内存管理、设备模拟、设备分配、异常处理、指令捕获、虚拟异常管理、中断控制器管理、调度、上下文切换、内存转换、多个虚拟地址空间管理等非常多的功能。
相比之下,SBI在RISC-V架构中充当了BIOS和在操作系统运行时为上层提供底层抽象的作用,功能较少。不过SBI也在不断发展中,可能在将来SBI会去承担虚拟化的功能。