来自用户空间的陷阱

问题1:内核如何处理来自用户空间的陷阱?

进入内核空间的路径:先uservec,后usertrap
返回用户空间的路径:先usertrapret,后userret

问题2:函数uservec都做了哪些事?

  • 保存除了pc之外的所有寄存器的值;
  • 切换内核页表;
  • 切换内核栈;
  • 调用usertrap

问题3:函数usertrap都做了哪些事?

  • 判断陷阱的原因;
  • 处理陷阱;
  • 从内核中返回,即调用usertrapret

问题4:函数usertrapret都做了哪些事?

为下一次来自用户空间的陷阱做好准备,包括:

  • 修改stvec指向uservec
  • 准备好trapframe字段;
  • 设置sepc为之前保存的用户pc
  • 调用userret

问题5:函数userret都做了哪些事?

  • 切换用户页表;
  • 恢复用户寄存器的值;
  • sscratch中保存用户trapframe的地址;
  • 使用sret指令返回到用户空间;

问题6:进程的trapframe有哪些性质?

  • 什么时候创建?
    创建进程时,分配一个页用于进程的trapframe,并映射到用户的虚拟地址TRAPFRAME
  • 相关的指针有哪些?
    p->trapframe

问题7:在处理来自用户空间的陷阱时,是如何使用trapframe的?

  • 进入内核空间时,在trapframe上保存属于用户空间的寄存器的值;
  • 返回用户空间时,保存trapframe为下次陷阱做好准备;
    比如,当前进程的内核栈指针、usertrap的地址、内核页表的地址等;

问题8:uservec函数和trampoline页的联系?

  • uservec函数在trampline页上。
  • 基于事实:trampoline页被映射到内核页表和用户页表的虚拟地址是相同的,所以在修改satp后,uservec可继续执行。

问题9:陷阱帧trapframe上有哪些数据?

  • 当前进程内核栈的指针;
  • 当前CPU的hartid;
  • usertrap的地址;
  • 内核页表的地址;

问题10:在处理来自用户空间的陷阱过程中,a0sscratch进行了几次交换?

两次,分别是

  • 在进入内核的过程中,uservec在一开始就使用csrrw指令交换a0sscratch
    交换后,原用户空间的a0值被保存到sscratch中,即sscratch此时的值是陷阱发生时用户空间的a0a0的值是内核先前在sscratch中放入的值。
  • 在返回用户空间的过程中,userret交换a0sscratch
    交换前,sscratch中记录的是陷阱发生时保存的用户空间的a0值,交换后,a0的值就是先前保存的用户空间的值;
    交换前,在usertrapret调用userret时,给a0传递了指向TRAPFRAME的指针,交换后,sscratch中记录的就是指向TRAPFRAME的指针;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章