MODULE_DEVICE_TABLE巨集的作用(轉)
阿新 • • 發佈:2018-11-09
1. MODULE_DEVICE_TABLE (usb, skel_table);
該巨集生成一個名為__mod_pci_device_table的區域性變數,該變數指向第二個引數。核心構建時,depmod程式會在所有模組中搜索符號__mod_pci_device_table,把資料(裝置列表)從模組中抽出,新增到對映檔案/lib/modules/KERNEL_VERSION/modules.pcimap中,當depmod結束之後,所有的PCI裝置連同他們的模組名字都被該檔案列出。當核心告知熱插拔系統一個新的PCI裝置被發現時,熱插拔系統使用modules.pcimap檔案來找尋恰當的驅動程式。
MODULE_DEVICE_TABLE的第一個引數是裝置的型別,如果是USB裝置,那自然是usb(如果是PCI裝置,那將是pci,這兩個子系統用同一個巨集來註冊所支援的裝置)。後面一個引數是裝置表,這個裝置表的最後一個元素是空的,用於標識結束。例:假如程式碼定義了USB_SKEL_VENDOR_ID是 0xfff0,USB_SKEL_PRODUCT_ID是0xfff0,也就是說,當有一個裝置接到集線器時,usb子系統就會檢查這個裝置的 vendor ID和product ID,如果他們的值是0xfff0時,那麼子系統就會呼叫這個模組作為裝置的驅動。
1、MODULE_DEVICE_TABLE
該巨集定義在檔案中,原型為:
點選(此處)摺疊或開啟
- #define MODULE_GENERIC_TABLE(gtype,name) \
- extern const struct gtype##_id __mod_##gtype##_table \
- __attribute__ ((unused, alias(__stringify(name))))
-
- #define MODULE_DEVICE_TABLE(type,name) \
- MODULE_GENERIC_TABLE(type##_device,name)
生成一個名為__mod_mdio_device_id_table,核心構建時,depmod程式會在所有模組中搜索符號__mod_mdio_device_id_table,把資料(裝置列表)從模組中抽出,新增到對映檔案 /lib/modules/KERNEL_VERSION/modules.pcimap 中,當depmod結束之後,所有的MDIO裝置連同他們的模組名字都被該檔案列出。在需要驅動的時候,由modules.pcimap檔案來找尋恰當的驅動程式。
MODULE_DEVICE_TABLE的第一個引數是裝置的型別,如果是PHY裝置,那自然是MDIO(如果是PCI裝置,那將是pci,這兩個子系統用同一個巨集來註冊所支援的裝置)。後面一個引數是裝置表,這個裝置表的最後一個元素是空的,用於標識結束。ex:
點選(此處)摺疊或開啟
- static struct mdio_device_id __maybe_unused realtek_tbl[] = {
- { 0x001cc912, 0x001fffff },
- { }
- };
2、其他相關巨集的定義
這些巨集定義在下
1) MODULE_AUTHOR(name) 定義驅動的程式設計者,name為string
2) MODULE_LIC ENSE(license) 定義驅動的license,一般為GPL,或相關公司的license
3) MODULE_DESCRIPT ION(desc) 對驅動程式的描述,string
4) MODULE_SUPPORTED_DEVICE(name) 驅動程式所支援的裝置,string
5) MODULE_PARM(var,type),提供在執行時通過控制檯將引數傳遞給模組(在insmod時)。如果我們想用這個巨集來傳遞命令列引數,那麼在我們的模組中定義一個全域性變數。在insmod模組時,便可以用引數的形式,將具體的實參傳遞給模組中的那個全域性變數。MODULE_PARM(name,type)有兩個引數,一個是這個全域性變數的名稱,另一個是這個全域性變數的型別。而他的型別有以下幾種:
b:位元型
h:短整型
i:整型
l:長整型
s:字串型
在傳遞字串型的引數時,這個全域性變數需要在模組中用Char *來宣告!insmod會自動為其分配記憶體空間。
例如:
點選(此處)摺疊或開啟
- int a = 3;
- char *st;
- MODULE_PARM(a,”i”);
- MODULE_PARM(st,”s”);
在insmod是我們加這樣的引數:
點選(此處)摺疊或開啟
- insmode a.o “a = 3″, “st = hello world”
這裡最重要的是,MODULE_PARM()也支援我們最常用的陣列型別。用短線‘-’把兩個數字分開,分別表示陣列引數中的最小位數和最大位數。例如:
點選(此處)摺疊或開啟
- int array[8];
- MODULE_PARM(array,”1-8i”);
在命令列我們使用加這樣的引數:
點選(此處)摺疊或開啟
- insmod a.o “array = 38745,123,4000″
在那些模組程式設計時,我們往往給這些全域性變數以預設值,如果我們才insmod時沒有傳入引數時,模組會使用這些預設值,而如果我們傳入引數時,這些預設值便被覆蓋掉。
6) MODULE_PARM_DESC(var,desc) 對變數的描述
7) GP L_HEADER()
8) THI S_M ODULE 指向全域性變數 __this_module (struct module)的指標。
9)系統對每個模組維護一個usage counter,以便決定何時可以安全的解除安裝模組。
下面的巨集用來對該usage counter操作,usage counter可以通過/proc/modules檔案檢視
MOD_INC_USE_COUNT
MOD_DEC_USE_COUNT
MOD_IN_USE
MODULE_DEVICE_TABLE
10) EXPORT_SYMTAB 預處理巨集,當在程式中用EXPORT_SYMBOL等巨集時需要定義該巨集。例如,可以在Makefile中定義:-DEXPORT_SYMTAB
__EXPORT_SYMBOL(sym,str)
EXPORT_SYMBOL(var)
11) EXPORT_SYMBOL_NOVERS(var) 匯出一個符合到核心符號表,匯出後,該符合可以供其他模組使用。這個巨集有助於編寫驅動程式時清楚的劃分出層次。可以通過/proc/ksyms檔案或ksyms命令檢視核心符號表。EXPORT_SYMBOL_NOVERS(var),匯出是不帶版本資訊。在使用該巨集時,需定義 EXPORT_SYMBOL_GPL(var)
12) EXPORT_NO_SYMBOLS 顯示指出,該模組不向核心符合表匯出符號
13)SET_MODULE_OWNER