How to compile Linux kernel module without kernel Makefile? - linux

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

Related

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

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.

Kernel Makefiel Link against Module

I am currently trying to write some Kernel Module code.
I am using the functions of an existing Kernel Module.
The hearders are included in my .c file but I dont know how to link my code with the Kernel Module properly
in normal userspace Makefiles I would know but not how to do this with Kernel Modules
Any suggestions?
Here's my Makefile
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
INC := -I/usr/src/kernels/$(shell uname -r)/include
obj-m := scif.o
all:
$(MAKE) V=1 -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean
You do not 'link' code between modules. Beside including the header files, a module can call only functions that are exported (with EXPORT_SYMBOL or EXPORT_SYMBOL_GPL ..etc) either in the main Kernel or in other modules. Also, make sure that module dependencies in modeules.dep are correct or the module will complain when it is loaded.

Device Driver. Make file,External module

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.

Cross-compiling external linux module: M=`pwd`directory not found

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-

Makefile for a basic kernel module

The following Makefile aims to create a basic Module in the kernel 2.6. And so, I really would like if somebody explain to me the command lines in this Makefile:
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
One further question : Being in a 2.6 kernel, should I replace hello-1.o by hello-1.ko?
The first line tells the kernel makefile that hello-1.o should be used to build a module. The kernel makefile will handle the extension itself; you should not change it.
The third and fifth lines invoke the kernel makefile to build/clean a module, passing it the directory it should look for source files in.
The rest is all standard makefile boilerplate.
See Documentation/kbuild/modules.txt in the kernel documentation for more details.

Resources