在CPU的所有指令中,有一些指令是非常危險的,如果錯用,將導致整個系統崩潰。比如:清內存、設置時鍾等。如果所有的程序都能使用這些指令,那么你的系統一天死機n回就不足為奇了。所以,CPU將指令分為特權指令和非特權指令,對於那些危險的指令,只允許操作系統及其相關模塊使用,普通的應用程序只能使用那些不會造成災難的指令。Intel的CPU將特權級別分為4個級別:RING0,RING1,RING2,RING3。
linux的內核是一個有機的整體。每一個用戶進程運行時都好像有一份內核的拷貝,每當用戶進程使用系統調用時,都自動地將運行模式從用戶級轉為內核級,此時進程在內核的地址空間中運行。
當一個任務(進程)執行系統調用而陷入內核代碼中執行時,我們就稱進程處於內核運行態(或簡稱為內核態)。此時處理器處於特權級最高的(0級)內核代碼中執行。當進程處於內核態時,執行的內核代碼會使用當前進程的內核棧。每個進程都有自己的內核棧。當進程在執行用戶自己的代碼時,則稱其處於用戶運行態(用戶態)。即此時處理器在特權級最低的(3級)用戶代碼中運行。當正在執行用戶程序而突然被中斷程序中斷時,此時用戶程序也可以象征性地稱為處於進程的內核態。因為中斷處理程序將使用當前進程的內核棧。這與處於內核態的進程的狀態有些類似。
內核態與用戶態是操作系統的兩種運行級別,跟intel cpu沒有必然的聯系, 如上所提到的intel cpu提供Ring0-Ring3四種級別的運行模式,Ring0級別最高,Ring3最低。Linux使用了Ring3級別運行用戶態,Ring0作為 內核態,沒有使用Ring1和Ring2。Ring3狀態不能訪問Ring0的地址空間,包括代碼和數據。Linux進程的4GB地址空間,3G-4G部 分大家是共享的,是內核態的地址空間,這里存放在整個內核的代碼和所有的內核模塊,以及內核所維護的數據。用戶運行一個程序,該程序所創建的進程開始是運 行在用戶態的,如果要執行文件操作,網絡數據發送等操作,必須通過write,send等系統調用,這些系統調用會調用內核中的代碼來完成操作,這時,必 須切換到Ring0,然后進入3GB-4GB中的內核地址空間去執行這些代碼完成操作,完成后,切換回Ring3,回到用戶態。這樣,用戶態的程序就不能 隨意操作內核地址空間,具有一定的安全保護作用。
處理器總處於以下狀態中的一種:
1、內核態,運行於進程上下文,內核代表進程運行於內核空間;
2、內核態,運行於中斷上下文,內核代表硬件運行於內核空間;
3、用戶態,運行於用戶空間。
從用戶空間到內核空間有兩種觸發手段:
1.用戶空間的應用程序,通過系統調用,進入內核空間。這個時候用戶空間的進程要傳遞很多變量、參數的值給內核,內核態運行的時候也要保存用戶進程的一些寄存器值、變量等。所謂的“進程上下文”,可以看作是用戶進程傳遞給內核的這些參數以及內核要保存的那一整套的變量和寄存器值和當時的環境等。
2.硬件通過觸發信號,導致內核調用中斷處理程序,進入內核空間。這個過程中,硬件的一些變量和參數也要傳遞給內核,內核通過這些參數進行中斷處理。所謂的“中斷上下文”,其實也可以看作就是硬件傳遞過來的這些參數和內核需要保存的一些其他環境(主要是當前被打斷執行的進程環境)。
一個程序我們可以從兩種角度去分析。其一就是它的靜態結構,其二就是動態過程。下圖表示了用戶態和內核態直接的關系(靜態的角度來觀察程序)