"Keine Symbolversion für module_layout" beim Versuch, usbhid.ko zu laden

27

Ich versuche, mein eigenes Modul für zu erstellen usbhid.ko, aber nachdem ich kompiliert habe, kann ich das Modul nicht laden. dmesgsagt no symbol version for module_layout. Ich frage mich, was ist das Problem? Ich habe bereits die von Ubuntu bereitgestellte Kernel-Quelle verwendet und ich habe auch sichergestellt, dass die Kernel-Version dieselbe ist.

SpecC
quelle

Antworten:

22

Insbesondere ist das Problem, dass beim Erstellen des Moduls im Kernelquellbaum wahrscheinlich die Datei "Modules.symvers" fehlte. Das kbuild-System warnt Sie tatsächlich davor, wenn Sie Ihr Modul erstellen. Wenn Modules.symvers fehlt, wird Folgendes angezeigt:

Warnung: Die Symbolversion dump /usr/src/linux-2.6.34-12/Modules.symvers fehlt. Module haben keine Abhängigkeiten und Modifikationen.

Wenn Ihr Kernel CONFIG_MODVERSIONSaktiviert ist, wird er während der Modpost-Phase Ihres Treibers scripts / mod / modpost mit der Option -m ausführen . Wenn Sie mutig sind und einen Blick auf die Quelle scripts / mod / modpost.c werfen , werden Sie feststellen , dass die Option -m das Symbol _module_layout_ aus vmlinux hinzufügt. Wenn Sie jedoch keine Modules.symvers aus Ihrem Kernel haben, Sie erhalten den CRC-Wert für dieses Symbol nicht und erhalten am Ende diese Fehlermeldung.

Es gibt also zwei Möglichkeiten, dies zu umgehen.

1) Führen Sie einen vollständigen Build Ihres laufenden Kernels aus, um Modules.symvers zu generieren, und erstellen Sie dann Ihr Modul neu. [http://www.mjmwired.net/kernel/Documentation/kbuild/modules.txt[1]

51  === 2. How to Build External Modules
52  
53  To build external modules, you must have a prebuilt kernel available
54  that contains the configuration and header files used in the build.
55  Also, the kernel must have been built with modules enabled. If you are
56  using a distribution kernel, there will be a package for the kernel you
57  are running provided by your distribution.
58  
59  An alternative is to use the "make" target "modules_prepare." This will
60  make sure the kernel contains the information required. The target
61  exists solely as a simple way to prepare a kernel source tree for
62  building external modules.
63  
64  NOTE: "modules_prepare" will not build Module.symvers even if
65  CONFIG_MODVERSIONS is set; therefore, a full kernel build needs to be
66  executed to make module versioning work.

2) Die andere Möglichkeit ist, dummem modprobe mitzuteilen, dass er den ganzen Mist einfach ignorieren und das Modul trotzdem laden soll:

modprobe -f <module>

Ich neige dazu, Option 2 zu bevorzugen :)

Dan Gora
quelle
1
+1 für "sage dummem modprobe, dass er den ganzen Mist einfach ignorieren und dein Modul trotzdem laden soll".
Hayri Uğur Koltuk
Ich habe 2 ausprobiert und festgestellt, dass das Modul beim Booten nicht automatisch geladen wird. Gibt es eine Möglichkeit, -f beim Booten?
Justin Zhang
17

Haben Sie die linux-headersund linux-source-Pakete für Ihren Kernel installiert. Zum Beispiel für den Kernel 3.2.0-27-generic-paebenötigen Sie:

  1. linux-headers-3.2.0-27-generic-pae und
  2. linux-source-3.2.0-27-generic-pae.

Falls die Version für die oben genannten Pakete nicht $(uname -r)mit der Version Ihres laufenden Kernels übereinstimmt, müssen Sie sie durch die Versionszeichenfolge Ihres installierten Kernelpakets von oben ersetzen .
Für das obige Beispiel lautet die Paketversion 3.2.0-27-generic-pae. Wenn Sie ausführen uname -rund die Ausgabe etwas anderes ist 3.2.0-27-generic-pae, müssen Sie jeweils die $(uname -r)folgenden ersetzen , um die Versionszeichenfolge aus den installierten Paketen abzugleichen.

  1. cd /usr/src/linux-source-$Version und entpacke das .tar.bz2-Archiv an Ort und Stelle und cd in das extrahierte Verzeichnis - ich denke, du hast das bereits getan
  2. cp /boot/config-$(uname -r) .config in das Kernel-Quellverzeichnis
  3. cp /usr/src/linux-headers-$(uname -r)/Module.symvers . in das Kernel-Quellverzeichnis

Nachdem Sie dies getan haben, gehen Sie im Kernel-Quellverzeichnis wie folgt vor:

  1. make prepare
  2. make scripts
  3. make M=drivers/usb/serial- Ändern Sie den Pfad danach M=entsprechend Ihren Anforderungen

Leider weiß ich nicht, wie ich ein bestimmtes Modul bauen soll, ohne es zu berühren Module.symvers. Wenn Sie make drivers/usb/serial/option.kozum Beispiel die Module.symversDatei löschen, haben Sie Ihr ursprüngliches Problem. Die Verwendung des M=Parameters bringt es nicht zum Erliegen, aber Sie müssen alle Module im angegebenen Pfad erstellen - und ich habe noch keinen Weg gefunden, dies zu umgehen.

Radu C
quelle
Dies scheint die beste Möglichkeit zu sein, falls Sie das Modul in derselben Baumversion kompilieren ...
Treviño,
2

Sie müssen vor der Ausführung die exakt identische Kernel-Konfiguration verwenden make prepare. Wenn Sie den Kernel außerhalb der Baumstruktur erstellen, müssen Sie ihn anhand der genau identischen Kernel-Header erstellen, die dem aktuell ausgeführten Kernel entsprechen (oder anhand des Ziel-Headers, wenn Sie ihn zum Zeitpunkt der Kompilierung nicht ausführen).

Daniel T Chen
quelle
"make mrproper", "cp / boot / config - $ (uname -r) .config", "make oldconfig", "make prepare", "make scripts" Ich habe diese Anweisungen verwendet, um die Kompilierung vorzubereiten. Ich möchte wissen, ob ich die richtige Konfigurationsdatei kopiert habe. Anscheinend gibt es nur eine Konfiguration, die zu meiner Kernel-Version in / boot / passt. Entschuldigung für die Formatierung, da das Kommentarfeld kein Format hat ....
SpecC
Ja, das scheint richtig zu sein. Wo rufen Sie den Build auf, und wenn nicht aus dem obersten Verzeichnis, welchen SUBDIRS-Wert übergeben Sie?
Daniel T Chen
danke für die Antwort. als ich versuchte, die usbhid.ko zu bauen. Ich habe diesen Befehl "make modules SUBDIRS = drivers / hid / usbhid" verwendet
SpecC
Wenn ich den Befehl "make modules SUBDIRS = drivers / hid / usbhid" ausführe, wird die folgende Warnung angezeigt: WARNUNG: Die Symbolversion dump /usr/src/linux-source-2.6.31/Module.symvers fehlt Keine Abhängigkeiten und Änderungen. "
SpecC
@SpecC Wenn Sie Ihr Problem untersuchen, aktualisieren Sie Ihre ursprüngliche Frage mit den Schritten, die Sie ausführen. Dann wird Dan seine Antwort aktualisieren und Sie werden so lange aktualisieren, bis Sie es herausgefunden haben, anstatt eine Reihe von Kommentaren zu hinterlassen.
Jorge Castro