Linux內核態、用戶態簡介與IntelCPU特權級別--Ring0-3
一、現代操作系統的權限分離:
現代操作系統一般都至少分為內核態和用戶態。一般應用程序通常運行於用戶態,而當應用程序調用系統調用時候會執行內核代碼,此時會處於內核態。一般的,應用程序是不能隨便進入內核態的而是需要向OS申請,因為內核態擁有更高的權限。所以當程序運行的時候,其實是有兩個棧的,一個位於用戶態,一個位於內核態。他們之間會按照操作系統的規定進行通信。
二、用戶態切換到內核態的三種方式:
1、系統調用,也即是應用程序使用OS提供的接口調用內核功能。例如x86平臺的int 80h和powerrpc的sc等。
2、異常,這是一種被動切換到內核態的方法,當程序在用戶態執行時,遇到了未知異常,例如缺頁異常。
3、外部中斷,也是一種被動切換到內核態的方法,當外設完成用戶請求的操作後會發出中斷信號,CPU會停止當前進程的調度,轉而處理中斷處理函數所定義的操作。例如硬盤讀寫,或者網絡IO,此時也會切換進入內核態。
當應用程序進程創建並開始運行時,都處於用戶態。當需要用到磁盤、網絡讀寫等操作時候調用操作系統提供接口(系統調用)來進入內核態(方法如上)。然後執行完畢後返回用戶態,在這裏,一般的應用程序不能隨意操作內核態數據,具有一定的保護作用。
三、intel的x86架構分級。
事實上,類似的分級分層處理機制一直都有,Intel x86架構使用了4個級別來標明不同的特權級權限。R0實際就是內核態,擁有最高權限。而一般應用程序處於R3狀態--用戶態。在Linux中,還存在R1和R2兩個級別,一般歸屬驅動程序的級別。在Windows平臺沒有R1和R2兩個級別,只用R0內核態和R3用戶態。在權限約束上,使用的是高特權等級狀態可以閱讀低等級狀態的數據,例如進程上下文、代碼、數據等等,但是反之則不可。R0最高可以讀取R0-3所有的內容,R1可以讀R1-3的,R2以此類推,R3只能讀自己的數據。因為shelllog應該寫在內核中。
四、軟中斷:
之前在老東家之一的啟明工作的時候經常接觸軟中斷的這個概念,也接觸軟中斷就是int 80h,當然這是相對於外部設備的硬中斷來說的。今天我終於明白了,所謂的軟中斷就是系統調用的入口指令,int 80h。
當真的有進程執行到0x80時候,操作系統首先會保護現場,以便於恢復。這裏的本質就是對於堆棧信息和寄存器信息的轉存。然後切換特權等級進入內核態,在中斷向量表中查詢0x80,找到對應的中斷處理程序,開始執行中斷處理。處理完畢後需要iret從內核態切回用戶態。在這個過程中iret會從內核態將之前保存的寄存器、堆棧信息等進程上下文從內核態彈出,以便於恢復到中斷之前處理的進程環境,繼續執行原程序調度。
Linux內核態、用戶態簡介與IntelCPU特權級別--Ring0-3