第五章系统调用
內核提供了用戶進程與內核進行交互的一組接口
5.1與內核通信
系統調用在用戶空間進程和硬件設備之間添加了一個中間層,該層有三個作用:
1) 為用戶空間提供了一種硬件的抽象接口
2) 系統調用保證了系統的穩定和安全
3) 每個進程都運行在虛擬系統中,而在用戶空間和系統的其余部分提供這樣一層公共接口。
在Linux中系統調用是用戶空間訪問內核的唯一手段。除了異常和陷入外,系統調用是內核的唯一合法入口。
5.2API,POSIX,和C庫
應用程序通過在用戶空間實現的應用編程接口(API)而不是直接通過系統調用來編程。
5.3系統調用
使用getpid()系統調用課返回當前的 PID。在內核中被定義為sys_getpid()。
5.3.1系統調用號
作用:指明到底是要執行哪個系統調用,進程不會提及系統調用的名稱。
系統調用號一旦分配就不能再有任何變更。
5.3.2系統調用的性能
Linux系統調用比其他許多操作系統執行更快。 1,進出內核都被優化得簡潔高效。2,系統調用處理程序和每個系統調用本身都很簡潔。
5.4系統調用處理程序
用戶空間的程序無法直接執行內核代碼。
系統轉換到內核態是通過軟中斷實現的:通過引發一個異常來促使操作系統切換到內核態去執行異常處理程序(系統調用處理程序)。
在X86系統上預定義的軟中斷是中斷號128.通過int $0x80指令來觸發該中斷。該處理程序名字叫做system_call()。
5.4.1指定恰當的系統調用
所有的系統調用陷入內核的方式都一樣,所以還需把系統調用號和陷入內核的空間一并傳入內核。
在X86系統調用號是通過eax寄存器傳遞給內核的。
System_call()函數通過將給定的系統調用與NR_syscalls做比較來檢查其有效性。如果它大于NR_syscalls時,該函數返回-ENOSYS.否則執行相應的系統調用
Call sys_call_table(,%eax,8)
5.4.2參數傳遞
發生陷入時應該把外部的參數輸入從用戶空間傳給內核。 把參數放在寄存器里。在X86-32系統上,按照ebx,ecx,edx,esi,edi存放前五個參數。需要六個及以上情況不多見。
給用戶空間的返回值也通過寄存器傳遞。在X86中存放在eax中。
5.5系統調用的實現
5.5.1實現系統調用
步驟一:決定它的用途。新系統調用的參數,返回值,錯誤碼。系統調用的接口應該力求簡潔參數盡可能的少。設計接口時要盡量為將來多做考慮
記住Unix的格言:“提供機制而不是策略”。
5.5.2參數驗證
在接受;一個用戶空間的指針時,內核必須保證:
指針指向的內存區域在進程的地址空間里。進程決不能哄騙內核去讀內核空間的數據。
指針指向的內存區域在進程的地址空間里。進程決不能哄騙內核去讀其他進程的數據。
如果是讀。該內存應被標記為可讀。如果是寫,內存應該被標記為可寫。如果是可執行該內存應該被標記為可執行。進程決不能繞過內存訪問限制。
為了向用空間寫入數據內核提供了copy_to_user()。三參數:進程空間中的目的內存地址。內核空間內的源地址。需要拷貝的數據長度(字節數)。
為了向用空間讀取數據內核提供了copy_from_user()。三參數:進程空間中的目的內存地址。內核空間內的源地址。需要拷貝的數據長度(字節數)。
5.6系統調用上下文。
內核在執行系統調用時候處于進程上下文。在進程上下文中,內核可以休眠并且被搶占。當系統調用返回的時候。控制權仍在system_call()中,它最終會負責切換到用戶空間。
5.6.1綁定一個系統調用的最后步驟
當編寫完一個系統調用后。把它注冊成一個正式的系統調用
1),在系統調用表的最后一個表中加入一個表項。從0開始,系統調用在該表中的的地位就是它的系統調用號。
2),對于所有支持的給種體系結構,系統調用號都必須定義在<asm/unistd.h>
3),系統調用必須被編譯進內核影像。
轉載于:https://www.cnblogs.com/20135237zero/p/5314790.html
總結
- 上一篇: iOS动态部署之RSA加密传输Patch
- 下一篇: JavaCodeTra 猴子选猴王 约瑟