Загрузка модуля на клавиатуре hotplug

Я пытаюсь научиться писать модули и драйверы для Linux-систем. Подобно этому вопросу, я пытаюсь запустить простой модуль Hello World на горячем подключении USB-клавиатуры (код ниже). Несмотря на то, что инициализация модуля с помощью команд insmode и modprobe, похоже, работает (dmesg показывает отладочные сообщения), модуль не загружается при подключении клавиатуры.

Что я сделал:

  • Запустите make, чтобы создать файл hellomodule.ko.
  • Скопируйте файл hellomodule.ko в /lib/modules/ "my_kernel_version" /
  • Запустите depmod -a comand.

После этих трех шагов мой модуль добавлен в файлы modules.alias и modules.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);

Makefile:

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

У меня была та же проблема. В моем случае это было вызвано тем, что модуль 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" не загружается.

Возможное решение состоит в том, чтобы изменить/изменить правило udev, удалив условие DRIVER!="?*", превратив его в:

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

Другим возможным обходным решением является разгрузка модуля usbhid перед подключением клавиатуры. Конечно, это приведет к тому, что все USB-клавиатуры, мыши и другие устройства класса HID перестанут работать до тех пор, пока вы не присоедините новую клавиатуру.

Ответ 2

Используете ли вы виртуальную машину? Если да, попробуйте настоящую установку, даже на live-USB. У меня была такая же проблема с использованием VirtualBox, которая была решена после попытки установки debian на live-USB.

Изменить после ответа хаба: Это также может быть конфигурация ядра, см. http://wiki.sourcemage.org/FrequentlyAskedQuestions%282f%29KernelConfiguration.html#kmodload (Вопрос "Как я могу загружать модули через kmod?" ).

В menuconfig вы можете включить опцию "Kernel module loader" в разделе Поддержка загружаемого модуля. Но я еще не проверял этот ответ.