Linux-Kernel
如何在連接的 USB 設備上傳入我的自定義驅動程序模組?
我正在為 LED 徽章編寫一個簡單的小型驅動模組。我遵循了一些教程和參考資料來完成這項工作。所有這些似乎都暗示在插入設備時會自動載入模組。但是,當我執行
usb-devices
相應的設備時,有 driverDriver=usbfs
。我有另一個終端在進行後續操作
dmesg
,它絕不會吐出我的任何調試消息。當我嘗試連接和斷開連接時,會出現以下情況:[36078.726962] usb 1-2: USB disconnect, device number 24 [36080.925619] usb 1-2: new full-speed USB device number 25 using xhci_hcd [36081.067062] usb 1-2: New USB device found, idVendor=0483, idProduct=5750 [36081.067067] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [36081.067071] usb 1-2: Product: CHW20160112 HID [36081.067075] usb 1-2: Manufacturer: Chuanghongweitech1 [36081.068695] input: Chuanghongweitech1 CHW20160112 HID as /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/0003:0483:5750.0018/input/input40 [36081.069072] hid-generic 0003:0483:5750.0018: input,hidraw2: USB HID v1.10 Device [Chuanghongweitech1 CHW20160112 HID] on usb-0000:00:14.0-2/input0
如果我向日誌發出帶有此輸出的
sudo insmod ledbadge_drv.ko
(rmmod
用於解除安裝),我的模組會解除安裝/載入:[36216.554620] ledbadge:, Unloading module. Handler: ledbadge_exit [36216.554620] ledbadge:, Attempting to deregister USB device. [36216.554621] usbcore: deregistering interface driver ledbadge [36216.554647] ledbadge:, Leaving module! [36217.632615] ledbadge:, Loading module. Handler: ledbadge_init [36217.632616] ledbadge:, Attempting to register USB device. [36217.632636] usbcore: registered new interface driver ledbadge
該模組的程式碼如下:
#include <linux/init.h> #include <linux/module.h> #include <linux/usb.h> #define LEDBADGE_VENDOR_ID 0x0483 #define LEDBADGE_PRODUCT_ID 0x5750 #define LEDBADGE_MOD_NAME "ledbadge" #define LEDBADGE_DRV_NAME "ledbadge" /************* usb operations *************/ /* ledbadge_probe called when plugging the USB device */ static int ledbadge_probe(struct usb_interface *interface, const struct usb_device_id *id) { printk(KERN_NOTICE "Led Badge driver (%04X: %04X) plugged \n", id->idVendor, id->idProduct); return 0; } /* ledbadge_disconnect called when unplugging the USB device */ static void ledbadge_disconnect(struct usb_interface *interface) { printk(KERN_NOTICE "%s:, ledbage USB device removed", LEDBADGE_DRV_NAME); } /************* usb driver *************/ // information required to recognize the device static struct usb_device_id ledbadge_table [] = { {USB_DEVICE(LEDBADGE_VENDOR_ID, LEDBADGE_PRODUCT_ID)}, { }, // terminating entry }; MODULE_DEVICE_TABLE(usb, ledbadge_table); static struct usb_driver ledbadge_driver = { .name = LEDBADGE_DRV_NAME, .id_table = ledbadge_table, .probe = ledbadge_probe, .disconnect = ledbadge_disconnect, }; /************** module definition **************/ /* ledbadge_init caled on module loading */ static int __init ledbadge_init(void) { int ret = -1; printk(KERN_NOTICE "%s:, Loading module. Handler: %s", LEDBADGE_MOD_NAME, __FUNCTION__); printk(KERN_NOTICE "%s:, Attempting to register USB device.", LEDBADGE_MOD_NAME); // attempt to register usb device ret = usb_register(&ledbadge_driver); // log dmesg of status if(ret == 0) printk(KERN_NOTICE "%s:, Device registered!", LEDBADGE_MOD_NAME); else printk(KERN_ERR "%s:, Device registration failed > %d", LEDBADGE_MOD_NAME, ret); return ret; } /* ledbadge_exit caled on module unloading */ static void __exit ledbadge_exit(void) { printk(KERN_NOTICE "%s:, Unloading module. Handler: %s", LEDBADGE_MOD_NAME, __FUNCTION__); printk(KERN_NOTICE "%s:, Attempting to deregister USB device.", LEDBADGE_MOD_NAME); // attempt to deregister usb device usb_deregister(&ledbadge_driver); // log dmesg of status printk(KERN_NOTICE "%s:, Leaving module!", LEDBADGE_MOD_NAME); } module_init(ledbadge_init); module_exit(ledbadge_exit); MODULE_LICENSE("GPL");
您是否將模組放在
/lib/modules/<your kernel version>
目錄樹中並在depmod
此之後執行?如果是這樣,那麼在
/lib/modules/<your kernel version>/modules.alias
文件中應該是這樣的一行:alias usb:v0483p5750d*dc*dsc*dp*ic*isc*ip*in* ledbadge
當核心看到一個新的 USB 設備時,它會讀取其供應商和產品 ID 以及許多其他屬性,並將它們用作系統創建的模組別名的組件,如上所示。然後核心
modprobe
使用該別名執行命令(實際機制在 Linux 2.6 及更高版本的歷史中有所不同)。如果modprobe
找到與其匹配的別名定義,則載入該別名定義中列出的模組。我認為匹配以這樣一種方式發生,即最具體的匹配將獲勝。目前看起來
hid-generic
模組可能會勝過您的模組(假設您depmod
在安裝模組後執行),因此您的 ledbadge 設備可能是 USB HID 類設備。因此,您可能還需要/改為聲明 USB HID 設備別名。像這樣的東西:static const struct hid_device_id ledbadge_hid_table[] = { {HID_USB_DEVICE(LEDBADGE_VENDOR_ID,LEDBADGE_PRODUCT_ID)}, { } // terminating entry }; MODULE_DEVICE_TABLE(hid, ledbadge_hid_table);
文件中的結果行
modules.alias
應如下所示:alias hid:b0003g*v00000483p00005750 ledbadge