關於設備驅動和設備管理,四種內核成分。網絡
在Linux 以及全部Unix 系統中,設備被分爲如下三種類型數據結構
塊設備一般縮寫爲blkdev,它是可尋址的,尋址以塊爲單位,塊大小隨設備不一樣而不一樣; 塊設備一般支持重定位( seeking )操做,也就是對數據的隨機訪問。 塊設備是經過稱爲「塊設備節點」的特殊文件來訪問的,井且一般被掛載爲文件系統。
字符設備一般縮寫爲cdev,它是不可尋址的,僅提供數據的流式訪問,就是一個個字符,或者一個個字節。 字符設備是經過稱爲「字符設備節點」的特殊文件來訪問的。 與塊設備不一樣,應用程序經過直接訪問設備節點與字符設備交互。
網絡設備最多見的類型:以太網設備(ethemet devices) 它提供了對網絡的訪問, 經過-個物理適配器和一種特定的協議(如IP 協議)進行的。 網絡設備打破了Unix 的「全部東西都是文件」的設計原則, 它不是經過設備節點來訪問, 而是經過套接字API 這樣的特殊接口來訪問。
有些設備驅動是虛擬的,僅提供訪問內核功能而已.咱們稱爲「僞設備」(pseudo device )
17.2 模塊模塊化
儘管Linux 是「單塊內核」( monolithic )的操做系統 整個系統內核都運行於一個單獨的保護域中, 可是Linux 內核是模塊化組成的, 它容許內核在運行時動態地向其中插入或從中刪除代碼。 這些代碼(包括相關的子例程、數據、函數人口和函數出口〉被一併組合在一個單獨的二進制鏡像中, 即所謂的可裝載內核模塊中,或簡稱爲模塊。 支持模塊的好處是基本內核鏡像能夠儘量地小, 由於可選的功能和驅動程序能夠利用模塊形式再提供。 模塊容許咱們方便地刪除和從新載入內核代碼,也方便了調試工做。 並且當熱插拔新設備時,可經過命令載入新的驅動程序。
17.2.1 Hello, World函數
hel lo_init -初始化函散, 當模塊裝載時被調用,若是成功裝載返回零,不然返回非零值工具
hello_exit -退出函數,當模塊卸載時披調用 spa
module init(hello init); module exit(hello exit);
hello_init的函數是模塊的入口點, 它經過module_ init()例程註冊到系統中,在內核裝載時被調用。 調用module_initO 實際上不是真正的函數調用,而是一個宏調用,它惟一的參數即是模塊的初始化函數。 模塊的全部初始化函數必須符合下面的形式: int my _ init (void) ; 由於init 函數一般不會被外部函數直接調用,因此你沒必要導出該函數,故它可標記爲static 類型.
hello_ exit()函數是模塊的出口函數, 它由module_exit()例程應冊到系統.在模塊從內存卸載時,內核便會調用hello_exit。 退出函數可能會在返回前負責清理資源,以保證硬件處於一致狀態:或者作其餘的一些操做。 exit 函數負責對init 函數以及在模塊生命週期過程當中所作的一切事情進行撤銷工做, 在退出函數返回後, 模塊就被卸載了。 退出函數必須符合如下形式: void my_exit (void); 與init 函數同樣,你也能夠標記其爲static.
若是上述文件被靜態地編譯到內核映像中,那麼退出函數將不被包含,並且永遠都不會被調 MODULE_LICENSE()宏用於指定模塊的版權。 MODULE_AUTHOR()宏和MODULE_DESCRIPTION()宏指定了代碼做者 和模塊的簡要描述,它們徹底是用做信息記錄目的。
17.2.2 構建模塊
1. 放在內核派代碼樹中
當你決定了把你的模塊放入內核源代碼樹中,下一步要清楚你的模塊應在內核源代碼樹中
處於何處。操作系統
設備驅動程序存放在內核源碼樹根目錄下/drivers 的子目錄下,在其內部,設備驅動
文件被進一步按照類別、類型或特殊驅動程序等更有序地組織起來。設計
2. 放在內核代碼外
17.2.3 安裝模塊調試
編譯後的模塊將被裝入到目錄/li~/modules/version/kemel/ 下,對象
在kernel/ 目錄下的每個目錄都對應着內核源碼樹中的模塊位置。
若是使用的是2 .6.34 內核,並且將你的模塊源代碼直接
放在drivers/char/下,那麼編譯後的釣魚竿驅動程序的存放路徑將是:
/lib/modules/2.6.34/kemel/drivers/chai/fisbing.ko.
下面的構建命令用來安裝編譯的模塊到合適的目錄下
make modules install
一般須要以root 權限運行。
17.2.4 產生模塊依賴性
Linux 模塊之間存在依賴性
depmod
系,這時root 用戶可運行命令
depmod -A
模塊依賴關係信息存放在/lib/modules/version/modules.dep 文件中.
17.2.5 戴入模塊
載入模塊最簡單的方法是經過insmod 命令,請求內核載入指定的模塊。 insmod 程序不執行任何依賴性分析或進一步的錯誤檢查。 以root 身份運行命令: insmod module .ko 這裏, module.ko 是要載入的模塊名稱。 執行命令 insmod fishing.ko 卸載一個模塊,你可以使用rmmod 命令,它一樣須要以root 身份運行 rmmod module 先進工具modprobe 提供了模塊依賴性分析、錯誤智能檢查、錯誤報告以及許多其餘功能和選項。 爲了在內核via modprobe 中插入模塊,須要以root 身份運行 modprobe module [ module parameters ] 其中,參數module 指定了須要載入的模塊各稱,後面的參數將在模塊加載時傳入內核。
modprobe 命令不但會加載指定的模塊,並且會自動加載任何它所依賴的有關模塊.因此說 它是加載模塊的最佳機制。 modprobe 命令也可用來從內核中卸載模塊,固然這也須要以root 身份運行: modprobe -r modules 參數modules 指定一個或多個須要卸載的模塊.與rmmod 命令不一樣, modprobe 也會裝載給 定模塊所依賴的相關模塊,但其前提是這些相關模塊沒有被使用.
17.2.6 管理配置選項
17.2. 7 模塊參數
17.2.8 導出符號表
模塊被載入後,就會被動態地鏈接到內核。注意,它與用戶空間中的動態連接庫相似,只有當被顯式導出後的外部函數,才能夠被動態庫調用。在內核中,導出內核函數須要使用特殊的指令: EXPORT_ SYMBOL()和EXPORT_SYMBOL_GPL()。導出的內核函數能夠被模塊調用,而來導出的函數模塊則無陸被調用。