笔记思维导图

隔离性系统调用的进入和退出.svg

trap流程图

流程图 (1).jpg

注意

  • ecall不会更换页表,所以这意味着,陷阱处理代码必须存在于每一个用户页表中。而蹦床页面(trampoline page),是由内核小心的映射到每一个用户页表中,以使得当我们仍然在使用用户页表时,内核在一个地方能够执行trap机制的最开始的一些指令。这个地址是由stvec指明的,每次从内核空间转为用户空间前,都会设置好stvec
  • 即使蹦床页面是在用户地址空间的页表完成的映射,但用户代码不能写它,因为这些页面对应的PTE并没有设置PTE_U标志位。这也是为什么trap机制是安全的。
  • SSCRATCH如何保存TRAPFRAME,即陷阱帧的地址?

操作系统开始时先运行在管理模式,即内核中,而后才会转到用户模式
在从内核返回到用户空间的最后一个C函数usertrapretkernel/trap.c)中最后一行代码((void (*)(uint64, uint64))fn)(TRAPFRAME, satp)调用fn函数,第一个参数将传入a0中保存,因此a0保存了TRAPFRAME,而在trampoline.Suserret函数执行了csrrw a0, sscratch, a0指令交换了sscratcha0的值,因此SSCRATCH保存TRAPFRAME了。