咱們已經看到 insmod 如何對應共用的內核符號來解決未定義的符號. 表中包含了全局內 核項的地址 -- 函數和變量 -- 須要來完成模塊化的驅動. 當加載一個模塊, 如何由模塊 輸出的符號成爲內核符號表的一部分. 一般狀況下, 一個模塊完成它本身的功能不須要輸 出如何符號. 你須要輸出符號, 可是, 在任何別的模塊能得益於使用它們的時候.linux
新的模塊能夠用你的模塊輸出的符號, 你能夠堆疊新的模塊在其餘模塊之上. 模塊堆疊在 主流內核源碼中也實現了: msdos 文件系統依賴 fat 模塊輸出的符號, 某一個輸入 USB 設備模塊堆疊在 usbcore 和輸入模塊之上.編程
模塊堆疊在複雜的工程中有用處. 若是一個新的抽象以驅動程序的形式實現, 它可能提供 一個特定硬件實現的插入點. 例如, video-for-linux 系列驅動分紅一個通用模塊, 輸出 了由特定硬件的低層設備驅動使用的符號. 根據你的設置, 你加載通用的視頻模塊和你的 已安裝硬件對應的特定模塊. 對並口的支持和衆多可鏈接設備以一樣的方式處理, 如同 USB 內核子系統. 在並口子系統的堆疊在圖 並口驅動模塊的堆疊 中顯示; 箭頭顯示了模 塊和內核編程接口間的通信.ide
當使用堆疊的模塊時, 熟悉 modprobe 工具是有幫助的. 如咱們前面講的, modprobe 函數 不少地方與 insmod 相同, 可是它也加載任何你要加載的模塊須要的其餘模塊. 因此, 一 個 modprobe 命令有時可能代替幾回使用 insmod( 儘管你從當前目錄下加載你本身模塊仍 將須要 insmod, 由於 modprobe 只查找標準的已安裝模塊目錄 ).模塊化
使用堆疊來劃分模塊成不一樣層, 這有助於經過簡化每一層來縮短開發時間. 這同咱們在第 1 章討論的區分機制和策略是相似的.函數
linux 內核頭文件提供了方便來管理你的符號的可見性, 所以減小了命名空間的污染( 將 與在內核別處已定義的符號衝突的名子填入命名空間), 並促使了正確的信息隱藏. 若是你 的模塊須要輸出符號給其餘模塊使用, 應當使用下面的宏定義:工具
EXPORT_SYMBOL(name); EXPORT_SYMBOL_GPL(name);視頻
上面宏定義的任一個使得給定的符號在模塊外可用. _GPL 版本的宏定義只能使符號對 GPL 許可的模塊可用. 符號必須在模塊文件的全局部分輸出, 在任何函數以外, 由於宏定義擴 展成一個特殊用途的並被指望是全局存取的變量的聲明. 這個變量存儲於模塊的一個特殊 的可執行部分( 一個 "ELF 段" ), 內核用這個部分在加載時找到模塊輸出的變量. ( 感興 趣的讀者能夠看 <linux/module.h> 獲知詳情, 儘管並不須要這些細節使東西動起來. )接口