子 issue #6:进程上下文切换
子 issue #6:进程上下文切换
描述
实现 LoongArch64 的进程/线程上下文保存与恢复,使内核能 fork 进程并在父子进程间切换。
依赖
- #4 (closed)(异常处理框架完成,与本 issue 共享 TrapFrame 类型设计)
- #5(页表与地址空间切换完成)
与 #4 (closed) 的耦合关系
#4 (closed) 和 #6 应联合推进,因为:
- trap entry 汇编需要知道 TrapFrame 内存布局
- TrapFrame 的字段设计同时影响异常处理和上下文切换
- 建议先共同定义 TrapFrame/UserContext 结构体,再分头实现 trap 汇编(#4 (closed))和 switch 汇编(#6)
需要实现的文件
| 文件 | 说明 |
|---|---|
crate/trapframe/ (vendor) |
LoongArch TrapFrame、UserContext、GeneralRegs 完整定义和保存/恢复汇编
|
kernel/src/arch/loongarch64/interrupt/trap.S |
trap entry/exit 上下文保存恢复(与 #4 (closed) 共享此文件) |
kernel/src/arch/loongarch64/context.rs(可选) |
SwitchContext 定义 + switch_to 内联汇编 |
kernel/src/arch/loongarch64/fp.rs |
FP 寄存器保存/恢复实现 |
kernel/src/arch/loongarch64/signal.rs |
MachineContext::from_tf / fill_tf 完整实现、set_signal_handler
|
关键技术点
LoongArch 寄存器约定
| 寄存器 | ABI 名称 | 用途 | 保存约定 |
|---|---|---|---|
| r0 | zero | 硬件零 | - |
| r1 | ra | 返回地址 | caller-saved |
| r2 | tp | 线程指针 | - |
| r3 | sp | 栈指针 | callee-saved |
| r4-r11 | a0-a7 | 参数/返回值 | caller-saved |
| r12-r20 | t0-t8 | 临时 | caller-saved |
| r21 | reserved | 保留 | - |
| r22 | fp/s9 | 帧指针 | callee-saved |
| r23-r31 | s0-s8 | 保存 | callee-saved |
建议 TrapFrame 布局
#[repr(C)]
pub struct TrapFrame {
pub regs: [usize; 32], // r0-r31, regs[0]=zero 始终为 0
pub era: usize, // CSR.ERA — 异常返回地址
pub prmd: usize, // CSR.PRMD — 异常前 CRMD 状态
pub badv: usize, // CSR.BADV — 缺页故障地址(可选)
pub estat: usize, // CSR.ESTAT — 异常状态(可选)
}
内核线程切换(SwitchContext)
只需保存 callee-saved 寄存器:
#[repr(C)]
pub struct SwitchContext {
pub ra: usize, // r1
pub sp: usize, // r3
pub s0: usize, // r23
pub s1: usize, // r24
pub s2: usize, // r25
pub s3: usize, // r26
pub s4: usize, // r27
pub s5: usize, // r28
pub s6: usize, // r29
pub s7: usize, // r30
pub s8: usize, // r31
pub fp: usize, // r22 (s9/fp)
}
浮点状态
- 32 个浮点寄存器 f0-f31(64位双精度)
- 8 个条件标志寄存器 FCC0-FCC7
-
FCSR0:浮点控制状态寄存器 -
保存策略建议:初期全量保存,后续可优化为 lazy save(利用
CSR.EUEN.FPE控制浮点使能)
用户态返回
- 通过
ERTN指令返回(从CSR.ERA取 PC,从CSR.PRMD恢复特权级) - 进入用户态前设置:
CSR.PRMD.PPLV = 3(用户态),CSR.PRMD.PIE = 1(开中断)
完成标准
- 内核线程 switch 正确(
switch_to汇编能在两个内核栈间切换) - 能
fork进程并在父子进程间切换不崩溃 - 能从内核态正确返回用户态(
ERTN) - FP 状态在进程切换时不丢失
- signal handler 能正确设置用户态上下文
父任务:#1