riscvlinux参考启动流程
本篇博客涉及到了 riscv 从0开始到 linux 启动成功的流程,涉及到以下标准
The Standardized Boot flow for RISC-V Platforms : crva.ict.ac/crvs2020/index/slides/3-8.pdf学校老师
本博客从以下⾓度分析启动历程
1. risc-v 的运⾏模式
糖醋里脊肉怎么做2.芯⽚启动配置
3.⾮易失性存储器的镜像布局
4. risc-v 的启动流程
5.易失性存储器的镜像布局
risc-v的运⾏模式
risc-v ⽀持三种运⾏模式
U-Mode S-Mode M-Mode
U-Mode :⽤户程序运⾏在这个Mode
S-Mode : OS运⾏在这个Mode
M-Mode : A bare metal machine mode,OPENSBI运⾏在这个Mode
这其中前沿技术:虚拟化和安全扩展不在 rsic-v 架构设计范围内
我们需要⽤软件提供虚拟化和安全扩展,其中
虚拟化
由软件 OpenSBI 提供,OpenSBI 是 risc-v 官⽅提供的
SBI 意义为 RISC-V Open Source Supervisory Binary Interface
OpenSBI 运⾏在 M-Mode,在OS(运⾏在S-Mode)之下域名劫持
RISC-V start from M-Mode, A bare metal machine mode.
在启动时, OpenSBI switch into S-Mode from M-Mode for non-hypervisor world.煨
相当于 ARM64 的Hypervisor/EL2 层,这⼀层在ARM64中是由硬件提供的,⽽在RISCV中,是由硬件提供的 System call type interface layer between Firmware runtime, M-Mode to Operating system, S-Mode.
opensbi 能编译出三种固件(FW_PAYLOAD FW_JUMP FW_DYNAMIC),⽤于不同的启动⽅式
my.oschina/u/4239621/blog/4872019
risc-v 硬件上不提供虚拟化,软件OpenSBI提供虚拟化
安全扩展
TEE : Trusted Execution Environment
risc-v 硬件上不提供TEE,软件Penglai-Enclave提供虚拟化
it is bad on OpenSBI
微信案例Penglai-Enclave 运⾏在 M-Mode,在OS(运⾏在S-Mode)之下,在OpenSBI(运⾏在M-mode)之上
芯⽚启动配置
⼀般芯⽚内置srom和sram,srom中有软件代码,被称为bootrom
bootrom中会做⼀些⾮易失性存储器的初始化
// 主要是为了读取SPL代码
// SPL代码是板卡⽤户可配置的⼀般⽤于被bootrom加载的代码
// cond program loader 第⼆阶段程序加载器 ,说明其是第⼀阶段
// 根据 The Standardized Boot flow for RISC-V Platforms, SPL 由 U-boot-SPL 提供
// SPL代码⼀般有⼤⼩限制(⼀般不会超过8KB)
bootrom中会读取启动配置,并决定从哪种⾮易失性存储器读取SPL
/
/ 启动配置为⼏个引脚
// ax45mp 数据⼿册中没有启动配置的引脚,但说了可以通过设置每个核⼼的 ret vector 寄存器的值
// 问题是设置该寄存器需要代码,但是该寄存器的值就是读取代码的位置
// 鸡⽣蛋与蛋⽣鸡的问题. 估计数据⼿册没有暴漏,或者是写死的.
// 例如 ax45mp VCU118 被配置为从 SPI1 连接的 2MB的 QSPI Flash 启动
// SP1 AHB memory 被映射到了 0x8000 0000 - 0x87FF FFFF
⾮易失性存储器的镜像布局
根据 The Standardized Boot flow for RISC-V Platforms 以及 linux启动流程,我们需要以下镜像⽂件
1. u-boot-spl
2. board-device.dtb
3. opensbi
4. u-boot
5. linux
涛贝勒府
6. rootfs
u-boot-spl 在启动配置选取的⾮易失性存储器A的指定位置(数据⼿册)
board-device.dtb 在⾮易失性存储器B的某个位置(由u-boot-spl指定)
opensbi 在⾮易失性存储器C的某个位置(由u-boot-spl指定)
u-boot 在⾮易失性存储器D的某个位置(由u-boot-spl指定)
linux 在⾮易失性存储器F的某个位置(由u-boot指定)
rootfs 在⾮易失性存储器G的某个位置(由u-boot指定)
注意:⾮易失性存储器A B C D E F G 可以为同⼀个,也可以不为同⼀个
risc-v 的启动流程
联欢游戏
上电,pc处于system memory map中的bootrom中前沿位置,运⾏模式为M-mode
01. bootrom 根据拨码开关去定位 u-boot-spl 在哪⾥,并加载 u-boot-spl 到 ilm
A1. u-boot-spl XIP运⾏,或者被bootrom搬到某个 memory地址开始执⾏
A2. u-boot-spl 初始化⾮易失性存储器B/C/D ,初始化 ddr
A3. u-boot-spl 从⾮易失性存储器B 加载 board-device.dtb 到 ddr
A4. u-boot-spl 从⾮易失性存储器C 加载 opensbi 到 ddr
A5. u-boot-spl 从⾮易失性存储器D 加载 u-boot 到 ddr
A6.跳转到 opensbi
B1. opensbi 根据 board-device.dtb 初始化 domain 和 platform ,并对设备树进⾏fix_up处理
B2. opensbi 切换到 S-mode ,跳转到 U-boot
C1. U-boot 根据 fix_up 后的设备树初始化 platform ,并对设备树再次 fix_up
C2. U-boot 从⾮易失性存储器D 加载 linux 到 ddr
C3. U-boot 跳转到 linux
D1. linux 创建页表,开MMU,创建物理内存管理机制和虚拟内存管理机制
D2. linux 初始化调度器,将⾃⼰(standalone)与init_task绑定
D3. linux 创建 kernel_init 内核线程,并开启调度
D4. linux 中的 kernel_init 根据 fix_up 后的设备树对platform 初始化
D5. linux 中的 kernel_init mount 真实⽂件系统(上⾯提到的rootfs)
深林人不知明月来相照
D6. linux 中的 kernel_init 调⽤ run_init_process 更改1号进程的PCB相连的thread_info中的相关寄存器为U-Mode,并主动调度D7. linux 中的1号调度实体(init⽤户进程)被调度回来,即进⼊U-mode
E1. init⽤户进程开始启动⽤户相关进程,并为⽤户提供服务
注释:此时三个运⾏模式都运⾏着不同的代码,三套代码时分复⽤PE
1. U-Mode ⽤户进程
2. S-Mode linux代码// 为⽤户进程提供服务
3. M-Mode OpenSBI // 像 linux为⽤户进程提供服务⼀样 , 为 linux 提供服务
易失性存储器的镜像布局
u-boot-spl 在 SRAM 或者FLASH(XIP)上
board-device.dtb&opensbi&u-boot&linux 在 sdram/ddr/ddr2/ddr3/ddr4 中
rootfs中的 super_block&dentry&inode&buffercache 缓存在 sdram/ddr/ddr2/ddr3/ddr4 中