5

Ho appena fatto il mio primo modulo del driver, il modulo mondo Ciao seguente LDD3 Tuttavia purtroppo riscontrato questo errore:errore insmod: inserendo './hello.ko':. -1 formato modulo non valido"

insmod: error inserting './hello.ko': -1 Invalid module format. 

sto facendo questo su Ubuntu 11.04, e il mio ambiente:

$ uname -r 
2.6.38-8-generic 

ho la sorgente del kernel in questo modo:

sudo apt-cache search linux-source 
linux-source - Linux kernel source with Ubuntu patches 
linux-source-2.6.38 - Linux kernel source for version 2.6.38 with Ubuntu patches 
$sudo apt-get install linux-source-2.6.38 

mio/usr/src:

$ls /usr/src/ 
linux-headers-2.6.38-8   linux-source-2.6.38   vboxguest-5.0.10 
linux-headers-2.6.38-8-generic linux-source-2.6.38.tar.bz2 

e poi compilare il kernel

$sudo cp /boot/config-2.6.38-8-generic ./.config 
$sudo make menuconfig -- load the .config file 
$make 
$make modules 

e poi posso compilare il modulo del kernel

$make -C /usr/src/linux-source-2.6.38/linux-source-2.6.38 M=`pwd` modules 

con Makefile:

obj-m := hello.o 

e infine quando inserisco il modulo:

$sudo insmod hello_world.ko 
insmod: error inserting 'hello_world.ko': -1 Invalid module format 

quello che ho trovato in dmesg:

hello: disagrees about version of symbol module_layout 

Allora qual è il problema?

Ho anche notato che la versione linux-header is -2.26.38-generic e codice sorgente è -2.26.38, è questo il problema? ma non ho davvero trovato un pacchetto linux-source-2.26.38-generic sul web.

aggiornamento di stato: ho trovato che il file/lib/moduels/$ (nome -r)/build/Makefile indicare la mia versione del kernel in esecuzione:

VERSION = 2 
PATCHLEVEL = 6 
SUBLEVEL = 38 
EXTRAVERSION = .2 

Così ho scaricare il linux-2.6. 38.2 e compilare, ma ancora lo stesso errore.

Ho anche scoperto che c'è una linea in/boot/config - $ (uname -r):

CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.38-8.42-generic 2.6.38.2" 

Se uno sa che cosa è questo? Non lo vedo nel file di configurazione del kernel che sto costruendo.

+0

L'errore in 'insmod' suggerisce che il modulo è stato inserito in una diversa noleggia il kernel rispetto a quello su cui è stato compilato. Assicurati di avviare lo stesso kernel che stavi compilando ... – dragosht

+0

@dragosht, puoi indicare come trovare il codice sorgente del kernel esatto che il mio sistema sta eseguendo? Il passo sopra è quello che ho trovato su google, ma ancora non funziona. – roMoon

+0

uname -r mostra il kernel che viene avviato e per selezionare il kernel particolare, tenendo premuto il tasto Maiusc al momento dell'avvio. – Rusty

risposta

1

Il kernel da cui si genera il modulo del kernel e al quale si sta inserendo il modulo deve essere della stessa versione. Se non vuoi occuparti di questa cosa puoi usare il seguente Makefile.

obj−m += hello−world.o 

all: 
make −C /lib/modules/$(shell uname −r)/build M=$(PWD) modules 
clean: 
make −C /lib/modules/$(shell uname −r)/build M=$(PWD) clean 

Ora è possibile creare e provare a inserire il modulo.

suggerisco di diventare root, se possibile prima di questa linea

$sudo cp /boot/config-2.6.38-8-generic ./.config

$su 
#cp /boot/config-2.6.38-8-generic ./.config 
#insmod hello_world.ko 

In alternativa è anche possibile utilizzare i seguenti fare file di

TARGET := hello-world 
WARN := -W -Wall -Wstrict-prototypes -Wmissing-prototypes 
INCLUDE := -isystem /lib/modules/`uname -r`/build/include 
CFLAGS := -O2 -DMODULE -D__KERNEL__ ${WARN} ${INCLUDE} 
CC  := gcc-3.0 

${TARGET}.o: ${TARGET}.c 

.PHONY: clean 

clean: 
    rm -rf ${TARGET}.o 
+0

le cose funzionano con "-C/lib/modules/$ (shell uname -r)/build", ma voglio davvero sapere perché il kernel che ho compilato e il kernel che sto utilizzando ha una diversa versione del kernel. Vuoi dare qualche indicazione? – roMoon

+0

controlla modinfo ciao-mondo.ko, ti mostrerà la versione del tuo modulo da cui il kernel è compilato. controlla la versione del tuo kernel. Sia la versione del tuo modulo del kernel sia la tua versione del kernel vera e propria? –

+0

la versione del mio kernel è 2.26.38-8-generic e la versione del kernel su cui sto costruendo il modulo è 2.6.38-8. Ma non riesco davvero a trovare un sorgente di kernel generico 2.26.38-8 nella versione del kernel. – roMoon

-2

avete fatto tutto correttamente, ma non ha avviato il sistema con il kernel che hai compilato così il primo passo è che dovresti fare il boot con esso. Se stai usando Ubuntu puoi tenere premuto il tasto shift al momento dell'avvio e ti verrà dato un elenco di kernel compilato nel tuo sistema da lì selezionare linux-source-2.6.38 e quindi provare a creare il modulo e installare a modo tuo, che non troverai alcun problema. GoodLuck.

+0

Ciao @Rusty, perché devo installare il kernel che ho creato? Se è così, chi vuole installare il mio kernel deve installare il kernel che ho creato? – roMoon

0

Provare a utilizzare la compilazione incrociata. Si prega di guardare il codice qui sotto per il file make. Fai attenzione all'indentazione altrimenti potresti finire con errori come missing separator. Stop

obj-m += hello_.o # questo nome dovrebbe essere il nome del tuo file .c. Sto solo usando ciao ad esempio

suggerisco l'approccio migliore è tramite la compilazione incrociata

Creare una variabile per contenere il nome della directory in cui la directory kernel di Linux risiede Nel mio esempio, modificare il valore "PATH_TO_LINUX_KERNEL_DIRECTORY" ad un valore reale percorso Esempio ~/linux Hai davvero bisogno di fare questo in modo che il file make saprà dove trovare armare-linux-gnueabi- Senza questo, si rischia di incorrere in problemi di braccio-linux-gnueabi-

KDIR := PATH_TO_LINUX_KERNEL_DIRECTORY 

all: 
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -C $(KDIR) M=$(shell pwd) modules 

clean: 
    make -C $(KDIR) M=$(shell pwd) clean