操作系统开发底层知识资料库1-0
目录
-
处理器与寄存器
-
CSR 控制与状态寄存器
-
RISC-V 汇编指令
-
汇编语法与伪指令
-
函数调用约定与 ABI
-
Rust 与汇编的交互
-
特权级与运行环境
-
Trap、中断与异常
-
上下文、任务与线程切换
-
内存管理与地址转换
-
系统调用与 SBI
-
内核对象与进程管理
-
同步、互斥与等待
-
内核启动、链接与可执行文件
-
开发、构建与调试工具
一、处理器与寄存器
1.1 RISC-V 通用寄存器
RISC-V 有 32 个通用寄存器,编号为 x0 至 x31。在 RV64 中,每个通用寄存器宽度为 64 位。
| 编号 | ABI 名称 | 常见用途 |
|---|---|---|
| x0 | zero | 恒为 0 |
| x1 | ra | 返回地址 |
| x2 | sp | 栈指针 |
| x3 | gp | 全局指针 |
| x4 | tp | 线程指针 |
| x5 | t0 | 临时寄存器 |
| x6 | t1 | 临时寄存器 |
| x7 | t2 | 临时寄存器 |
| x8 | s0 / fp | 保存寄存器/帧指针 |
| x9 | s1 | 保存寄存器 |
| x10 | a0 | 参数/返回值 |
| x11 | a1 | 参数/返回值 |
| x12 | a2 | 参数 |
| x13 | a3 | 参数 |
| x14 | a4 | 参数 |
| x15 | a5 | 参数 |
| x16 | a6 | 参数 |
| x17 | a7 | 参数 |
| x18–x27 | s2–s11 | 保存寄存器 |
| x28–x31 | t3–t6 | 临时寄存器 |
1.2 寄存器用途分类
| 类别 | 寄存器 | 说明 |
|---|---|---|
| 零寄存器 | zero |
读取恒为 0 |
| 返回地址 | ra |
保存函数调用返回位置 |
| 栈指针 | sp |
指向当前栈 |
| 全局指针 | gp |
全局数据相关用途 |
| 线程指针 | tp |
线程局部数据相关用途 |
| 参数寄存器 | a0–a7 |
函数参数传递 |
| 返回值寄存器 | a0–a1 |
函数返回值传递 |
| 临时寄存器 | t0–t6 |
临时计算 |
| 保存寄存器 | s0–s11 |
按调用约定由被调用函数维护 |
1.3 需要区分的寄存器概念
-
硬件寄存器: CPU 中真实存在的寄存器。
-
ABI 名称: 为寄存器规定的用途名称。
-
编译器寄存器分配: 编译器决定变量在寄存器或内存中的存放位置。
-
上下文保存: 操作系统将需要保留的寄存器值保存到内存中。
-
寄存器别名: 如
a0与x10指向同一个寄存器,并非两个独立寄存器。
二、CSR 控制与状态寄存器
CSR(Control and Status Register)用于控制处理器状态、特权级、中断、异常与地址转换等功能。
2.1 S 模式常见 CSR
| CSR | 英文名称 | 主要用途 |
|---|---|---|
sstatus |
Supervisor Status | S 模式状态控制 |
sepc |
Supervisor Exception Program Counter | 保存异常/Trap 返回地址 |
scause |
Supervisor Cause | 记录 Trap 原因 |
stval |
Supervisor Trap Value | 提供 Trap 附加信息 |
stvec |
Supervisor Trap Vector | 指定 Trap 入口 |
sscratch |
Supervisor Scratch | 暂存 S 模式相关信息 |
sie |
Supervisor Interrupt Enable | S 模式中断使能 |
sip |
Supervisor Interrupt Pending | S 模式中断挂起状态 |
satp |
Supervisor Address Translation and Protection | 地址转换与页表控制 |
2.2 sstatus 常见字段
| 字段 | 作用 |
|---|---|
SIE |
S 模式全局中断使能 |
SPIE |
保存 Trap 前的中断使能状态 |
SPP |
记录 Trap 前的特权级 |
SUM |
控制 S 模式访问 U 模式页面 |
MXR |
控制从可执行页面读取数据的权限 |
2.3 scause 与 Trap 原因
scause 用于记录进入 S 模式的 Trap 原因,通常需要区分:
-
Interrupt:中断
-
Exception:异常
-
Exception Code:具体原因编号
常见缺页异常编号:
| 编号 | 含义 |
|---|---|
| 12 | 指令缺页异常 |
| 13 | Load 缺页异常 |
| 15 | Store/AMO 缺页异常 |
2.4 stvec 入口模式
| 模式 | 含义 |
|---|---|
| Direct | Trap 进入统一入口 |
| Vectored | 中断可根据原因进入对应向量位置 |
2.5 satp
涉及概念:
-
地址转换模式
-
ASID(地址空间标识符)
-
页表根页号
-
虚拟地址到物理地址的转换
三、RISC-V 汇编指令
以下按用途分类,作为查阅清单。具体指令支持情况应以所使用的 RISC-V 扩展与目标环境为准。
3.1 数据传送与立即数
| 指令 | 作用 |
|---|---|
mv |
寄存器复制,伪指令 |
li |
加载立即数,伪指令 |
la |
加载地址,伪指令 |
lui |
加载立即数高位 |
auipc |
将立即数高位与 PC 相加 |
nop |
空操作,伪指令 |
3.2 整数运算
| 指令 | 作用 |
|---|---|
add |
加法 |
addi |
加立即数 |
sub |
减法 |
mul |
乘法,需相应扩展 |
div |
除法,需相应扩展 |
rem |
取余,需相应扩展 |
and / andi |
按位与 |
or / ori |
按位或 |
xor / xori |
按位异或 |
sll / slli |
左移 |
srl / srli |
逻辑右移 |
sra / srai |
算术右移 |
slt / slti |
有符号小于比较 |
sltu / sltiu |
无符号小于比较 |
3.3 RV64 位宽相关
| 指令 | 作用 |
|---|---|
addw |
32 位加法,结果符号扩展至 64 位 |
addiw |
32 位加立即数 |
subw |
32 位减法 |
sllw |
32 位左移 |
srlw |
32 位逻辑右移 |
sraw |
32 位算术右移 |
3.4 内存访问
| 指令 | 作用 |
|---|---|
lb |
读取 8 位并符号扩展 |
lbu |
读取 8 位并零扩展 |
lh |
读取 16 位并符号扩展 |
lhu |
读取 16 位并零扩展 |
lw |
读取 32 位并符号扩展 |
lwu |
读取 32 位并零扩展 |
ld |
读取 64 位 |
sb |
写入 8 位 |
sh |
写入 16 位 |
sw |
写入 32 位 |
sd |
写入 64 位 |
3.5 分支与跳转
| 指令 | 作用 |
|---|---|
beq |
相等则分支 |
bne |
不相等则分支 |
blt |
有符号小于则分支 |
bge |
有符号大于等于则分支 |
bltu |
无符号小于则分支 |
bgeu |
无符号大于等于则分支 |
jal |
跳转并保存返回地址 |
jalr |
间接跳转并保存返回地址 |
j |
无条件跳转,伪指令 |
jr |
间接跳转,伪指令 |
ret |
函数返回,伪指令 |
call |
函数调用,伪指令 |
3.6 CSR 操作指令
| 指令 | 作用 |
|---|---|
csrrw |
读 CSR,并写入新值 |
csrrs |
读 CSR,并置位 |
csrrc |
读 CSR,并清位 |
csrrwi |
使用立即数写 CSR |
csrrsi |
使用立即数置位 CSR |
csrrci |
使用立即数清位 |
csrr |
读取 CSR,伪指令 |
csrw |
写入 CSR,伪指令 |
csrs |
置位 CSR,伪指令 |
csrc |
清位 CSR,伪指令 |
3.7 特权级与 Trap
| 指令 | 作用 |
|---|---|
ecall |
发起环境调用,触发异常/Trap |
sret |
从 S 模式 Trap 返回 |
mret |
从 M 模式 Trap 返回 |
ebreak |
触发断点异常 |
wfi |
等待中断相关事件 |
3.8 内存屏障与地址转换同步
| 指令 | 作用 |
|---|---|
fence |
约束内存访问顺序 |
fence.i |
同步指令获取与内存写入 |
sfence.vma |
同步地址转换相关状态 |
四、汇编语法与伪指令
4.1 常见汇编表达形式
| 形式 | 含义 |
|---|---|
rd |
目标寄存器 |
rs1、rs2 |
源寄存器 |
imm |
立即数 |
offset(rs1) |
以寄存器值加偏移量计算地址 |
label |
代码标签 |
.section |
指定段 |
.global |
声明全局符号 |
.align |
对齐 |
.word |
定义 32 位数据 |
.dword |
定义 64 位数据 |
.equ |
定义符号常量 |
.macro |
定义汇编宏 |
.endm |
结束汇编宏 |
.rept |
重复汇编内容 |
.set |
设置汇编符号 |
4.2 常见伪指令
| 伪指令 | 常见展开形式/用途 |
|---|---|
mv rd, rs |
addi rd, rs, 0 |
nop |
addi x0, x0, 0 |
ret |
jalr x0, 0(ra) |
j label |
无条件跳转 |
call symbol |
调用函数 |
li rd, imm |
加载常量,可能展开为多条指令 |
la rd, symbol |
加载符号地址,可能展开为多条指令 |
4.3 汇编中常见的地址与位置概念
-
PC:程序计数器,指向当前执行位置。 -
label:汇编代码中的符号位置。 -
symbol:链接器处理的符号。 -
offset:相对某个基址的偏移量。 -
relocation:链接阶段对地址或符号引用进行调整。
五、函数调用约定与 ABI
ABI(Application Binary Interface)规定函数之间如何传递参数、返回值,以及如何使用寄存器和栈。
5.1 RISC-V 常见调用约定
| 项目 | 约定 |
|---|---|
| 参数寄存器 | a0—a7 |
| 返回值寄存器 | a0、a1 |
| 返回地址 | ra |
| 栈指针 | sp |
| 临时寄存器 | t0—t6 |
| 被调用者保存寄存器 | s0—s11 |
5.2 Caller-saved 与 Callee-saved
| 类型 | 寄存器 | 含义 |
|---|---|---|
| Caller-saved | a0—a7、t0—t6 等 |
调用者若需要跨函数调用保留值,应自行保存 |
| Callee-saved | s0—s11 |
被调用函数若修改这些寄存器,应负责恢复 |
具体还需结合 ABI 对 ra、sp 等寄存器的约定理解。
5.3 函数调用基本流程
-
按调用约定准备参数。
-
使用
call、jal或jalr转移控制流。 -
被调用函数按需保存寄存器与栈帧。
-
执行函数主体。
-
准备返回值。
-
恢复需要恢复的寄存器。
-
使用
ret返回。
六、Rust 与汇编的交互
6.1 常用宏与声明
| 名称 | 作用 |
|---|---|
asm! |
在 Rust 函数中嵌入汇编 |
global_asm! |
引入全局汇编 |
include_str! |
将文件内容作为字符串引入 |
extern "C" |
声明使用 C ABI 的接口 |
#[no_mangle] |
禁止符号名被 Rust 改名 |
unsafe |
标记需要调用者承担安全性责任的操作 |
6.2 asm! 操作数形式
| 形式 | 含义 |
|---|---|
in(reg) value |
将输入值放入寄存器 |
out(reg) value |
从寄存器获取输出值 |
inout(reg) value |
同一操作数既输入又输出 |
lateout(reg) value |
较晚写入的输出 |
inlateout(reg) input => output |
输入输出绑定 |
const value |
编译期常量操作数 |
sym symbol |
符号操作数 |
6.3 Rust 与汇编的接口注意事项
-
汇编函数的参数传递要符合 ABI。
-
汇编函数的返回方式要与 Rust 声明一致。
-
汇编中修改的寄存器需要正确告知编译器。
-
内联汇编可能涉及内存、栈、控制流和特权级状态。
-
unsafe本身不会自动保证汇编代码正确。
6.4 系统调用参数传递示例
你提供的资料中,系统调用通过 ecall 进入内核,参数与系统调用号通过寄存器传递。示例中使用 a0—a2 传递参数,a7 传递 syscall ID,返回值通过 a0 传回。
Rust操作系统简明手册.txt
七、特权级与运行环境
7.1 RISC-V 特权级
| 特权级 | 名称 | 典型用途 |
|---|---|---|
| U-mode | User Mode | 用户程序 |
| S-mode | Supervisor Mode | 操作系统内核 |
| M-mode | Machine Mode | 机器级固件与底层管理 |
7.2 相关概念
| 名称 | 含义 |
|---|---|
| Privilege Mode | 处理器特权级 |
| Trap | 异常或中断引发的控制流转移 |
| Exception | 同步异常 |
| Interrupt | 异步中断 |
| SBI | Supervisor Binary Interface |
| SEE | Supervisor Execution Environment |
| RustSBI | SBI 的一种实现 |
7.3 SBI 与系统调用的区别
| 对比项 | 系统调用 | SBI 调用 |
|---|---|---|
| 调用方 | 用户程序 | 操作系统内核 |
| 服务方 | 操作系统内核 | SBI 实现 |
| 常见特权级变化 | U → S | S → M |
| 触发指令 | ecall |
ecall |
同样是 ecall,调用方所处的特权级与服务方不同,触发的异常类型也不同。资料中以 RustSBI 提供关机、输出等底层服务为例。
Rust操作系统简明手册.txt
八、Trap、中断与异常
8.1 相关概念
| 名称 | 含义 |
|---|---|
| Trap | 处理器控制流转移机制 |
| Exception | 指令执行引发的同步异常 |
| Interrupt | 外部或计时等事件引发的异步中断 |
| Trap Handler | Trap 处理函数 |
| Trap Vector | Trap 入口位置 |
| Trap Context | 被打断程序的上下文 |
| Return from Trap | 从 Trap 处理过程返回 |
8.2 常见 CSR 对应关系
| CSR | 与 Trap 的关系 |
|---|---|
stvec |
指定 Trap 入口 |
sepc |
保存返回位置 |
scause |
记录 Trap 原因 |
stval |
提供附加信息 |
sstatus |
保存与恢复相关状态 |
sie |
控制中断使能 |
sip |
反映中断挂起状态 |
sscratch |
可用于入口时暂存上下文信息 |
8.3 中断相关概念
-
中断使能与屏蔽
-
中断挂起状态
-
时钟中断
-
外部中断
-
软件中断
-
中断嵌套
-
中断委托
-
中断处理与返回
九、上下文、任务与线程切换
9.1 上下文相关术语
| 名称 | 含义 |
|---|---|
| CPU Context | CPU 执行状态 |
| TrapContext | Trap 发生时保存的执行状态 |
| TaskContext | 任务切换时保存的上下文 |
| Thread Context | 线程执行上下文 |
| Context Switch | 上下文切换 |
| Kernel Stack | 内核栈 |
| User Stack | 用户栈 |
| Task Control Block | 任务控制块 |
| Thread Control Block | 线程控制块 |
9.2 任务管理相关状态
| 状态 | 含义 |
|---|---|
| New | 已创建,尚未开始执行 |
| Ready | 可运行,等待调度 |
| Running | 正在运行 |
| Blocked | 等待事件或资源 |
| Suspended | 被暂停 |
| Exited / Dead | 已退出 |
具体状态名称和状态转换取决于操作系统实现。
9.3 调度相关术语
-
调度器(Scheduler)
-
时间片(Time Slice)
-
抢占式调度(Preemptive Scheduling)
-
协作式调度(Cooperative Scheduling)
-
时间片轮转(Round Robin)
-
主动让出 CPU(Yield)
-
阻塞与唤醒(Block / Wakeup)
-
任务队列(Run Queue)
9.4 上下文切换涉及的关键动作
-
保存当前执行上下文。
-
更新当前任务状态。
-
选择下一个可运行任务。
-
恢复目标任务上下文。
-
转移控制流,继续执行目标任务。
9.5 需要区分的机制
| 机制 | 主要目的 |
|---|---|
| 函数调用 | 在同一执行流中调用函数 |
| Trap 处理 | 响应异常或中断 |
| 任务切换 | 切换 CPU 执行的任务 |
| 进程切换 | 切换进程执行环境 |
| 地址空间切换 | 切换虚拟地址空间 |
十、内存管理与地址转换
10.1 基础术语
| 名称 | 英文/缩写 |
|---|---|
| 物理地址 | Physical Address(PA) |
| 虚拟地址 | Virtual Address(VA) |
| 地址空间 | Address Space |
| 页表 | Page Table |
| 页表项 | Page Table Entry(PTE) |
| 页帧 | Frame |
| 页大小 | Page Size |
| 内存管理单元 | MMU |
| 转译后备缓冲器 | TLB |
| 地址空间标识符 | ASID |
| 缺页异常 | Page Fault |
10.2 RISC-V SV39 相关术语
-
SV39 分页模式
-
虚拟页号(VPN)
-
物理页号(PPN)
-
页表根节点
-
多级页表
-
页表项权限位
-
地址转换
-
TLB 刷新与同步
10.3 页表权限相关字段
| 字段 | 常见含义 |
|---|---|
| V | 有效 |
| R | 可读 |
| W | 可写 |
| X | 可执行 |
| U | 用户态可访问 |
| G | 全局映射 |
| A | 已访问 |
| D | 已修改 |
10.4 内存管理机制
-
物理内存分配
-
页帧分配与回收
-
虚拟内存映射
-
内核地址空间
-
用户地址空间
-
地址空间隔离
-
缺页异常处理
-
延迟分配(Lazy Allocation)
-
页面置换
-
内核堆与用户堆
-
内存映射与解除映射
10.5 内存访问权限
-
Read:读
-
Write:写
-
Execute:执行
-
User:用户态访问
-
Kernel:内核态访问
-
W^X:避免同一映射同时可写与可执行的策略
十一、系统调用与 SBI
11.1 系统调用相关概念
| 名称 | 含义 |
|---|---|
| System Call | 系统调用 |
| Syscall ID | 系统调用编号 |
| Syscall Arguments | 系统调用参数 |
| Return Value | 返回值 |
| User Library | 用户态封装库 |
| Syscall Handler | 内核系统调用处理函数 |
11.2 资料中出现的系统调用
| 系统调用 | 功能 |
|---|---|
sys_write |
输出缓冲区内容 |
sys_exit |
退出应用程序 |
sys_yield |
主动让出处理器 |
其中,简明手册示例中的 sys_write ID 为 64,sys_exit ID 为 93。
Rust操作系统简明手册.txt
11.3 SBI 相关概念
-
SBI 调用约定
-
SBI Extension
-
SBI Function ID
-
SBI 参数与返回值
-
RustSBI
-
固件服务
-
关机服务
-
控制台输出服务
-
时钟相关服务
十二、内核对象与进程管理
本节补充 zCore 资料中的内核对象模型。zCore 教程以 Zircon 微内核为背景,关注内核对象、任务管理、内存管理和用户程序等机制。
简明zCore教程.txt
12.1 常见内核对象
| 对象 | 主要用途 |
|---|---|
| Process | 进程 |
| Thread | 线程 |
| Job | 组织和管理进程 |
| VMO | 虚拟内存对象 |
| VMAR | 虚拟内存地址区域 |
| Channel | 进程间通信 |
| Port | 等待与事件通知 |
| EventPair | 成对事件对象 |
| Timer | 定时器 |
| Futex | 用户态同步互斥机制 |
12.2 进程与线程相关概念
-
进程创建与退出
-
线程创建与退出
-
线程启动
-
进程与线程的关联
-
任务状态
-
任务控制块
-
句柄(Handle)
-
对象生命周期
-
父子进程关系
-
资源与权限管理
12.3 进程间通信(IPC)
| 机制 | 主要用途 |
|---|---|
| Channel | 消息传递 |
| Port | 等待多个事件/信号 |
| EventPair | 关联对象间的事件通知 |
| Shared Memory | 共享内存 |
| Futex | 用户态同步与等待 |
十三、同步、互斥与等待
13.1 同步原语
| 名称 | 主要用途 |
|---|---|
| Mutex | 互斥锁 |
| Semaphore | 信号量 |
| Condition Variable | 条件变量 |
| Futex | 快速用户态互斥机制 |
| Spinlock | 自旋锁 |
| Atomic Operation | 原子操作 |
13.2 同步相关术语
-
临界区(Critical Section)
-
竞态条件(Race Condition)
-
死锁(Deadlock)
-
饥饿(Starvation)
-
互斥(Mutual Exclusion)
-
同步(Synchronization)
-
阻塞(Blocking)
-
唤醒(Wakeup)
-
等待队列(Wait Queue)
-
原子性(Atomicity)
13.3 条件变量基本操作
| 操作 | 含义 |
|---|---|
wait |
释放锁并等待条件满足;被唤醒后重新获取锁 |
signal |
唤醒一个等待者 |
broadcast |
唤醒多个等待者 |
具体实现需要保证等待与释放锁之间不会产生丢失唤醒等问题。
十四、内核启动、链接与可执行文件
14.1 启动相关术语
| 名称 | 含义 |
|---|---|
| Bootloader | 引导程序 |
| Firmware | 固件 |
| RustSBI | SBI 实现 |
| Kernel Entry | 内核入口 |
_start |
常见启动入口符号 |
| Stack Initialization | 栈初始化 |
| BSS Initialization | BSS 段初始化 |
| Kernel Image | 内核镜像 |
14.2 链接与文件格式
| 名称 | 含义 |
|---|---|
| ELF | 可执行与可链接文件格式 |
| Linker | 链接器 |
| Linker Script | 链接脚本 |
| Symbol | 符号 |
| Relocation | 重定位 |
| Section | 段 |
.text |
代码段 |
.rodata |
只读数据段 |
.data |
已初始化数据段 |
.bss |
未初始化数据段 |
14.3 启动过程相关概念
-
固件初始化
-
内核镜像加载
-
内核入口跳转
-
栈空间建立
-
全局数据初始化
-
中断入口设置
-
内存管理初始化
-
第一个用户程序启动
14.4 QEMU 相关
| 参数 | 用途 |
|---|---|
-machine |
指定模拟硬件 |
-nographic |
使用非图形界面 |
-bios |
指定固件/引导程序 |
-device loader |
加载指定镜像 |
简明手册中的 QEMU 启动示例涉及 qemu-system-riscv64、RustSBI 与内核镜像加载。
Rust操作系统简明手册.txt
十五、开发、构建与调试工具
15.1 Rust 工具链
| 工具 | 用途 |
|---|---|
rustc |
Rust 编译器 |
cargo |
项目构建与依赖管理 |
rustup |
Rust 工具链管理 |
rust-analyzer |
Rust 代码分析 |
rustfmt |
Rust 代码格式化 |
15.2 操作系统开发工具
| 工具 | 用途 |
|---|---|
| QEMU | 模拟器 |
| GDB | 调试器 |
| Make | 自动化构建 |
| GCC / Clang | 编译工具链 |
| GNU Binutils | 汇编、链接与二进制分析 |
| objdump | 反汇编与目标文件分析 |
| readelf | ELF 文件信息查看 |
15.3 常见调试方向
-
查看内核启动入口
-
查看反汇编
-
检查寄存器值
-
检查栈内容
-
检查页表与地址转换
-
跟踪 Trap 入口与返回
-
跟踪任务切换
-
检查 ELF 段与符号
-
使用断点与单步执行
十六、后续补充清单
以下内容先留作资料库中的待整理项,不在本稿中展开:
-
RISC-V 所有常用 CSR 的完整名称、字段与用途
-
RISC-V 汇编指令按 RV64I、M、A、F、D、C 等扩展分类
-
原子指令与内存模型
-
浮点寄存器与浮点上下文
-
RISC-V PMP 与物理内存保护
-
中断控制器与平台设备
-
时钟、定时器与时间管理
-
DMA 与设备访问
-
文件系统与块设备
-
I/O 与设备驱动
-
网络协议栈
-
进程间通信的实现细节
-
异步运行时与
async/await -
Rust 所有权、生命周期与内核数据结构的结合
-
内核堆分配器
-
多核处理器与 SMP
-
锁、原子操作与内存屏障的配合
-
内核安全、权限检查与用户指针校验
整理说明: 本稿将 rCore 的 RISC-V 裸机、系统调用、任务切换、分页与启动机制,以及 zCore 的内核对象、进程线程、VMO/VMAR、IPC 与同步机制放在同一份跨主题资料中。不同教程、不同实现中的名称与结构可能不同,后续应以对应源码和规范为准,不将它们直接视为同一个内核的实现。