13

I have just made my first driver module, the hello world module following LDD3. However unfortunately encountered this error:

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

I am doing this on Ubuntu 11.04, and my environment:

$ uname -r
2.6.38-8-generic

I get the kernel source like this:

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

my /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

and then I compile the kernel

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

and then I compile my kernel module

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

with Makefile:

obj-m := hello.o

and then finally when I insert the module:

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

what I found in dmesg:

hello: disagrees about version of symbol module_layout

So what's the problem?

I have also noticed that the linux-header is -2.26.38-generic and source code version is -2.26.38, is this the problem? but I have really not found a linux-source-2.26.38-generic package on web.

status update: I have found that the file /lib/moduels/$(name -r)/build/Makefile indicate my running kernel version:

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

So I download the linux-2.6.38.2 and compile, but still the same error.

I have also found that there is a line in /boot/config-$(uname -r):

CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.38-8.42-generic 2.6.38.2"

Does any one know what is this mean? I don't see it in the config file of the kernel i am building.

roMoon
  • 339
  • 1
  • 5
  • 12
  • 1
    The error in `insmod` suggests that the module was inserted in a different kernel than the one it was compiled against. Make sure you boot the exact same kernel you have been compiling ... – dragosht Dec 20 '15 at 09:04
  • @dragosht, can you indicate how to find the exact kernel source code that my system is running? The step above is what I have found on google, but still not work. – roMoon Dec 20 '15 at 09:16
  • uname -r shows the kernel which is booted up and to select particular kernel keep pressing shift key at time of bootup. – Rusty Dec 20 '15 at 09:19
  • 3
    @roMoon try compiling your module with `make -C /usr/src/linux-headers-$(uname -r ) M=`pwd` modules` – Rusty Dec 20 '15 at 09:23
  • Thanks @Rusty, make with -C /usr/src/linux-headers-$(uname -r ) really works. Another question, ldd3 said that I nee a kernel source tree to build module, the headers directory "/usr/src/linux-headers-$(uname -r )" has the same effect ? Or I still have to build my kernel source tree ? – roMoon Dec 20 '15 at 10:57
  • @Rusty, 'uname -r' on my system is 2.6.38-8-generic, but can not found a kernel source with version of 2.6.38-8-generic. what I have download is linux-source-2.6.38.8 and linux-source-2.6.38.2, both not work. – roMoon Dec 20 '15 at 11:41
  • When you used `usr/src/linux-headers-$(uname -r )` that is equal to linux-headers-2.6.38-8-generic so you were compiling against linux-headers-2.6.38-8-generic(current kernel). So what we did is compiled your driver code with the current kernel your system is using that's why you were able to install it without the `Invalid module format.` And previously your were compiling your code with /usr/src/linux-source-2.6.38/linux-source-2.6.38,which is there in your /usr/src folder so it was able to compile but was not able to install as your current kernel gives error. – Rusty Dec 21 '15 at 04:58

4 Answers4

12

Kernel from which you build your kernel module and to which you are inserting module should be of same version. If you do not want to take care of this thing you can use following 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

Now you can build and try to insert module.

I suggest you to become root if possible before this line

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

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

Alternatively you can also use following make file

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
Punit Vara
  • 3,744
  • 1
  • 16
  • 30
  • things work with "−C /lib/modules/$(shell uname −r)/build", but I really want to know why the kernel I have compiled and the kernel I am running has different kernel version. Would you give some indication? – roMoon Dec 21 '15 at 14:33
  • 2
    check modinfo hello-world.ko , it will show you version of your module from which kernel it build. check your kernel version .Is both version your kernel module and your actual kernel version same? – Punit Vara Dec 21 '15 at 15:10
  • my kernel version is 2.26.38-8-generic and the kernel version on which I am building module is 2.6.38-8. But I really can not find a 2.26.38-8-generic kernel source in the kernel release. – roMoon Dec 22 '15 at 15:09
  • Have you checked with commands I have suggested you ? I know you have knowledge about your kernel but when you check with command you can find both version will differ so whenever you use $(shell uname -r) it will automatically take care of that matter – Punit Vara Dec 22 '15 at 15:15
  • uname -r command automatically build the module from the same kernel header that you are using. You will nowhere find this generic version – Punit Vara Dec 22 '15 at 15:15
  • Is it possible that cross compiling the kernel then making the kernel modules on the target machine could result in this kind of behaviour? In my case i'm using exactly the same kernel config. – Owl Sep 05 '18 at 09:52
  • @owl Check kernel version wherever you build and compile your module and target machine should have same version. However, it is possible to keep kernel config different – Punit Vara Sep 11 '18 at 04:12
  • How I can debug? Why "cannot install the module"? I cannot remove the `insmod: error inserting './hello.ko': -1 Invalid module format.`, and I cannot check main reason – Wang Liang Jul 02 '19 at 21:08
  • At raspbian, I re installed the `raspberry header`, and, re build the module – Wang Liang Jul 03 '19 at 06:31
  • I have the same Makefile as the first one but I get the OP error: `$ make` is ok, but `$ sudo insmod HiAgain.ko` prints out `insmod: ERROR: could not insert module HiAgain.ko: Invalid module format`. In this case my 'HiAgain.c' file is trying to call a function ('extern'ed in `HiAgain.c`) defined in a different module 'HelloKernel' (via `EXPORT_SYMBOL` from there). No idea what I'm doing wrong! – Gregory Fenn Jul 01 '21 at 17:07
1

You did everything correctly but did not booted your system with the kernel you compiled so the first step is you should boot with it. If you are using Ubuntu you can hold shift button at the time of booting and you will be given a list of compiled kernel in your system from there select linux-source-2.6.38 and then try to build your module and install it with your way ,than you won't find any problem. GoodLuck.

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Rusty
  • 168
  • 6
  • 1
    Hi @Rusty, why I have to install the kernel I have build? If so, any one who wants to install my kernel have to install the kernel I have built ? – roMoon Dec 21 '15 at 14:26
0

Try using cross compile. Please look at the code below for the make file. Be mindful of the indentation else you may end up with error such as missing separator. Stop

obj-m += hello_.o #this name should be the name of your .c file. I am just using hello for example

I suggest the best approach is via cross compilation

Create a variable to hold the directory name where the linux kernel directory resides In my example, change the value "PATH_TO_LINUX_KERNEL_DIRECTORY" to a real path value Example ~/linux You really need to do this so that the make file will know where to find arm-linux-gnueabi- Without this, you are likely to run into issues arm-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
Phil3992
  • 1,059
  • 6
  • 21
  • 45
rocksyne
  • 1,264
  • 15
  • 17
0

Use the following commands:

sudo apt update && sudo apt upgrade
sudo apt remove --purge linux-headers-*
sudo apt autoremove && sudo apt autoclean
sudo apt install linux-headers-generic

This will reinstall the kernel headers

ganya
  • 1
  • 1