Kerneltrap-内核中断
场景: 当 CPU 已经在内核态运行(例如正在执行 sys_open)时,发生了时钟中断或磁盘中断。
区别于 User Trap
- 不需要切页表: 已经在内核页表了。
- 不需要切栈: 已经在内核栈了。
- 入口:
kernelvec(在kernelvec.S),而不是uservec。
处理流程
- 保存现场: 直接把寄存器
addi sp, sp, -256然后sd压入当前内核栈。- 注意: 这里不用 Trapframe,直接用栈。
- 调用 C 函数:
kerneltrap()。- 判断是否是时钟中断 →
yield()。 - 限制: 如果当前持有自旋锁 (Spinlock),则不能 yield (防止死锁)。
- 判断是否是时钟中断 →
- 恢复现场: 从栈上
ld恢复寄存器。 - 返回:
sret(注意:这里是从 S-Mode 返回 S-Mode)。