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.
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
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
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.
Related
I have an ARM Linux device, but I don't have the Makefile of the kernel to build a kernel module.
I have GCC cross compiler to this arch.
How can I compile a kernel module without the Makefile of the kernel?
How can I compile kernel module without have the Makefile of the kernel?
You can't. You need the kernel Makefile in order to compile a module, along with a pre-built kernel source tree. On most distributions, you can obtain the kernel source for building modules through packages like linux-headers-xxx where xxx should be the output of uname -r.
For example, on Debian or Ubuntu:
sudo apt-get install linux-headers-$(uanme -r)
You will then find the files needed for building modules at /lib/modules/$(uname -r)/build, and you can build a module with a Makefile like this:
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
obj-m := mymodule.o # same name as the .c file of your module
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
What this does is basically invoking the kernel Makefile telling it to build the module in the current directory.
Also, I am not sure why you say that you are on an ARM Linux device, and you have a cross compiler. If you are on the device itself, you shouldn't need a cross compiler at all. If you are on a different device, then you'll need to use the appropriate uname -r for the target device in order to get the right sources and in order to build. You might need to do this by hand since the output of uname -r isn't always helpful.
You'll also need to secify the architecture and cross compilation toolchain prefix in the module Makefile, for example:
default:
$(MAKE) -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules
I'm having trouble compiling a kernel module for a raspberry pi. I want to compile a "hello world" kernel module using the raspberry pi itself.
I am using raspbian wheezy 3.6.11+.
I tried following the directions at http://elinux.org/RPi_Kernel_Compilation.
Here is the Makefile I am using:
obj-m += hello-1.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
Here is the source code for hello-1.c:
/*
* hello-1.c - The simplest kernel module.
*/
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
int init_module(void)
{
printk(KERN_INFO "Hello world 1.\n");
/*
* A non 0 return means init_module failed; module can't be loaded.
*/
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Goodbye world 1.\n");
}
Here's what I get when I try to make the project:
root#raspberrypi:/home/pi/hello-module# make
make -C /lib/modules/3.6.11+/build M=/home/pi/hello-module modules
make: *** /lib/modules/3.6.11+/build: No such file or directory. Stop.
make: *** [all] Error 2
I tried creating the build directory at /lib/modules/3.6.11+
make -C /lib/modules/3.6.11+/build M=/home/pi/hello-module modules
make[1]: Entering directory `/lib/modules/3.6.11+/build'
make[1]: *** No rule to make target `modules'. Stop.
make[1]: Leaving directory `/lib/modules/3.6.11+/build'
make: *** [all] Error 2
I have GNU Make 3.81 and gcc (Debian 4.6.3-14+rpi1) 4.6.3 installed. I also installed the linux source using
sudo apt-get install linux-source
Any ideas on what I might do to get this to compile?
Here are the steps I used to build the Hello World kernel module on Raspbian.
Perform sudo rpi-update
See https://github.com/Hexxeh/rpi-update for details on
rpi-update. You have to be on the latest firmware and associated kernel to be able to perform the next step.
Install and run rpi-source to install the source code that built the latest kernel that you are running. This will create the correct entry in /lib/modules for the kernel that you are running. Note: you don't need to be root to run this, however the script will perform certain tasks using sudo and the root password will be requested during the script execution.
Instructions to install rpi-source can be found at https://github.com/notro/rpi-source/wiki
Once those steps are performed you should be able to make the Hello World kernel module.
johnma#raspberrypi ~/HelloWorld $ make
make -C /lib/modules/3.12.19+/build M=/home/johnma/HelloWorld modules
make[1]: Entering directory `/home/johnma/linux-c3db7205bcd8988cf7c185e50c8849542554b1f5'
CC [M] /home/johnma/HelloWorld/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/johnma/HelloWorld/hello.mod.o
LD [M] /home/johnma/HelloWorld/hello.ko
make[1]: Leaving directory `/home/johnma/linux-c3db7205bcd8988cf7c185e50c8849542554b1f5'
johnma#raspberrypi ~/HelloWorld $ sudo insmod hello.ko
johnma#raspberrypi ~/HelloWorld $ tail -1 /var/log/syslog
May 15 13:45:39 raspberrypi kernel: [59789.169461] Hello World :)
johnma#raspberrypi ~/HelloWorld $ sudo rmmod hello.ko
johnma#raspberrypi ~/HelloWorld $ tail -1 /var/log/syslog
May 15 13:46:10 raspberrypi kernel: [59819.503503] Goodbye World!
When compiling a module the -C parameter should point to the source tree where the kernel was built (don't clean it up!). If you built it on the pi its likely in a directory under your home directory.
The build directory under /lib/modules/<version> is a Debian-ism, where a cut-down version of the source tree is provided with just enough context to build modules against. The kernels from the Raspberry Pi Foundation kernels don't ship with a build directory.
They may be a bit out of date, but raspbian provides a kernel as a Debian-style package, which should include the build directory you could use to build kernel modules against.
sudo aptitude install linux-image-rpi-rpfv linux-headers-rpi-rpfv
You first need kernel headers (and the corresponding kernel binary) to build your module.
Like Greg said, the raspbian distribution provides the packages :
sudo apt-get install linux-image-rpi-rpfv linux-headers-rpi-rpfv
Then, tell raspbian to boot your newly installed kernel (3.10-3-rpi for me).
Append this at end of /boot/config.txt and reboot your Pi :
# Parameters to boot on raspbian kernel (linux-image-rpi-rpfv package)
kernel=vmlinuz-3.10-3-rpi
initramfs initrd.img-3.10-3-rpi followkernel
Then, modify your Makefile to point the freshly installed kernel headers :
KERNEL_HEADERS=/lib/modules/$(shell uname -r)/build
obj-m := hello-1.o
all:
#$(MAKE) -C $(KERNEL_HEADERS) M=$(PWD) modules
clean:
#$(MAKE) -C $(KERNEL_HEADERS) M=$(PWD) clean
This was a pain. I had to compile and install a kernel mode driver.After long search, i got the headers for pi 2 (3.18.7-v7+) from here.
sudo apt-get install dkms build-essential
wget http://www.niksula.hut.fi/~mhiienka/Rpi/linux-headers-rpi/linux-headers-3.18.7-v7%2b_3.18.7-v7%2b-2_armhf.deb
sudo dpkg -i linux-headers-3.18.7-v7+_3.18.7-v7+-2_armhf.deb
I meet with the same problem and just fix it by sudo apt-get install raspberrypi-kernel-headers
I was working on the exact same sample on my RPI with the exact same kernel. I managed to compile the module on my RPI but when I issued insmod I received an error. I followed the instructions here on an XUbuntu virtual machine (using my RPI's kernel version 3.6.y) and it worked perfectly. Not sure why compiling directly on the RPI did not work, that will be a problem for another day.
I had to change the Makefile to match the new environment.
obj-m += hello-1.o
all:
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -C /home/cstick/rpi/linux-rpi-3.6.y M=$(PWD) modules
clean:
make -C /home/cstick/rpi/linux-rpi-3.6.y M=$(PWD) clean
I'm trying to cross compile a helloworld kernel (2.6.x) module for ARM architecture on my intel x86 host.
The tool chain for ARM is located at: /home/vivek/ti-sdk-am335x-evm-05.07.00.00/linux-devkit/bin
The kernel source is located at: /home/vivek/Arago
The hellow.c and Makefile are located on Desktop on /home/vivek/Desktop/hellodriver
I have given the path for cross compiler as /home/vivek/ti-sdk-am335x-evm-05.07.00.00/linux-devkit/bin
My Makefile is follows:-
export ARCH=arm
export CROSS_COMPILE=arm-arago-linux-gnueabi-
obj-m =Hello.o
KDIR =/home/vivek/Arago
PWD = $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
On executing make I am getting
vivek#ubuntu:~/Desktop/hellodriver$ make
make: Nothing to be done for `default'.
What am I doing wrong?
There is mistake in your Makefile. As your source code name is hellow.c, But in your Makefile its Hello.o.
So change your obj-m =Hello.o to obj-m =hellow.o
And one more thing Etan Reisner said above make sure you using Tab for command in Makefile.
I'm compiling an external module against a complete kernel tree using CentOS. I've succesfully modified, cross-compiled, built and booted this kernel on a Beaglebone. I'm using the linaro tools (arm-gnueabihf-). I'm using the same typical Makefile structure to compile the module I've ever used since 2.6 came out. When running the make rule:
make ARCH=arm CROSS_COMPILE=${CC} -C $(KDIR) M=`pwd` modules
where CC and KDIR are properly set for my toolchain and my kernel src tree, kbuild properly changes dir to the -C (kernel src) dir, but when coming back (i.e. processing M) I get the following error:
scripts/Makefile.build:44: /home/foo/bar/
Makefile: No such file or directory
where /home/foo/bar is actually my current working directory, i.e. the proper outcome of pwd
Directly writing my pwd path in M= or using a make var instead of invoking pwd yields the same result (not a syntax problem)
Any idea?
Just try this ,as i dont know how is your make file.
create Makefile in /home/foo/bar
obj-m += hello.o
KERNELDIR=/home/vinay.hunachyal/build/clfs/sources/linux-3.9
all:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean
In above Makefile edit KERNELDIR=(path-to-kernel-source)
also change obj-m +=(your module)
After this just build your module using
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
I'd like to redirect the output of my module build to segregate the artifacts from the source.
My makefile looks like:
obj-m += hello-1.o
all:
make ARCH=arm CROSS_COMPILE=arm-eabi- -C /work/TI-Android-ICS-4.0.3_AM37x_3.0.0/kernel M=$(PWD) modules
clean:
make ARCH=arm CROSS_COMPILE=arm-eabi- -C /work/TI-Android-ICS-4.0.3_AM37x_3.0.0/kernel M=$(PWD) clean
This works correctly, except that the module output happens to be in my source directory. I tried adding O={path to my output dirctory} in each line, but then it failed to build with something like...
ERROR: Kernel configuration is invalid.
include/generated/autoconf.h or include/config/auto.conf are missing.
Run 'make oldconfig && make prepare' on kernel src to fix it.
WARNING: Symbol version dump
/work/development/linux/driver/blah/Module.symvers
is missing; modules will have no dependencies and modversions.
I assume this stems from the fact that there is some output file from the kernel build that's used in the module build, and changing the output directory with "O=" collides with that.
Is there a method for accomplishing this using the existing build infrastructure?
Looking at the documentation for the module system, it doesn't look good. Perhaps you can copy .config into your build directory and do a make oldconfig && make modules-prepare with O= set.
Alternatively, what happens if you run make from another directory?
/somewhere/else$ make -C /path/to/kernel ARCH=arm CROSS_COMPILE=arm-eabi- M=/your/module/dir modules
This Makefile will solve your query
obj-m += hello-1.o
all:
make ARCH=arm CROSS_COMPILE=arm-eabi- -C /work/TI-Android-ICS-4.0.3_AM37x_3.0.0/kernel M=$(PWD) modules_install INSTALL_MOD_PATH=<output directory for modules>
clean:
make ARCH=arm CROSS_COMPILE=arm-eabi- -C /work/TI-Android-ICS-4.0.3_AM37x_3.0.0/kernel M=$(PWD) clean