《Linux內核設計與分析》第十七章讀書筆記

 設備與模塊

關於設備驅動和設備管理,四種內核成分。網絡

  • 設備類型:在全部Unix 系統中爲了統一普通設備的操做所採用的分類.
  • 模塊: Linux 內核中用於按需加載和卸載目標碼的機制.
  • 內核對象:內核數據結構中支持面向對象的簡單操做,還支持維護對象之間的父子關係。
  • sysfs :表示系統中設備樹的一個文件系統。

17 .1 設備類型

在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 模塊之間存在依賴性

  • 若想產生內核依賴關係的信息, root 用戶可運行

        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()。導出的內核函數能夠被模塊調用,而來導出的函數模塊則無陸被調用。

相關文章
相關標籤/搜索