1. 程式人生 > >使用者態切換至核心態

使用者態切換至核心態

1、發生系統呼叫時

  這是處於使用者態的程序主動請求切換到核心態的一種方式。使用者態的程序通過系統呼叫申請使用作業系統提供的系統呼叫服務例程來處理任務。而系統呼叫的機制,其核心仍是使用了作業系統為使用者特別開發的一箇中斷機制來實現的,即軟中斷。

2、產生異常時

  當CPU執行執行在使用者態下的程式時,發生了某些事先不可知的異常,這時會觸發由當前執行的程序切換到處理此異常的核心相關的程式中,也就是轉到了核心態,如缺頁異常。

3、外設產生中斷時

  當外圍裝置完成使用者請求的操作後,會向CPU發出相應的中斷訊號,這時CPU會暫停執行下一條即將要執行的指令轉而去執行與中斷訊號對應的處理程式,如果先前執行的指令是使用者態下的程式,那麼這個轉換的過程自然也就發生了由使用者態到核心態的切換。比如硬碟讀寫操作的完成,系統會切換到硬碟讀寫的中斷處理程式中執行後續操作等。    
   可以看到上述三種由使用者態切換到核心態的情況中,只有系統呼叫是程序主動請求發生切換的,中斷和異常都是被動的。

   由於系統呼叫、中斷和異常由使用者態切換到核心態的機制大同小異,所以這裡僅就係統呼叫的切換過程進行具體說明。

  如果一個使用者程式需要呼叫底層的系統介面,如fork等諸如libc裡面的系統呼叫函式,就牽涉到使用者態與核心態的切換問題,因為系統呼叫處理程式都是執行在核心態下。

  在系統呼叫時由於使用者態和核心態是運行於兩個獨立的棧上面,即分別為核心棧和使用者棧,因此,不能僅簡單的傳遞函式指標,因為對於核心態堆疊在使用者態下是不可見的,所以對於系統呼叫函式的處理程式對於使用者態是不可見的;同時,因為核心棧和使用者棧是相互獨立的,所以在引數傳遞的過程中不能使用普通的壓棧出棧的方式來進行引數傳遞。

Linux使用者態切換核心態

Linux使用了Ring3級別執行使用者態,Ring0作為核心態,沒有使用Ring1和Ring2。Ring3狀態不能訪問Ring0的地址空間,包括程式碼和資料。Linux程序的4GB地址空間,3G-4G部分大家是共享的,是核心態的地址空間,這裡存放在整個核心的程式碼和所有的核心模組,以及核心所維護的資料。使用者執行一個程式,該程式所建立的程序開始是執行在使用者態的,如果要執行檔案操作,網路資料傳送等操作,必須通過write,send等系統呼叫,這些系統呼叫會呼叫核心中的程式碼來完成操作,這時,必須切換到Ring0,然後進入3GB-4GB中的核心地址空間去執行這些程式碼完成操作,完成後,切換回Ring3,回到使用者態。這樣,使用者態的程式就不能隨意操作核心地址空間,具有一定的安全保護作用


保護模式,通過記憶體頁表操作等機制,保證程序間的地址空間不會互相沖突,一個程序的操作不會修改另一個程序的地址空間中的資料。在核心態下,CPU可執行任何指令,在使用者態下CPU只能執行非特權指令。當CPU處於核心態,可以隨意進入使用者態;而當CPU處於使用者態,只能通過中斷的方式進入核心態。一般程式一開始都是運行於使用者態,當程式需要使用系統資源時,就必須通過呼叫軟中斷進入核心態