王雪 原創作品轉載請注明出處 《linux內核分析》MOOC課程 http://mooc.study.163.com/course/USTC-1000029000
一、重點知識 (1)用戶棧與內核棧 內核棧:存在于內核空間,當進程在內核棧里運行時,CPU棧頂指針寄存器里面的內容是內核棧空間地址,使用內核棧。 用戶棧:存在于用戶空間,當進程在用戶棧里運行時,CPU棧頂指針寄存器里面的內容是用戶??臻g地址,使用用戶棧。 (2)用戶態與內核態 用戶態:用戶在非特權模式下,訪問會資源會受到限制。 內核棧:用戶在特權模式下,可隨意訪問資源 為什么要區分用戶態與內核態? 因為在操作系統中有很多很重要的代碼要保證安全性,不可被任意修改,區別用戶態和內核態可訪問的空間,保證了系統的安全,防止因不當操作而造成的系統崩潰。 在Linux中有0和3兩種運行級別:0表示內核態,3表示用戶態 (3)利用地址空間區別內核態和用戶態 只有內核態可以訪問0xc0000000以上的地址空間,0x00000000到0xbfffffff在兩種狀態下都可以訪問 (4)內核態與用戶態的切換 當進程因為硬件中斷或者系統調用,而從用戶態轉變為內核態時,進程所使用的堆棧要從用戶棧變為內核棧,此時進程進入內核態后,首先,在內核態上保存用戶態堆棧上的地址,設置堆棧指針寄存器的內容為當前進程的內核棧地址,這樣就完成了用戶棧向內核棧的切換。 當進程從內核態恢復到用戶態時,將內核態保存的用戶態的堆棧地址恢復到棧指針寄存器,這樣就完成了內核態向用戶態的切換。 (5)系統調用 1.系統調用與API(應用程序編程接口)區別 API只是一個函數定義,而系統調用通過軟中斷向內核發出一個明確的請求。 不是每個API都對應一個特定的系統調用。首先,API可能直接提供用戶態的服務(比如一些數學函數),其次,一個單獨的API可能調用幾個系統調用,不同的API可能調用了同一個系統調用。 2.系統調用的優點 系統調用為用戶提供了調用與硬件設備等進行交互的接口,可以將用戶從底層的硬件編程中解放出來,提高系統的安全性,是用戶程序具有更好的可移植性。 3.系統調用時執行的操作 1)在進程的內核態堆棧中保存大多數寄存器的內容(即保存恢復進程到用戶態執行所需要的上下文) 2)根據用戶態傳遞的系統調用號,確定系統調用的服務例程 3)調用名為系統調用服務例程的相應的C函數來處理系統調用 4)從系統調用返回 4.系統調用的過程描述
簡單描述系統調用的執行過程:在用戶態下執行某個API函數,在API函數中有一個int 0x80的中斷向量,觸發后,由用戶態進入內核態,保存現場,查找system_ call表找到相應的系統調用號,找到后執行相應的系統調用服務例程,執行過后返回,恢復現場,回到用戶態。
可以發現:用戶模式下的API函數xyz()中在執行時觸發了中斷向量int 0x80,隨后進入了內核態,保存現場,執行相應的服務例程。 中斷向量0x80與system_call連接起來,system _call包含了很多系統調用,通過系統號找到特定的服務例程。系統調用號將xyz與sys _xyz關聯起來。 5.系統調用的參數傳遞(從用戶態向內核態傳遞參數)規則: (1)每個參數的殘毒不能超過寄存器的長度 (2)在系統調用號(eax)外,參數的個數不能超過6個(ebx,ecx,edx,esi,edi,ebp),如果超過6個,將某一個寄存器作為一個指針指向一塊內存,到達內核棧后,通過這塊內存來傳遞參數 二、實驗內容 1.簡單的系統調用time,獲得系統時間
實驗執行結果:gcc …… -m32,64位的系統按32位編譯程序
2.利用內嵌匯編代碼深層了解系統調用過程
實驗執行結果
在這段內嵌匯編代碼中,模仿了time系統調用的功能,在編寫代碼時我們用ebx來傳遞系統調用的第一個參數,用eax來傳遞系統調用號,通過int $0x80產生系統中斷,執行系統調用號為13的系統調用,將返回的結果保存下來,這就完成了一次系統調用的模擬。 三、實驗總結 今天的實驗簡單的了解了系統調用的基本知識,包括內核態與用戶態、內核棧與用戶棧以及在系統調用過程中,如何從內核態過渡到用戶態等。 形象化的記憶將系統調用可以看成三層皮:API函數,system_ call,sys _xxx()系統調用服務例程。 要清楚系統調用的執行過程。
新聞熱點
疑難解答