1. 程式人生 > >系統呼叫 (原理)

系統呼叫 (原理)

// 轉自:https://blog.csdn.net/u012877472/article/details/49907137

“作業系統”通常包含以下兩種含義:

1、表示完整的軟體包,包括用來管理計算機資源的核心層軟體,以及附帶的所有標準軟體工具,諸如命令列直譯器、圖形使用者介面、檔案操作工具和文字編輯器等;

2、狹義上的作業系統是指管理和分配計算機資源(如CPU、RAM和裝置)的核心層軟體。

核心負責管理分配計算機資源,作為計算機和使用者之間的溝通橋樑而存在。因此就有核心態和使用者態的概念。執行硬體指令可以在兩種狀態間轉換。與之對應,可以將虛擬記憶體分為核心空間和使用者空間。在使用者態執行時,CPU只能訪問使用者空間;在核心態執行時,CPU可以訪問核心空間和使用者空間。

系統呼叫是受控的核心入口,藉助這一機制,程序可以請求核心以自己的名義去執行某些動作。以應用程式程式設計介面的形式(API),核心提供了一系列服務。這些服務包括建立新錦程、執行I/O、為程序間通訊建立管道等。

需要注意:

1、系統呼叫將處理器從使用者態切換到核心態,以便CPU訪問受保護的核心空間;

2、系統呼叫的組成是固定的,每個系統呼叫都由一個唯一的數字來標識;

3、每個系統呼叫都提供一套引數,來規範使用者空間與核心空間之間的資訊傳遞;

從程式設計角度來看,系統呼叫很像C語言函式呼叫。下面是一個系統呼叫事件的發生順序:

1、應用程式通過呼叫C語言的外殼函式(wrapper)發起系統呼叫;

2、對系統呼叫中斷處理例程來說,外殼函式必須保證所有的系統呼叫引數可用。引數是通過堆疊傳遞到外殼函式的,但核心希望這些引數置入特定的暫存器。因此,外殼函式將上述引數複製到暫存器;

3、由於所有的系統呼叫進入核心的方式相同,核心需要設法區分每個系統呼叫。因此外殼函式會將系統呼叫編號複製到一個特殊的CPU暫存器中;

4、外殼函式執行一條中斷機器指令(int 0x80),引發處理器從使用者態切換到核心態,並執行系統中斷0x80的中斷向量所指向的程式碼;

5、為響應0x80中斷,核心會呼叫system_call()例程,來處理中斷,具體如下:
(1)在核心棧中儲存暫存器值;

(2)稽核系統呼叫編號的有效性;

(3)以系統呼叫編號對存放所有呼叫服務例程的列表(核心變數sys_call_table)進行索引,發現並呼叫相應的系統呼叫服務例程。若系統呼叫服務例程帶有引數,那麼將首先檢查引數的有效性。隨後該服務例程會執行必要的任務,這可能會涉及對特定引數中指定地址處的值進行修改,以及在使用者記憶體和核心記憶體間傳遞資料。最後該服務例程會將結果狀態返回給system_call()例程;

(4)從核心態回覆暫存器的值,並將系統呼叫返回值置於堆疊中;

(5)返回外殼函式,同時將處理器切換到使用者態;

6、若系統呼叫服務例程的返回值表明調用出錯,外殼函式會使用該值來設定全域性變數errno。然後外殼函式會返回呼叫函式,並返回一個整數型值,以表明系統呼叫是否成功。

下圖以系統呼叫execve()為例,展示了上述事件的發生序列: