在键盘hotplug上加载模块

时间:2014-04-25 06:47:14

标签: linux module

我正在尝试学习如何为Linux系统编写模块和驱动程序。与this问题类似,我试图运行一个简单的" Hello World" USB键盘热插拔模块(下面的代码)。即使通过命令insmodemodprobe初始化模块似乎工作(dmesg显示调试消息),插入键盘时也不会加载模块。

我做了什么:

  1. 运行make以生成hellomodule.ko文件。
  2. hellomodule.ko文件复制到/ lib / modules /" my_kernel_version" /
  3. 运行depmod -a cmand。
  4. 完成这三个步骤后,我将模块添加到modules.aliasmodules.dep个文件中。它仍然无效。

    这个内核配置有问题还是完全不同?

    系统: Ubuntu 14.04 LTS ;内核: 3.14.0

    hellomodule.c:

    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/usb.h>
    #include <linux/usb/input.h>
    #include <linux/hid.h>
    
    MODULE_AUTHOR("author");
    MODULE_DESCRIPTION("helloworld module\n");
    MODULE_LICENSE("GPL");
    
    static struct usb_device_id hello_id_table [] = {
            { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID,
            USB_INTERFACE_SUBCLASS_BOOT,
                USB_INTERFACE_PROTOCOL_KEYBOARD) },
        { } /* Terminating entry */
    };
    
    MODULE_DEVICE_TABLE (usb, hello_id_table);
    
    static int hello_probe(struct usb_interface *interface,
        const struct usb_device_id *id)
    {
        pr_debug("HelloModule: USB keyboard probe function called\n");
        return 0;
    }
    
    static void hello_disconnect(struct usb_interface *interface)
    {
        pr_debug("HelloModule: USB keyboard disconnect function called\n");
    }
    
    static struct usb_driver hello_driver = {
    //.owner =  THIS_MODULE,
    .name =     "hello_driver",
    .probe =    hello_probe,
    .disconnect =   hello_disconnect,
    .id_table = hello_id_table
    };
    
    static int __init hello_init(void)
    {
       int retval = 0;
    
       pr_debug("HelloModule: Hello World!\n");
       retval = usb_register(&hello_driver);
       if (retval)
           pr_debug("HelloModule: usb_register failed. Error number %d", retval);
    
       return 0;
    }
    
    static void __exit hello_exit(void)
    {
        usb_deregister(&hello_driver);
        pr_debug("HelloModule: exit\n");
    }
    
    module_init(hello_init);
    module_exit(hello_exit);
    

    生成文件:

    obj-m := hellomodule.o
    CFLAGS_hellomodule.o := -DDEBUG
    
    KDIR  :=  /lib/modules/`uname -r`/build
    
    default:
        make -C $(KDIR) M=$(PWD) modules
    clean:
        make -C $(KDIR) M=$(PWD) clean
    

1 个答案:

答案 0 :(得分:12)

我遇到了同样的问题。在我的情况下,它是由usbhid模块已经加载引起的,因为我使用的是USB鼠标。

如果我理解正确,在Ubuntu 14.04中,在连接新设备时加载适当模块的udev规则如下(位于/lib/udev/rules.d/80-drivers.rules):

DRIVER!="?*", ENV{MODALIAS}=="?*", RUN{builtin}="kmod load $env{MODALIAS}"

如您所见,kmod load仅在新设备​​没有驱动程序时执行。但是,如果已加载usbhid,则刚刚连接的键盘已有驱动程序。因此,未加载“hello world”模块。

一种可能的解决方案是通过删除DRIVER!="?*"条件来修改/覆盖udev规则,从而将其转换为:

ENV{MODALIAS}=="?*", RUN{builtin}="kmod load $env{MODALIAS}"`.

另一种可行的解决方法是在连接键盘之前卸载usbhid模块。当然,这将导致所有USB键盘,鼠标和其他HID类设备停止工作,直到您连接新键盘。