linux系统调用理解之摘录(1)
寫在前面:出于對系統調用這一塊知識的疑惑,先從網上摘錄處一些經典的講解。
操作系統負責資源管理,當應用層需要使用系統資源時,就會向內核發起系統調用。如:讀取文件時發起syscall_read系統調用;建立socket時,發起syscall_socket系統調用等等;
(1)能夠觸發內核響應的三種操作:
內核在完成引導后,就一直處于等待各種請求的狀態,以便做出響應從而實現對硬件資源的管理。
1.系統調用:基于軟件中斷機制(簡稱為“軟中斷”)實現,應用層對內核層發起的請求;
2.異常:如缺頁異常,使虛擬地址分配到物理空間;
3.中斷:一般為硬件狀態改變引起內核響應,如usb設備插入等;
本文主要介紹系統調用,它是由軟中斷實現的。
1.首先,用戶程序為系統調用設置參數。其中一個參數是系統調用編號;
2.參數設置完成后,程序執行“系統調用”指令(這是一個特殊的機器指令);在x86平臺上的軟中斷是由int指令產生的。(不明白?);
3.系統調用指令會產生一個異常:產生一個事件,這個事件首先會導致處理器進行狀態切換:用戶態——>系統態(或稱為內核態),然后跳轉到一個新的地址執行異常處理程序,這個程序就是“系統調用處理程序”。
(2)內核空間中的實現
在linux中,每個系統調用都有一個對應的系統調用號。
當用戶程序的進程執行一個系統調用時,這個系統調用號就是用來指明到底要執行哪一個系統調用。
(2.2)所有系統調用陷入內核的方式都是一樣的,所以僅僅是陷入內核空間是不夠的。
因此必須將系統調用號一并傳給內核。
在x86上,系統調用號是通過eax寄存器傳遞給內核的。在陷入內核之前,用戶空間就將系統調用號一并傳給eax中了。這樣系統調用處理程序一旦運行,就可以從eax中得到數據。arm中也是類似操作。
(2.3)
除了系統調用號,一般系統調用還需要傳遞一些輸入參數。系統調用時,也需要把這些參數傳遞給內核。
最簡單的方式:如傳遞系統調用號一樣,將這些參數先存在寄存器中;x86上,ebx,ecx,edx,esi,edi按順序存放前五個外部輸入參數。
如果需要傳遞的參數多于六個時,可以使用一個單獨的寄存器來指向存放所有這些參數在用戶空間地址的指針。
(2.4)
內核記錄了系統調用表中的所有已注冊的系統調用,保存在sys_call_table中。
它與體系結構有關,一般在entry.s中定義。
它是一張由指向實現各種系統調用的內核函數的函數指針組成的表。
用戶空間的實現:
linux下三種關系發生系統調用的方法:
1.通過glibc提供的庫函數
glibc是Linux下使用的開源的標準C庫,它是GNU發布的libc庫。glibc為程序員提供豐富的API,出了例如字符串處理,數學運算等用戶服務外,最重要的是封裝了操作系統提供的系統服務,即系統調用的封裝。
好處:封裝好的系統調用以API形成存在,容易理解,用戶不需要知道更多的內部細節,比如chmod系統調用,我們只需要知道它的作用,不需要知道它的內部實現原理。
同時,使用API形式的系統調用,具有更好的可移植性,glibc方便移植;即使采用的不是glibc的c函數庫,也只需要進行少量的修改;
2.使用syscall直接調用
glibc中沒有進行封裝的系統調用,比如用戶私自增加的一個系統調用,這時候就需要利用glibc提供過的syscall函數直接調用(值得深入研究)
3.通過int指令陷入
實際上,用戶程序通過軟中斷指令 int 0x80 來陷入內核態(在Intel Pentium II中又引入了sysenter指令),參數的傳遞是通過寄存器,eax 傳遞的是系統調用號,ebx、ecx、edx、esi和edi 來依次傳遞最多五個參數;
當系統調用返回時,返回值會存在eax中。
?
?
?
?
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的linux系统调用理解之摘录(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FTP服务器端口说明
- 下一篇: linux系统调用理解之摘录(2)