《Linux內核設計與實現》讀書筆記 第五章 系統調用html
第五章系統調用編程
系統調用是用戶進程與內核進行交互的接口。爲了保護系統穩定可靠,避免應用程序恣意忘形。安全
5.1與內核通訊函數
系統調用在用戶空間進程和硬件設備間添加了一箇中間層,post
做用:爲用戶空間提供了一種硬件的抽象接口;保證了系統的穩定和安全,避免應用程序不正確使用硬件,竊取其餘進程的資源,或作出危害系統的行爲;爲了實現多任務和虛擬內存。性能
Linux提供的系統調用比大部分操做系統少得多。url
5.2 API、POSIX、和C庫spa
一個API定義了一組應用程序使用的編程接口。(API和系統調用不是一一對應)API能夠在各類不一樣的操做系統上實現,給應用程序提供徹底相同的接口,而API自己的實如今不一樣系統中可能迥異。操作系統
Unix的API基於POSIX,Linux盡力與POSIX和SUSv3兼容設計
Linux的系統調用做爲C庫的一部分提供。
5.3系統調用
訪問系統調用一般經過C庫中定義的函數調用,一般須要定義參數,並且可能產生反作用(使系統狀態發生改變)。系統調用還會返回了一long類型的值表示成功或錯誤。
定義系統調用:asmlinkage long sys_***
限定詞 返回類型 命名規則
系統調用號:每一個系統調用被賦予一個系統調用號,用戶空間執行系統調用時,用系統調用號指明系統調用。一旦分配再也不變動,系統調用被刪除,其系統調用號也不容許回收利用。內核記錄了系統調用表中全部已註冊的系統調用列表,存儲在sys_call_table中
系統調用的性能:Linux系統調用比其餘操做系統要快,緣由:上下文切換時間短;系統調用程序和系統調用都很簡潔。
5.4系統調用處理程序
內核駐留在受保護的地址空間上,所以應用程序要通知內核本身須要使用系統調用。通知內核是靠軟中斷實現,引起異常時系統切換到內核態。經過int $0x80觸發中斷,執行128號異常處理程序(系統調用處理程序)
指定恰當的系統調用:X86上系統調用號經過eax寄存器傳遞給內核
參數傳遞:除了系統調用號還須要傳遞外部參數,按順序存儲在ebx,ecx,edx,esi和edi五個寄存器中,不多有須要六個參數的。
5.5系統調用的實現
實現系統調用:一、決定用途(不提倡採用多用途);二、調用的參數、返回值和錯誤碼應該是什麼(藉口力求簡潔,參數儘量少,力求穩定);三、設計接口儘可能爲未來作考慮(是否有沒必要要的限制,是否可移植);
提供機制(mechaniam)不提供策略(policy)
參數驗證:必須仔細檢查參數是否合法有效,由於系統調用在內核空間執行,若是有不合法輸入,那會威脅系統安全和穩定。最重要的檢查是 檢查用戶提供的指針是否有效。在接收一個用戶空間的指針以前,內核必須保證一、指針指向的內存區域屬於用戶空間。進程毫不能哄騙內核去讀內核空間的數據;二、指針指向的內存區域在進程的地址空間裏。進程毫不能哄騙內核去讀其餘進程的數據;三、進程毫不能繞過內存訪問限制。
內核提供copy_to_user(),copy_from_user()兩個方法完成檢查拷貝數據
5.6系統調用上下文
內核在執行系統調用的時候處於進程上下文,在進程上下文中,內核能夠休眠,而且能夠被搶佔。休眠說明系統調用可使用內核提供的絕大部分功能。能夠搶佔說明新進程可使用相同的系統調用。
綁定一個 系統調用的最後步驟:一、在系統調用表的最後加入一個表項;二、系統調用號必須定義於<asm/unistd.h>;三、系統調用必須被編譯進內核映像。
從用戶空間訪問系統調用:只寫出系統調用gilc恐怕並不提供支持。Linux自己提供一組宏_syscalln(),n的範圍從0到6,表明須要傳遞給系統調用的參數個數。
新建一個系統調用的好處:一、系統調用容易建立且使用方便;二、系統調用很高效。
新建一個系統調用的壞處:一、須要系統調用號,這須要一個內核在處於開發版本的時;候官方分配給你;二、系統調用的接口不容許改動;三、須要將系統調用分別註冊到每一個須要支持的體系結構中;四、在腳本中不容易調用系統調用,也不能從文件系統直接訪問系統調用;五、對於簡單信息交換,系統調用大材小用;