在RISC-V架构下,Linux内核会在多种情况下调用OpenSBI的代码。OpenSBI(Open Source Supervisor Binary Interface)是RISC-V平台上提供M模式(Machine Mode)服务的固件,它允许S模式(Supervisor Mode)的操作系统通过SBI(Supervisor Binary Interface)与M模式进行交互。以下是一些典型的调用场景:
-
系统启动时:
- 在系统启动过程中,OpenSBI通常作为引导加载程序的一部分被加载并执行。启动流程通常如下:
- 系统上电复位(Power-On Reset, POR)后,从ROM开始启动,将SPL(Second Program Loader)加载到SRAM中并跳转到SPL执行。
- SPL进行DDR初始化,并将OpenSBI和U-Boot加载到DDR中,然后跳转到OpenSBI执行。
- OpenSBI执行相关初始化设置后,跳转到U-Boot执行。
- U-Boot加载Linux内核到DDR中,进行解析、解压等操作,最后跳转到Linux内核执行。
- 在系统启动过程中,OpenSBI通常作为引导加载程序的一部分被加载并执行。启动流程通常如下:
-
内核初始化时:
- 在Linux内核启动过程中,内核会调用
sbi_init()
函数来初始化SBI接口。这个函数会设置电源管理、获取SBI版本信息,并根据SBI版本配置定时器、IPI(Inter-Processor Interrupts)、远程栅栏(Remote Fence)等功能的函数指针。
- 在Linux内核启动过程中,内核会调用
-
定时器中断:
- Linux内核使用SBI接口来设置定时器中断。例如,内核会调用
__sbi_set_timer_v02()
函数,通过SBI的时间扩展(SBI_EXT_TIME)来设置定时器。
- Linux内核使用SBI接口来设置定时器中断。例如,内核会调用
-
IPI(Inter-Processor Interrupts):
- 内核在需要发送IPI时,会调用SBI接口。例如,通过调用
__sbi_send_ipi()
函数来触发IPI中断。
- 内核在需要发送IPI时,会调用SBI接口。例如,通过调用
-
远程栅栏(Remote Fence):
- 当内核需要在多个核之间同步内存操作时,会使用SBI的远程栅栏功能。例如,通过调用
__sbi_remote_fence_i()
函数来触发远程指令栅栏(Fence.I)。
- 当内核需要在多个核之间同步内存操作时,会使用SBI的远程栅栏功能。例如,通过调用
-
CPU启动和停止:
- 内核在启动或停止CPU核时,会调用SBI的HSM(Hart State Management)扩展。例如,通过调用
__sbi_hart_start()
函数来启动一个CPU核,或者调用__sbi_hart_stop()
函数来停止一个CPU核。
- 内核在启动或停止CPU核时,会调用SBI的HSM(Hart State Management)扩展。例如,通过调用
-
系统关机和重启:
- 当内核需要关机或重启系统时,会调用SBI的系统重置扩展(SBI_EXT_SRST)。例如,通过调用
__sbi_system_reset()
函数来触发系统重置。
- 当内核需要关机或重启系统时,会调用SBI的系统重置扩展(SBI_EXT_SRST)。例如,通过调用
以下是一个典型的SBI调用代码示例:
struct sbiret sbi_ecall(int ext,