標籤:應用程式 linux 作業系統 角色 介面
為了和使用者空間上啟動並執行進程進行互動,核心提供了一組介面。透過該介面,應用程式可以訪問硬體裝置和其他動作系統資源。這組介面在應用程式和核心之間扮演了使者的角色,應用程式發送各種請求,而核心負責滿足這些請求。系統調用在使用者空間和硬體裝置之間添加了一個中介層。該層主要作用有三個:
- 系統調用為使用者空間提供了一種硬體的抽象介面;
- 系統調用保證了系統的穩定和安全;
- 系統調用是使用者空間訪問核心的惟一手段。
API、POSIX、C庫
應用程式通過API而不是直接通過系統調用來編程,因為應用程式使用的這種編程介面實際上並不需要和核心提供的系統調用對應。一個API定義了一組應用程式使用的編程介面。它們可以實現成一個系統調用,也可以通過多個系統調用來實現,而完全不使用任何系統調用也不存在問題。實際上,API可以在各種不同的作業系統上實現,給應用程式提供完全相同的介面,而它們本身在這些系統上的實現卻可能迥異。linux中最流行的API是基於POSIX標準的。
linux的系統調用像大多數Unix系統一樣,作為C庫的一部分提供。C庫實現了Unix系統的主要API,包括標準C庫函數和系統調用。
系統調用
系統調用通常通過函數進行調用,函數返回0,代表執行成功,如果調用出現錯誤時,會把錯誤碼寫入errno全域變數,通過調用perror()庫函數,可以把該變數翻譯成使用者可以理解的錯誤字串。
在Linux中,每個系統調用被賦予一個系統調用號。當使用者空間的進程執行一個系統調用的時候,這個系統調用號就用來指明到底是要執行哪一個系統調用。系統調用號相當關鍵,一旦分配就不能再有任何變更,否則編譯好的應用程式就會崩潰。此外,如果一個系統調用被刪除,它所佔用的系統調用號也不允許回收利用,否則,以前編譯過的代碼會調用這個系統調用,但事實上卻調用的是另一個系統調用。
Linux系統調用比其他許多作業系統執行得要快。Linux令人難以置信的上下檔案切換時間是一個重要原因;進出核心都被最佳化得簡潔高效。另外一個原因是系統調用處理常式和每一個系統調用本身也都非常簡潔。
系統調用處理常式
使用者空間的程式無法直接執行核心代碼,它們不能直接調用核心空間中的函數,因為核心駐留在受保護的地址空間上。如果進程可以直接在核心的地址空間上讀寫的話,系統安全就會失去控制。
所以,應用程式應該以某種方式通知系統,告訴核心自己需要執行一個系統調用,希望系統切換到核心態,這樣核心就可以代表應用程式來執行該系統調用了。
通知核心的機制是靠非強制中斷實現的:通過引發一個異常來促使系統切換到核心態去執行例外處理常式。此時的異常處理實際上就是系統調用處理常式。除了系統調用號以外,大部分系統調用都還需要一些外部的參數輸入。所以,在發生異常的時候,應該把這些參數從使用者空間傳給核心。
系統調用的實現
實現一個系統調用的第一步是決定它的用途。每個系統調用都應該有一個明確的用途。在Linux中不提倡用多用途的系統調用。然後,考慮新系統調用的參數、傳回值和錯誤碼是什麼。新的系統調用必須檢查它們所有的參數是否合法有效。
linux核心--系統調用