來自用戶空間的陷阱

問題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的指針;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章