- usertrapret (trap.c): Sets up the RISC-V control registers to prepare for a future trap from user space. (ecall 的逆操作)
- 关中断
intr_off();
- 更新
stvec
指向用户空间的 trap 处理代码, 设置了 stvec
指向 trampoline, 在那里执行 sret
返回到 user address space
- 填入 trapframe 内容 (恢复现场)
- 存储 kernel page table pointer (
kernel_satp
)
- 存储当前用户进程的 kernel stack (
kernel_sp
, stack pointer)
- 存储 usertrap 函数指针, 使得 trampoline 代码能够跳转到 (
kernel_trap = usertrap
)
- 从
tp
中读取当前的CPU核编号 (kernel_hartid
), 存储在 trapframe 中, 使得 trampoline 代码能够恢复这个数字, 因为用户代码可能会修改它
- userret (trampoline.S): Switches satp to the process’s user page table. kernel 中最后一条指令
- 程序切换回 user mode
$sepc
的数值会被 copy 到 pc
- sret 重新打开中断