2

I'm looking for a way to replace my keyboard kernel module to a custom one. I have a Logitech MK710 keyboard + mouse set for this purpose, with a USB receiver with those 2 interfaces. Automatically, this USB receiver is managed by default usb, usbhid or logitech-hidpp-device modules, there is some information (note: 1-2 is the receiver device):

ubuntu@ubuntu-VirtualBox:/sys/bus/usb/devices/1-2$ tree | grep driver
│   ├── driver -> ../../../../../../bus/usb/drivers/usbhid
│   ├── driver -> ../../../../../../bus/usb/drivers/usbhid
│   │   │   ├── driver -> ../../../../../../../../bus/hid/drivers/logitech-hidpp-device
│   │   │   ├── driver -> ../../../../../../../../bus/hid/drivers/logitech-hidpp-device
│   │   ├── driver -> ../../../../../../../bus/hid/drivers/logitech-djreceiver
│   ├── driver -> ../../../../../../bus/usb/drivers/usbhid
├── driver -> ../../../../../bus/usb/drivers/usb

What I want to achieve is write a proper module which would be chosen by a kernel instead of those default drivers. I think it's a matter of writing a proper module alias, but I'm not sure because nothing worked yet. Things I already tried are:

  • put my module inside /lib/modules/$(uname -r)/kernel/drivers directory (I created my own custom subdir inside and put the .ko file there)

  • use a proper alias in the module C code, I tried all options listed below (note: USB_VENDOR_ID and USB_PRODUCT_ID are macros used by me and their values are set properly for my specific device):

    static struct hid_device_id mod_table [] = {
        { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID, USB_PRODUCT_ID) },
        { }                      /* Terminating entry */
    };
    MODULE_DEVICE_TABLE(hid, mod_table);
    

or

static struct hid_device_id mod_table [] = {
    { HID_USB_DEVICE(USB_VENDOR_ID, USB_PRODUCT_ID) },
    { }                      /* Terminating entry */
};
MODULE_DEVICE_TABLE(hid, mod_table);

and

static struct usb_device_id mod_table [] = {
    { USB_DEVICE(USB_VENDOR_ID, USB_PRODUCT_ID) },
    { }                      /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, mod_table);
  • remove original (default) HID drivers from /lib/modules/$(uname -r)/kernel/drivers directory (those 3 I specified at the top).

Yet still kernel chooses to load original modules instead of my own. I even made sure that only my driver's alias specifies the vendor and product IDs (checking it in modules.alias file), but nothing works. The module starts to work only when I decide to detach the kernel drivers manually from user space by libusb library (using libusb_detach_kernel_driver function) and reload my own custom module - only then the kernel associates the device with my driver, but that's only till the next boot. I'd like to make it permanent, or even automatic. I hope the whole concept is understandable and is not too big of a mess. Thanks in advance.

1 Answer 1

3

Most likely you are being tripped up by initramfs: a copy of the original HID driver module has been stored in there when your current kernel was installed, and if you haven't regenerated initramfs when adding your module, your customized one won't be in there.

At boot time, the USB support modules are among the first to be loaded, when the system is still running on initramfs and the real root filesystem has not been mounted yet. So the system is still finding & loading the original usbhid + logitech-hidpp-device module combination.

You seem to be using Ubuntu, so the Debian-style sudo update-initramfs -u command should be enough to rebuild the initramfs of the current kernel version using the current set of modules and other configuration files.

1
  • You're right. I checked this initramfs update thing and it works, but only if I earlier remove usbhid module from the /lib/modules/$(uname -r)/kernel/drivers/hid directory. I checked the aliases in /lib/modules/$(uname -r)/modules.alias and it says the following: alias usb:v*p*d*dc*dsc*dp*ic03isc*ip*in* usbhid alias usb:v046DpC52Bd*dc*dsc*dp*ic*isc*ip*in* my_module where my_module is, as you can guess, my module. My question is, why is usbhid chosen instead of my_module? What's wrong with the alias? The vendor and product ID in my alias are proper, of course.
    – pazdinho_
    Jan 25, 2022 at 21:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .