3. RISC-V 特权架构基础:机器模式、监督模式、用户模式与 CSR 寄存器
RISC-V 特权架构定义了三种核心特权模式(Privilege Modes),以及一套用于配置和控制处理器行为的控制状态寄存器(CSR,Control and Status Register)。理解这些模式与寄存器是进行 xv6 内核移植和板级支持包(BSP)构建的基石。xv6 主要运行在监督模式(S-Mode)下,但启动和底层硬件管理必须依赖机器模式(M-Mode)。
3.1 三种特权模式与层级关系
RISC-V 规范定义了三种特权级别,形成一个严格的层级保护模型。数字越大,特权越高。
| 模式名称 | 编码 | 缩写 | 主要用途 | xv6 中的角色 |
|---|---|---|---|---|
| 机器模式 | 11 | M-Mode | 硬件复位、异常处理、物理内存属性、安全启动 | 引导加载程序(如 OpenSBI)运行于此,为 xv6 准备环境 |
| 监督模式 | 01 | S-Mode | 操作系统内核运行、虚拟内存管理、中断处理 | xv6 内核主体运行于此 |
| 用户模式 | 00 | U-Mode | 应用程序运行、受限指令集、页级保护 | xv6 的用户进程运行于此 |
ecall 指令从 S-Mode 陷入 M-Mode,以请求 SBI 服务(如控制台输出、定时器设置)。这种设计将硬件平台相关的代码隔离在 M-Mode,使 xv6 内核本身具有更好的可移植性。
3.2 核心 CSR 寄存器分类与功能
CSR 寄存器是 RISC-V 架构中用于配置和控制处理器状态的关键接口。根据特权模式,CSR 分为三类:机器级(M-Mode)、监督级(S-Mode)和用户级(U-Mode)。xv6 内核主要操作监督级 CSR,但启动阶段会通过 SBI 间接访问机器级 CSR。
3.2.1 机器模式 CSR(M-Mode CSR)
这些寄存器只能在 M-Mode 下通过 csrrw、csrrs 等指令访问。在 S-Mode 或 U-Mode 下访问将触发非法指令异常。
| CSR 名称 | 地址 | 描述 | 在 xv6 移植中的角色 |
|---|---|---|---|
mvendorid |
0xF11 | 制造商 ID | 用于识别 CPU 厂商,调试时使用 |
marchid |
0xF12 | 架构 ID | 标识处理器实现的 RISC-V 架构版本 |
mimpid |
0xF13 | 实现 ID | 处理器微架构版本信息 |
mhartid |
0xF14 | 硬件线程 ID | 多核系统中每个核心的唯一标识 |
mstatus |
0x300 | 机器状态寄存器 | 控制全局中断使能、特权模式切换等 |
medeleg |
0x302 | 机器异常委托寄存器 | 将特定异常委托给 S-Mode 处理,xv6 依赖此机制 |
mideleg |
0x303 | 机器中断委托寄存器 | 将特定中断委托给 S-Mode 处理 |
mie |
0x304 | 机器中断使能寄存器 | 控制 M-Mode 下各中断源的使能 |
mtvec |
0x305 | 机器陷阱向量基址寄存器 | 设置 M-Mode 异常处理程序的入口地址 |
mepc |
0x341 | 机器异常程序计数器 | 保存发生异常时的返回地址 |
mcause |
0x342 | 机器异常原因寄存器 | 指示异常或中断的类型 |
mtval |
0x343 | 机器陷阱值寄存器 | 提供异常的附加信息(如访存地址) |
3.2.2 监督模式 CSR(S-Mode CSR)
这些寄存器是 xv6 内核直接操作的核心。S-Mode 下的代码可以直接读写它们,用于管理页表、处理中断和异常。
| CSR 名称 | 地址 | 描述 | 在 xv6 中的典型用途 |
|---|---|---|---|
sstatus |
0x100 | 监督状态寄存器 | 控制 S-Mode 中断使能(SIE 位)、用户模式访问权限(SUM 位) |
sie |
0x104 | 监督中断使能寄存器 | 使能/禁用外部中断(SEIE)、定时器中断(STIE)、软件中断(SSIE) |
stvec |
0x105 | 监督陷阱向量基址寄存器 | 设置 xv6 内核的异常/中断处理入口(trampoline 或 kernelvec) |
scounteren |
0x106 | 监督计数器使能寄存器 | 控制 U-Mode 下对性能计数器的访问权限 |
sscratch |
0x140 | 监督临时寄存器 | 在陷阱处理中保存 CPU 核心的 proc 结构体指针 |
sepc |
0x141 | 监督异常程序计数器 | 保存发生异常时的用户态或内核态返回地址 |
scause |
0x142 | 监督异常原因寄存器 | 指示异常类型(如系统调用、页错误、外部中断) |
stval |
0x143 | 监督陷阱值寄存器 | 提供异常的附加信息(如导致页错误的虚拟地址) |
satp |
0x180 | 监督地址转换和保护寄存器 | 控制页表的基地址、地址空间标识符(ASID)和页表模式(Sv39) |
sscratch 寄存器被用于在用户态和内核态之间快速交换 proc 指针。如果在移植过程中修改了陷阱处理流程,务必确保 sscratch 的初始化和使用逻辑与 xv6 原版一致,否则会导致内核崩溃。
3.3 异常委托机制:从 M-Mode 到 S-Mode
默认情况下,所有异常和中断都会陷入 M-Mode。为了让 xv6 内核能够直接处理系统调用、页错误和外部中断,RISC-V 提供了异常委托机制。通过配置 medeleg 和 mideleg 寄存器,可以将特定类型的异常和中断直接委托给 S-Mode 处理,而无需经过 M-Mode 的 SBI 固件。
3.3.1 委托的异常类型
xv6 依赖以下异常被委托给 S-Mode:
- 系统调用 (Exception Code 8):用户程序通过
ecall指令请求内核服务。 - 断点 (Exception Code 3):用于调试器支持。
- 指令页错误 (Exception Code 12):取指令时发生页错误。
- 加载页错误 (Exception Code 13):加载指令时发生页错误。
- 存储/AMO 页错误 (Exception Code 15):存储或原子操作时发生页错误。
3.3.2 委托的中断类型
xv6 依赖以下中断被委托给 S-Mode:
- 监督软件中断 (SSI, Interrupt Code 1):用于多核处理器间的核间中断(IPI)。
- 监督定时器中断 (STI, Interrupt Code 5):用于实现时间片轮转调度。
- 监督外部中断 (SEI, Interrupt Code 9):来自 PLIC(平台级中断控制器)的设备中断。
medeleg 和 mideleg。如果委托配置错误,xv6 将无法收到任何中断或系统调用,导致系统无响应。你可以通过检查 SBI 的启动日志或使用调试器读取这两个 CSR 的值来验证。
3.4 陷阱处理流程:从用户态到内核态
当用户进程执行 ecall 指令或发生异常时,硬件自动执行以下步骤:
- 保存返回地址:将当前 PC 值保存到
sepc寄存器。 - 记录异常原因:将异常类型编码写入
scause寄存器。 - 记录附加信息:将异常相关地址(如页错误地址)写入
stval寄存器。 - 关闭中断:将
sstatus.SIE位复制到sstatus.SPIE,然后清除sstatus.SIE以禁止嵌套中断。 - 切换模式:将当前特权模式(U-Mode)保存到
sstatus.SPP,然后切换到 S-Mode。 - 跳转到处理程序:将 PC 设置为
stvec寄存器中的值(在 xv6 中为trampoline页的起始地址)。
以下代码展示了 xv6 中 trampoline.S 中处理用户态陷阱的入口部分:
# 来自 xv6 源码 kernel/trampoline.S
# 用户态陷阱处理入口
.globl uservec
uservec:
# 1. 交换 sscratch 和 a0,sscratch 中保存了 trapframe 指针
csrrw a0, sscratch, a0
# 2. 保存用户寄存器到 trapframe
sd ra, 40(a0)
sd sp, 48(a0)
# ... 保存其他寄存器 ...
# 3. 保存用户 PC(sepc)到 trapframe
csrr t0, sepc
sd t0, 112(a0)
# 4. 保存用户模式(sstatus)到 trapframe
csrr t1, sstatus
sd t1, 120(a0)
# 5. 加载内核栈指针
ld sp, 8(a0)
# 6. 加载内核页表(satp)
ld t0, 16(a0)
csrw satp, t0
sfence.vma zero, zero
# 7. 跳转到 C 语言处理函数 usertrap
ld t0, 0(a0)
jr t0
trampoline 代码中,使用 csrrw 指令原子地交换 sscratch 和 a0 是一种常见的优化技巧。它避免了在进入陷阱处理时先保存 a0 到内存的额外开销。在移植到新的 CPU 时,请确保 sscratch 在进程创建时已被正确初始化为该进程的 trapframe 地址。
3.5 本章小结
RISC-V 的特权架构为 xv6 提供了清晰的保护边界和灵活的配置能力。M-Mode 作为可信计算基(TCB),运行 SBI 固件,为 S-Mode 的 xv6 内核提供平台抽象。S-Mode 的 CSR 寄存器是 xv6 实现进程管理、内存虚拟化和中断处理的核心工具。理解这些模式与寄存器的交互关系,是成功将 xv6 移植到新硬件平台的第一步。