2014-04-25 3 views
16

Ich versuche zu lernen, wie Module und Treiber für Linux-Systeme zu schreiben. Ähnlich wie this Frage versuche ich ein einfaches "Hello World" -Modul auf USB-Tastatur Hot-Plug (Code unten) zu laufen. Obwohl das Initialisieren des Moduls mit den Befehlen insmode und modprobe anscheinend funktioniert (dmesg zeigt Debugging-Meldungen), wird das Modul beim Einstecken der Tastatur nicht geladen.Laden Modul auf Tastatur hotplug

Was ich tat:

  1. Run makehellomodule.ko Datei zu erzeugen.
  2. Kopieren Sie die hellomodule.ko-Datei/lib/modules/"my_kernel_version"/
  3. Run depmod -a comand.

Nach diesen drei Schritten habe ich mein Modul zu modules.alias und modules.dep Dateien hinzugefügt. Es funktioniert immer noch nicht.

Ist diese Kernelkonfiguration fehlerhaft oder etwas völlig anderes?

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 
+0

Haben Sie dieses Problem gelöst? – bacchus

+0

@bacchus Nicht wirklich. Ich habe zu einem anderen Computer gewechselt, auf dem das gleiche System installiert ist und ohne irgendetwas am Modul selbst zu ändern - und es hat funktioniert. Ich vermute, dass ich einige Probleme mit meiner Kernel-Konfiguration hatte, obwohl ich das Problem nicht weiter untersucht habe. –

Antwort

12

Ich hatte das gleiche Problem. In meinem Fall wurde das Modul usbhid bereits geladen, da ich eine USB-Maus benutzt habe.

Wenn ich es richtig verstehen, in Ubuntu 14.04, die udev-Regel, die das richtige Modul lädt (n), wenn ein neues Gerät angeschlossen wird, ist die folgende (in /lib/udev/rules.d/80-drivers.rules):

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

Wie Sie können siehe, kmod load wird nur ausgeführt, wenn das neue Gerät keinen Treiber hat. Wenn jedoch usbhid bereits geladen ist, hat die gerade angeschlossene Tastatur bereits einen Treiber. Daher ist das Modul "Hallo Welt" nicht geladen.

Eine mögliche Lösung ist es, die udev-Regel zu ändern/außer Kraft setzen, indem Sie den DRIVER!="?*" Zustand zu entfernen, damit es in Drehung:

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

Eine weitere mögliche Abhilfe ist, das usbhid Modul vor dem Anbringen der Tastatur zu entladen. Dies führt natürlich dazu, dass alle USB-Tastaturen, Mäuse und anderen Geräte der HID-Klasse nicht mehr funktionieren, bis Sie die neue Tastatur anschließen.

-1

Verwenden Sie eine virtuelle Maschine? Wenn ja, versuchen Sie eine echte Installation, sogar auf einem Live-USB. Ich hatte das gleiche Problem mit VirtualBox, gelöst nach dem Versuch auf Live-USB-Installation von Debian.

bearbeitet nach der Antwort des Hubs: Es könnte auch eine Kernel-Konfiguration sein, http://wiki.sourcemage.org/FrequentlyAskedQuestions%282f%29KernelConfiguration.html#kmodload (siehe Frage „Wie habe ich Module Auto-Last über kmod?“).

In menuconfig können Sie unter Loadable Module Support die Option "Kernel module loader" aktivieren. Aber ich habe diese Antwort noch nicht überprüft.