Lab3: Context Saving
改寫自 entry.S。
Context saving
進入到 exception handler 前,kernel_entry 除了儲存 general purpose register x0-x30 外,處理器的狀態 elr_el1、spsr_el1 也一併儲存,並在 kernel_exit 還原。
scheduler 不會每次都選同一個 process,也就是說從 el1 回到 el0 不見得會是同一個 user process,因此連原本 user space 的 stack pointer 也要存下,schedule 後才會指向正確的 stack frame。從 el1 觸發的中斷,因為是在同個 exception level 觸發的中斷,得將 sp 加上位移取得原本的 stack pointer 後存下。
1 | .macro kernel_entry, el |
從 exception handler 出來時便可還原存在 x21 的 stack pointer
1 | .macro kernel_exit, el |
注意到我們並沒有在 kernel_exit 還原來自 el1 觸發中斷的 stack pointer,因為在最後進行的動作已經幫我們還原了
1 | .macro kernel_exit, el |
處理 el0 synchronous exception (syscall)
user process 透過 svc 觸發 synchronous exception。流程是從 esr_el1 判斷是否為 syscall,也就是呼叫 svc 帶的參數為 #0,接著載入 sys_call_table 位址與 syscall number 相加取得 syscall handler 地址,中間檢驗 syscall number 是否在合法範圍內,檢驗方式是使用 b.hs與 __NR_syscalls 進行比對是否超過上限,以上流程有任何一步錯直接跳錯誤處理。
1 | el0_sync: |