Uservec-保存现场
这是 trampoline.S 中的汇编代码,是 Trap 发生后 CPU 执行的第一段指令。此时页表仍是用户页表。
核心三步曲
-
获取立足点 (The Swap):
- 指令:
csrrw a0, sscratch, a0 - 魔法: 此时
sscratch里存着 Trapframe 的物理地址。交换后,a0变成了 Trapframe 指针,而用户原本的a0暂时存在sscratch里。 - 注: 这是唯一的“无中生有”获取内核指针的方法。
- 指令:
-
全量备份 (Save All):
- 指令:
sd ra, 40(a0),sd sp, 48(a0)… - 利用
a0指向的 Trapframe,将 31 个通用寄存器全部写入内存。
- 指令:
-
世界切换 (The Switch):
- 加载内核环境: 从 Trapframe 中读取预存的
kernel_sp(内核栈) 到sp,读取kernel_trap到t0。 - 加载内核页表: 从 Trapframe 读取
kernel_satp到t1,然后执行csrw satp, t1。 - 刷新:
sfence.vma。 - 跳转:
jr t0(跳转到usertrap)。
- 加载内核环境: 从 Trapframe 中读取预存的
此时状态: CPU 运行在 S-Mode,使用内核页表,使用内核栈。