linux内核杂记(13)-系统调用(1)
1、系統調用 在用戶空間進程和硬件 設備之間增加了一具中間層。其作用如下:
(1)為用戶空間提供了一種硬件 的抽象接口。
(2)保證了系統的穩定 和安全
(3)每個進程 運行在虛擬系統中,而在用戶空間和系統的其余部分提供這樣一層公共接口。
2、系統調用是用戶空間訪問內核的唯一手段,不能直接調用內核函數
3、一般情況下用戶程序通過在用戶空間實現的應用編程接口(API)而不是直接通過系統調用 來編程 。最流行的應用編程接口基于POSIX標準 。
4、訪問系統調用通常通過C庫中定義的函數調用 來進行。系統調用 在出現錯誤 時,C庫會所錯誤 碼寫入errno全局變量,可通過perror()庫函數將該 變量翻譯成用戶可理解的錯誤字符串。
5、系統調用 在內核中的實現舉例:
SYSCALL_DEFINE是一個宏,展開如下:
asmlinkage long sys_getpid(void)asmlinkage是一個編譯指令,通知編譯器僅從棧中提取該函數的參數。所有系統調用 都需要這個限定詞
此外,注意:get_pid在內核定義為sys_getpid(),這是LINUX系統調用在內核定義時應遵守的命名規則。
6、每個系統調用 被 賦予一個系統調用號,關聯唯一的系統調用。
7、sys_ni_syscall()為LINUX定義的一個未實現的系統調用,即無效系統調用 ,只返回-ENOSYS
8、內核在sys_call_table中記錄了系統調用表所有已經注冊過的系統調用的列表,在x86-64中,定義于arch/i386/kernel/syscall_64.c,為每個有效的系統調用指定了唯一的系統調用號。
9、內核空間的系統調用函數定義在受保護的地址空間中。調用內核的唯一方式是通知內核,靠軟中斷襪,在X86系統上預定義的軟中斷號128,通過int $0x80觸發該中斷 ,該指令會觸發一個異常,并導致系統切換到內核態,執行128號異常處理程序(程序名字為system_call()),最近,X86處理器增加了一條sysenter指令,比軟中斷更快更專業。
10、系統調用的相關參數
(1)通過eax寄存器將系統調用號傳遞給內核。在陷入內核之前,用戶空間將相應系統調用對應的號放入eax中。
(2)system_call函數要檢查系統調用號的有效性,不然就是一個無效系統調用。通過傳入的系統調用號與NR_syscalls比較來檢查有效性。大于或等于 NR_syscalls,該函數返回 -ENOSYS,表示調用失敗,否則可繼續執行對應的系統調用:
sys_call_table在64位系統下,以64位(8字節)存放,32位4字節,上例中,最后一個參數為8,表示為64位系統。
(3)通過其它寄存器傳遞參數。在x86-32系統上,ebx、ecx、edx 、esi、edi按順序 存放前5個參數,**如果需要6個或更多,則使用一個單獨的寄存器存放放指向所有這些參數在用戶空間中的地址指針。
注意:系統調用號相關錯誤,返回-ENOSYS
11 、系統調用實現
(1)實現新的系統調用 首先決定其用途,其次考慮接口設計,為將來多做考慮。然后,注意只是提供機制,不能提供策略,最后當寫一個系統調用時,時刻注意可移植性和健壯性。
(2)系統調用實現時,必須驗證傳入參數的合法性,更重要是要驗證用戶提供的參數指針的有效性:
A.指針指向的內存區域屬于用戶空間
B.指針指向的內存區域在進程的地址空間
C.如果讀,該內存應被標記為可讀,如果寫,該內存應標記 可寫如果可執行,應標記為可執行。
(3)用戶空間的數據是不能直接使用,需要在內核空間和用戶空間進行來回COPY
A.向用戶空間寫:
copy_to_user()
B.從用戶空間讀
copy_from_user()
C.最后一個參數是需要COPY的數據長度(字節數)
D.發生錯誤返回 -EFAULT
12、系統允許檢查針對 特定資源的特殊權限,調用者可使用capable()函數來檢查是否有權對指定資源進行操作,返回非0表示有權,返回0表示無權。
總結
以上是生活随笔為你收集整理的linux内核杂记(13)-系统调用(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 操作系统设计与实现第3版笔记与minix
- 下一篇: linux内核杂记(14)-Linux