2010-04-27 10 views
26

Ich versuche, ein Linux Kernel Legacy-Modul zu portieren, die von mir portiert werden. folgende Fehler angezeigt:modul_layout Version Inkompatibilität

> sudo insmod camac-mx.ko 
insmod: error inserting 'camac-mx.ko': -1 Invalid module format 
dmesg |tail -n 1 
[1312783.938299] camac_mx: disagrees about version of symbol module_layout 

Wie kann ich dieses Problem beheben?

Antwort

26

Dies zeigt an, dass Sie das Modul gegen eine andere Version des Kernels kompiliert haben als es läuft. Beachten Sie, dass selbst wenn der laufende Kernel und die Kernel-Quelle den gleichen numerischen Wert haben (z. B. beide sind 2.6.31-20-Server), kann dieser Fehler auftreten, wenn die beiden unterschiedliche Konfigurationsoptionen verwenden. Überprüfen Sie außerdem, ob mehrere Versionen dieses Moduls auf dem Computer vorhanden sind, und stellen Sie sicher, dass Sie den richtigen laden.

7

Um das zu lösen (war schwer).

Zuerst benötigen Sie Kernelquellen und Header.

Gehen Sie zu Ihrem Kernel Basis dir, hier /usr/src/linux-source-2.6.35

prüfen uname -r, hier 2.6.35-27-generic

make -C /lib/modules/2.6.35-27-generic/build \ 
SUBDIRS=/usr/src/linux-source-2.6.35/drivers/net/wireless/ath/ath5k modules 

/lib/modules/2.6.35-27-generic/build -> /usr/src/linux-headers-2.6.35-27-generic

überprüfen Sie die Modulabhängigkeiten mit modinfo oder lsmod und sie in einem Skript laden:

modprobe -r ath5k 
modprobe cfg80211 
modprobe led_class 
modprobe mac80211 
modprobe ath 
insmod /usr/src/linux-source-2.6.35/drivers/net/wireless/ath/ath5k/ath5k.ko 

Mit dieser Methode vermagic auch anders sein könnte .... die Make modules_install war nutzlos, aber vielleicht, weil Module in 2 verschiedenen Orten vorhanden ist (/ lib/modules/extra und .../kernel/drivers), nicht ersetzt ...

modinfo -F Vermagic /usr/src/linux-source-2.6.35/drivers/net/wireless/ath /ath5k/ath5k.ko

Ich verstehe nicht wirklich, warum es in ubuntu 10.10 so schwierig ist, ein Modul zu reparieren/debuggen :(

1

Schnelle und funktionierende Lösung gefunden here.

Verwenden Sie einfach modules/build Verzeichnis in Ihrem makefile, NICHT /usr/src/linux-source.

make -C /lib/modules/`uname -r`/build ... 
12

Für die Arbeit auf Systeme ohne Zugriff auf Kernel, Kernel-config oder ksyms, wenn Sie ein working.ko und die eingebaute, nicht arbeit haben, broken.ko.

Chancen werden es wahrscheinlich nicht laden, aber wenn Sie verzweifelt genug sind, es zu versuchen;

# modprobe --dump-modversions working.ko 
0x0b11e775  module_layout 
# modprobe --dump-modversions broken.ko 
0x2719d41e  module_layout 

dann Ihre Lieblings Hex-Editor, ändern Sie es zum Spiel:

00016c70 75 e7 11 0b 6d 6f 64 75 6c 65 5f 6c 61 79 6f 75 |u...module_layou| 

(aufgrund Endian Der Wert ist in umgekehrter Reihenfolge) Es wird höchstwahrscheinlich eine ganze Reihe Sie entsprechen müssen sein.Jemand könnte ein Perl-Skript schreiben, um dies zu tun ....

+0

aber ich kann nicht finden module_layout, nur viel le_layout. – netawater

+0

@netwater, ich denke, was Sie sehen, ist genau so: "0x75646f6dda9e78e9 le_layout". Was Sie ändern müssen, ist die Zahlen nach "75646f6d", die den umgekehrten hexadezimalen Inhalt von "modu" ist. – wangqi060934

0

Ich habe Android-System mit einem binären Modul (pvrsrvkm für Grafiken). Ich habe Kernel aus der Quelle für dieses System gebaut. Im Allgemeinen funktioniert alles gut, aber mit einigen Kernel-.config-Optionen (für kgdb) würde das pvrsrvkm-Modul nicht geladen werden mit "stimmt der Version des Symbols nicht überein" -Fehler.

Das pvrsrvkm-Modul wird von Android früh geladen und wenn es fehlschlägt, ist das System unbrauchbar ohne GUI.

static int check_version(Elf_Shdr *sechdrs, 
unsigned int versindex, 
const char *symname, 
struct module *mod, 
const unsigned long *crc, 
const struct module *crc_owner) 
{ 
unsigned int i, num_versions; 
struct modversion_info *versions; 

/* Exporting module didn't supply crcs? OK, we're already tainted. */ 
if (!crc) 
    return 1; 

/* No versions at all? modprobe --force does this. */ 
versindex = 0; // I added this line 
if (versindex == 0) 
    return try_to_force_load(mod, symname) == 0; 
0

Bevor in Ihrer Quelle: Quelldatei Kernel/module.c auf Kernel;

Da ich schon Kernels wurde, war meine schnelle Lösung Version durch Hinzufügen einer Zeile Prüfung zu deaktivieren (versindex = 0)

Kernel

make clean ARCH = Arm CROSS_COMPILE = arm-linux-gnueabi-

Bearbeiten Sie die Datei in Source-Kernel: Module.symvers change "Module_layout" gearbeitet ein, können Sie diese Datei auf Ihrem Gerät suchen

Recompile Treiber Beispiel: make -C ~/Source-Kernel ARCH = Arm CROSS_COMPILE = arm-linux-gnueabihf- DIR =/Quelle-Kernel M =/modules/example Module

prüfen module_layout in Sie XXX. ko mit: sudo modprobe --dump-modversions XXX.ko

NB

Verwandte Themen