I am trying to learn how to write modules and drivers for Linux systems. Similarly to this question I am trying to run a simple "Hello World" module on USB keyboard hot-plug (code below). Even though initializing the module by commands insmode
and modprobe
seem to work (dmesg
shows debugging messages), the module is not loaded upon plugging in the keyboard.
What I did:
make
to produce hellomodule.ko
file.hellomodule.ko
file to /lib/modules/"my_kernel_version"/depmod -a
comand.After those three steps I have my module added to modules.alias
and modules.dep
files. It still does not work.
Is this kernels configuration fault or something entirely different?
System: Ubuntu 14.04 LTS; Kernel: 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
I had the same problem. In my case it was caused by the usbhid
module being already loaded, since I was using a USB mouse.
If I understand it correctly, in Ubuntu 14.04, the udev rule that loads the proper module(s) when a new device is attached is the following (located in /lib/udev/rules.d/80-drivers.rules
):
DRIVER!="?*", ENV{MODALIAS}=="?*", RUN{builtin}="kmod load $env{MODALIAS}"
As you can see, kmod load
is executed only if the new device has no driver. However, if usbhid
is already loaded, the just-attached keyboard already has a driver. Therefore the "hello world" module is not loaded.
A possible solution is to modify/override the udev rule by removing the DRIVER!="?*"
condition, thus turning it into:
ENV{MODALIAS}=="?*", RUN{builtin}="kmod load $env{MODALIAS}"`.
Another possible workaround is to unload the usbhid
module before attaching the keyboard. Of course, that will cause all USB keyboards, mice and other HID class devices to stop working until you attach the new keyboard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With