首页
社区
课程
招聘
[原创] xv6 陷入机制浅析
发表于: 2025-8-30 21:42 553

[原创] xv6 陷入机制浅析

2025-8-30 21:42
553

笔者最近在写 xv6 的 lab,阅读 xv6 book 后仍对 xv6 的陷入机制感到迷惑。在统整 xv6 book 中的内容与询问 GPT 的答案后,便产出此篇文章。

因为笔者仍是新手,错误之处请各位师傅指正,谢谢!

xv6 的进程空间:

硬件线程(hardware thread, hart):处理器核心中的一个执行单元。

per-CPU:每个核的资料。

控制与状态寄存器 (Control and Status Register, CSR):存放一些能改变 CPU 行为的控制,并反映处理器目前的状态

trampoline:其中存放 uservecuserret 的汇编代码,帮助从用户模式切换为内核模式或从内核模式返回到用户模式。内核与每个进程都将 trampoline 映射到同一虚拟地址上,使得页表从一个模式切换到另一个模式后,对 trampoline 虚拟地址的访问不会造成 page fault。参考:trampoline.S

trapframe:存放使用者寄存器,还有与进程相关的内核栈、hartidusertrap地址、内核页表地址等资讯,其地址由 TRAMPOLINE 定义。参考proc.h

以下为陷入机制使用的 CSR 寄存器:

当执行陷阱(除去计时器中断)时,RISC-V 执行以下操作:

当硬件执行完以下操作,交由软件(xv6)处理剩余操作。

xv6 从用户模式陷入内核模式与返回的过程(uservec -> usertrap -> prepare_return -> userret):

以下用对 exec 的调用说明。

用户代码会将参数存在 a0, a1 中,然后将系统调用号存放在 a7syscall 将返回值存放在 a0。系统调用号的定义存放在:syscall.h

参考:syscall.c

  • stvec:内核在此放置陷阱处理程序的地址。
  • sepc:发生陷阱时,旧的 pc 值会保存在此,sret 会将 sepc 复制到 pc 从而从陷阱返回。
  • scause:存放引起陷阱的原因。
  • sscratch:保存 per-CPU 的 struct cpu* 指针。
  • sstatus:其中 SIE 位控制设备中断是否启用,SPP 位保存陷阱是来自用户还是管理模式,并控制 sret 的返回模式。
  1. 若陷阱是设备中断,且 SIE 被清空,则不执行以下操作。
  2. 清除 SIE 禁止中断,防止处理程序被打断。
  3. 将 pc 复制到 sepc
  4. 将当前模式(用户或管理)保存在状态的 SPP 位中。
  5. 设置 scause 反映原因。
  6. 将模式设置为管理模式。
  7. stvec 复制到 pc。
  8. 跳转到 pc 运行。
  1. 当执行用户代码时,stvec 指向 uservec (即 trampoline.S 中协助从用户模式陷入内核的汇编码),所以一旦需要陷入内核就会跳转到 uservec 中。
  2. uservectrampoline 中保存用户寄存器,以免进入内核时修改这些值。uservectrampoline 保存在 sscratch 中。
  3. p->trapframe->kernel_satp 中取得内核页表,将 satp 切换为内核页表并调用 usertrap (p->trapframe->kernel_trap)。usertrap 参考:trap.c
  4. usertrap 会确认陷阱的原因,处理并返回。usertrap 会修改 stvec 指向 kernelvec,因为此时系统处于内核模式,所以所有中断与异常都由都由 kerneltrap 处理。
  5. 当以上处理结束,会调用 prepare_return。由 trap.c 返回到 trampoline.c 中的 userret
  6. userret 会读出保存的用户寄存器,并切换页表回用户模式。

[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

收藏
免费 4
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回