为什么我的内核模块中的探测函数没有被调用?
Why is the probe function in my kernel module not being called?
在遵循本教程 (1) 和阅读 Linux 设备驱动程序 一书中的某些章节时,我无法获得 pr_debug()
probe 函数中的语句以显示 dmesg 中的任何输出。
这是我的代码:
#include <linux/module.h> /*included for all kernel modules*/
#include <linux/kernel.h> /*included for KERN_DEBUG*/
#include <linux/init.h> /*included for __init and __exit macros*/
#include <linux/usb.h>
#include <linux/usb/input.h>
#include <linux/hid.h>
#define VENDOR_ID 0x0930
#define DEVICE_ID 0x6545
MODULE_LICENSE("GPL");
MODULE_AUTHOR("dev");
MODULE_DESCRIPTION("eusb driver");
static struct usb_device_id eusb_table[] = {
{ USB_DEVICE(VENDOR_ID, DEVICE_ID) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, eusb_table);
static int eusb_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
pr_debug("USB probe function called\n");
return 0;
}
static void eusb_disconnect(struct usb_interface *interface)
{
pr_debug("USB disconnect function called\n");
}
static struct usb_driver eusb_driver = {
//.owner = THIS_MODULE,
.name = "eusb",
.probe = eusb_probe,
.disconnect = eusb_disconnect,
.id_table = eusb_table
};
static int __init eusb_init(void)
{
int result = 0;
pr_debug("Hello world!\n");
result = usb_register(&eusb_driver);
if(result){
pr_debug("error %d while registering usb\n", result);}
else{pr_debug("no error while registering usb\n");}
return 0;
}
static void __exit eusb_exit(void)
{
usb_deregister(&eusb_driver);
pr_debug("Exiting module\n");
}
module_init(eusb_init);
module_exit(eusb_exit);
和Makefile:
obj-m := eusb.o
CFLAGS_eusb.o := -DDEBUG
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
Make 没有错误地完成,在 insmod
之后我可以看到 lsmod
中列出的模块和初始化和退出函数中的 pr_debug()
在 dmesg 中显示输出。
当插入设备时,探测函数似乎没有被调用(或者 pr_debug()
语句在 dmesg 中没有显示任何输出)。
Dmesg 输出:
[ 7777.521236] Hello world!
[ 7777.521264] usbcore: registered new interface driver eusb
[ 7777.521266] no error while registering usb
[ 7780.597087] usb 1-6: USB disconnect, device number 9
[ 7797.686970] usb 1-6: new high-speed USB device number 10 using xhci_hcd
[ 7797.857324] usb 1-6: New USB device found, idVendor=0930, idProduct=6545
[ 7797.857328] usb 1-6: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 7797.857330] usb 1-6: Product: DataTraveler 2.0
[ 7797.857331] usb 1-6: Manufacturer: Kingston
[ 7797.857333] usb 1-6: SerialNumber: 08606E6D407FED10571E5067
[ 7797.858787] usb-storage 1-6:1.0: USB Mass Storage device detected
[ 7797.858902] scsi host11: usb-storage 1-6:1.0
[ 7798.931417] scsi 11:0:0:0: Direct-Access Kingston DataTraveler 2.0 PMAP PQ: 0 ANSI: 4
[ 7798.931824] sd 11:0:0:0: Attached scsi generic sg3 type 0
[ 7800.184749] sd 11:0:0:0: [sdc] 60964864 512-byte logical blocks: (31.2 GB/29.0 GiB)
[ 7800.186338] sd 11:0:0:0: [sdc] Write Protect is off
[ 7800.186343] sd 11:0:0:0: [sdc] Mode Sense: 23 00 00 00
[ 7800.187948] sd 11:0:0:0: [sdc] No Caching mode page found
[ 7800.187952] sd 11:0:0:0: [sdc] Assuming drive cache: write through
[ 7800.220477] sdc: sdc1 sdc2 sdc3
[ 7800.225068] sd 11:0:0:0: [sdc] Attached SCSI removable disk
[ 7802.798403] ISO 9660 Extensions: Microsoft Joliet Level 3
[ 7802.799507] ISO 9660 Extensions: RRIP_1991A
我尝试过使用另一台设备,尝试使用 printk()
而不是 pr_debug()
。我在 SO 上发现了几个问题相同的问题,但据我所知,我的代码 almost/completely 与答案中的代码相同。
我也尝试过:
USB_INTERFACE_INFO(
USB_INTERFACE_CLASS_HID,
USB_INTERFACE_SUBCLASS_BOOT,
USB_INTERFACE_PROTOCOL_KEYBOARD)
而不是 USB_DEVICE()
(另一个设备是键盘)。
我注意到一些答案谈论 platform_driver 而不是 usb_driver,但我认为这与我无关,因为教程中从未提及它。
我哪里错了?
你的目的只是教育吗?否则驱动程序已经存在并且它被称为 usb-storage
。似乎那个驱动程序也会先枚举你的设备。尝试禁用 usb-storage
并再次加载您的驱动程序。或者更好地使用虚拟机 (KVM / Qemu) 来尝试你的驱动程序。
如您所见,您的 Hello world!
已打印出来,这意味着模块已成功加载。通常所有声称通过 usb_device_id*
table 处理设备的模块都会被加载。参见 9.3.2.3. Module Loading。
现在,仅针对设备绑定 的驱动程序调用探测函数。在没有设置优先级且两个驱动程序能够绑定的情况下,任何一个都可能获得第一个机会。
我已经写了一个 blog post 可能会进一步澄清事情(如果没有,请在这里发表评论)。
此外,您可能想查看这两个相关的邮件列表线程
在遵循本教程 (1) 和阅读 Linux 设备驱动程序 一书中的某些章节时,我无法获得 pr_debug()
probe 函数中的语句以显示 dmesg 中的任何输出。
这是我的代码:
#include <linux/module.h> /*included for all kernel modules*/
#include <linux/kernel.h> /*included for KERN_DEBUG*/
#include <linux/init.h> /*included for __init and __exit macros*/
#include <linux/usb.h>
#include <linux/usb/input.h>
#include <linux/hid.h>
#define VENDOR_ID 0x0930
#define DEVICE_ID 0x6545
MODULE_LICENSE("GPL");
MODULE_AUTHOR("dev");
MODULE_DESCRIPTION("eusb driver");
static struct usb_device_id eusb_table[] = {
{ USB_DEVICE(VENDOR_ID, DEVICE_ID) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, eusb_table);
static int eusb_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
pr_debug("USB probe function called\n");
return 0;
}
static void eusb_disconnect(struct usb_interface *interface)
{
pr_debug("USB disconnect function called\n");
}
static struct usb_driver eusb_driver = {
//.owner = THIS_MODULE,
.name = "eusb",
.probe = eusb_probe,
.disconnect = eusb_disconnect,
.id_table = eusb_table
};
static int __init eusb_init(void)
{
int result = 0;
pr_debug("Hello world!\n");
result = usb_register(&eusb_driver);
if(result){
pr_debug("error %d while registering usb\n", result);}
else{pr_debug("no error while registering usb\n");}
return 0;
}
static void __exit eusb_exit(void)
{
usb_deregister(&eusb_driver);
pr_debug("Exiting module\n");
}
module_init(eusb_init);
module_exit(eusb_exit);
和Makefile:
obj-m := eusb.o
CFLAGS_eusb.o := -DDEBUG
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
Make 没有错误地完成,在 insmod
之后我可以看到 lsmod
中列出的模块和初始化和退出函数中的 pr_debug()
在 dmesg 中显示输出。
当插入设备时,探测函数似乎没有被调用(或者 pr_debug()
语句在 dmesg 中没有显示任何输出)。
Dmesg 输出:
[ 7777.521236] Hello world!
[ 7777.521264] usbcore: registered new interface driver eusb
[ 7777.521266] no error while registering usb
[ 7780.597087] usb 1-6: USB disconnect, device number 9
[ 7797.686970] usb 1-6: new high-speed USB device number 10 using xhci_hcd
[ 7797.857324] usb 1-6: New USB device found, idVendor=0930, idProduct=6545
[ 7797.857328] usb 1-6: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 7797.857330] usb 1-6: Product: DataTraveler 2.0
[ 7797.857331] usb 1-6: Manufacturer: Kingston
[ 7797.857333] usb 1-6: SerialNumber: 08606E6D407FED10571E5067
[ 7797.858787] usb-storage 1-6:1.0: USB Mass Storage device detected
[ 7797.858902] scsi host11: usb-storage 1-6:1.0
[ 7798.931417] scsi 11:0:0:0: Direct-Access Kingston DataTraveler 2.0 PMAP PQ: 0 ANSI: 4
[ 7798.931824] sd 11:0:0:0: Attached scsi generic sg3 type 0
[ 7800.184749] sd 11:0:0:0: [sdc] 60964864 512-byte logical blocks: (31.2 GB/29.0 GiB)
[ 7800.186338] sd 11:0:0:0: [sdc] Write Protect is off
[ 7800.186343] sd 11:0:0:0: [sdc] Mode Sense: 23 00 00 00
[ 7800.187948] sd 11:0:0:0: [sdc] No Caching mode page found
[ 7800.187952] sd 11:0:0:0: [sdc] Assuming drive cache: write through
[ 7800.220477] sdc: sdc1 sdc2 sdc3
[ 7800.225068] sd 11:0:0:0: [sdc] Attached SCSI removable disk
[ 7802.798403] ISO 9660 Extensions: Microsoft Joliet Level 3
[ 7802.799507] ISO 9660 Extensions: RRIP_1991A
我尝试过使用另一台设备,尝试使用 printk()
而不是 pr_debug()
。我在 SO 上发现了几个问题相同的问题,但据我所知,我的代码 almost/completely 与答案中的代码相同。
我也尝试过:
USB_INTERFACE_INFO(
USB_INTERFACE_CLASS_HID,
USB_INTERFACE_SUBCLASS_BOOT,
USB_INTERFACE_PROTOCOL_KEYBOARD)
而不是 USB_DEVICE()
(另一个设备是键盘)。
我注意到一些答案谈论 platform_driver 而不是 usb_driver,但我认为这与我无关,因为教程中从未提及它。
我哪里错了?
你的目的只是教育吗?否则驱动程序已经存在并且它被称为 usb-storage
。似乎那个驱动程序也会先枚举你的设备。尝试禁用 usb-storage
并再次加载您的驱动程序。或者更好地使用虚拟机 (KVM / Qemu) 来尝试你的驱动程序。
如您所见,您的 Hello world!
已打印出来,这意味着模块已成功加载。通常所有声称通过 usb_device_id*
table 处理设备的模块都会被加载。参见 9.3.2.3. Module Loading。
现在,仅针对设备绑定 的驱动程序调用探测函数。在没有设置优先级且两个驱动程序能够绑定的情况下,任何一个都可能获得第一个机会。
我已经写了一个 blog post 可能会进一步澄清事情(如果没有,请在这里发表评论)。
此外,您可能想查看这两个相关的邮件列表线程