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.
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 exampleI 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-
You did everything correctly but did not booted your system with the kernel you compiled so the 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.
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.
Now you can build and try to insert module.
I suggest you to become root if possible before this line
Alternatively you can also use following make file