How to compile a kernel module against a new Source - linux

I am trying to compile a Hello World module. I am having a fresh Ubuntu in my system which doesn't have any compiled kernel.
My kernel is:
2.6.32-34-generic
I gave the following Makefile and got the error:
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
# make
make -C /lib/modules/2.6.32-34-generic/build M=/home/james/Desktop/hello modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-34-generic'
make[2]: *** No rule to make target `/home/james/Desktop/hello/hello-1.c', needed by `/home/james/Desktop/hello/hello-1.o'. Stop.
make[1]: *** [_module_/home/james/Desktop/hello] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-34-generic'
make: *** [all] Error 2
The contents of my /lib/modules/2.6.32-34-generic are
total 3864
lrwxrwxrwx 1 root root 40 2011-11-05 15:55 build -> /usr/src/linux-headers-2.6.32-34-generic
drwxr-xr-x 2 root root 4096 2011-11-05 15:49 initrd
drwxr-xr-x 10 root root 4096 2011-11-05 15:49 kernel
.......................................................
.......................................................
The folder /usr/src/linux-headers-2.6.32-34-generic exists.
Since it didnt work, I downloaded the linux-headers-2.6.32-34-generic source from Ubuntu and compiled and changed my Makefile to:
obj-m += hello-1.o
all:
make -C /usr/src/linux-2.6.32/ M=$(PWD) modules
clean:
make -C /usr/src/linux-2.6.32/ M=$(PWD) clean
#make
make -C /usr/src/linux-2.6.32/ M=/home/james/Desktop/hello modules
make[1]: Entering directory `/usr/src/linux-2.6.32'
ERROR: Kernel configuration is invalid.
include/linux/autoconf.h or include/config/auto.conf are missing.
Run 'make oldconfig && make prepare' on kernel src to fix it.
WARNING: Symbol version dump /usr/src/linux-2.6.32/Module.symvers
is missing; modules will have no dependencies and modversions.
make[2]: *** No rule to make target `/home/james/Desktop/hello/hello-1.c', needed by `/home/james/Desktop/hello/hello-1.o'. Stop.
make[1]: *** [_module_/home/james/Desktop/hello] Error 2
make[1]: Leaving directory `/usr/src/linux-2.6.32'
make: *** [all] Error 2
Could someone help me solving this.http://packages.ubuntu.com/lucid-updates/devel/linux-headers-2.6.32-34-generic
I have some general questions to ask.
After a fresh install what is the best way of compiling a kernel. After I compiled the kernel and built a module it worked flawlessly earlier. But I couldnt know what to do this in this situation

The error:
ERROR: Kernel configuration is invalid.
include/linux/autoconf.h or include/config/auto.conf are missing.
Run 'make oldconfig && make prepare' on kernel src to fix it.
WARNING: Symbol version dump /usr/src/linux-2.6.32/Module.symvers
is missing; modules will have no dependencies and modversions.
simply is because your kernel source is newly downloaded and uncompiled before.
This is how u should compile any kernel module.
After download the kernel source, you must prepare it for adding any modules to it.
Copy the older-kernel's "config-xxxx" file from the /boot/ directory into the new kernel source directory, and rename it as ".config".
Then execute "make oldconfig", which will take a backup of the .config into .config.old, and regenerate a new .config based on the new kernel source. Just enter "ENTER" for all the default settings (lots of them).
Next is to do a "make" (and wait for some time) - it will generate a new kernel file "vmlinux", together with many other files which is read by the modules compilation process.
Now you can go to your directory where the kernel module source code is located, and based on the following Makefile:
obj-m += hello-1.o
default: modules
modules:
make -C /kernel_source/ M=$(PWD) modules
clean:
make -C /kernel_source/ M=$(PWD) clean
Together with Makefile are your header and source file, which is hello-1.c located together.
Just "make" and your kernel modules should be generated successfully.

You need to install some package like 'kernel-devel' on Fedora (sorry I am not a Ubuntu user), it provides the headers and .config to compile your kernel module.

make[2]: * No rule to make target
/home/james/Desktop/hello/hello-1.c', needed by/home/james/Desktop/hello/hello-1.o'. Stop
Your are facing this error in the first compilation because hello-1.c file is missing in /home/james/Desktop/hello/ directory.

Check if hello-1.c exists in /home/james/Desktop/hello/ directory.
You need to have modules_enabled in your kernel. You need to compile a fresh kernel to do this.
Following post explains how to build kernel nicely. Enable modules in configuration of kernel build.
http://kernelnewbies.org/FAQ/KernelCompilation

Related

Kernel module on cross-compile kernel: /bin/sh: 1: scripts/basic/fixdep: Exec format error

I'm doing some experiment on rpi4, and trying to reproduce this kernel module from github https://github.com/sysprog21/dont-trace on my rpi4. I encounter this problem:
make -C /lib/modules/`uname -r`/build M=/home/ubuntu/dont-trace modules
make[1]: Entering directory '/usr/src/linux-headers-5.15.65-rt49-preemptrt-full-raspi'
warning: the compiler differs from the one used to build the kernel
The kernel was built by: aarch64-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110
You are using: gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0
CC [M] /home/ubuntu/dont-trace/dont_trace.o
/bin/sh: 1: scripts/basic/fixdep: Exec format error
make[2]: *** [scripts/Makefile.build:289: /home/ubuntu/dont-trace/dont_trace.o] Error 126
make[2]: *** Deleting file '/home/ubuntu/dont-trace/dont_trace.o'
make[1]: *** [Makefile:1896: /home/ubuntu/dont-trace] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.15.65-rt49-preemptrt-full-raspi'
make: *** [Makefile:7: all] Error 2
The kernel here is cross-compiled from x86 server and do show above. I was wondering how to solve this problem & what's the root cause. I can make it on x86 server. It should be something fundamental knowledge I don't understand. Thks!
it seems work this time
My solution might be a bit workaround, but it works. I follow the clues /bin/sh: 1: scripts/basic/fixdep: Exec format error. So I copy the source code to local raspberry pi, and make modules_prepare to construct complete /scripts, then move it into /lib/modules/`uname -r\`/build. It remain the gcc version warning, but work properly.

make refuses to build kernel module

I have to write a simple linux kernel module for a study research project, but I am having trouble with make. This is what my Makefile looks like right now:
obj-m := main.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
The source file I want to compile is named main.c, and when I type make in the source code directory I get this output:
root#debian:~/test-module# make
make -C /lib/modules/4.9.0-4-amd64/build M=/root/test-module modules
make[1]: Entering directory '/lib/modules/4.9.0-4-amd64/build'
make[1]: *** No rule to make target 'modules'. Stop.
make[1]: Leaving directory '/lib/modules/4.9.0-4-amd64/build'
Makefile:6: recipe for target 'all' failed
make: *** [all] Error 2
As the output already suggests, I am running Debian 9 with kernel 4.9.0-4-amd64. Since I am pretty new to Makefiles, I can't find any errors in the file. Could somebody please explain to me where my error is?
UPDATE: After some research I found out that /lib/modules/4.9.0-4-amd64/build must contain the kernel source tree. So i did
ln -s /usr/src/linux-source-4.9 /lib/modules/4.9.0-4-amd64/build
where the link's target directory contains the complete linux kernel source tree. When I run make now, I get this output:
root#debian:~/test-module# make
make -C /lib/modules/4.9.0-4-amd64/build modules
make[1]: Entering directory '/usr/src/linux-source-4.9'
scripts/kconfig/conf --silentoldconfig Kconfig
***
*** Configuration file ".config" not found!
***
*** Please run some configurator (e.g. "make oldconfig" or
*** "make menuconfig" or "make xconfig").
***
scripts/kconfig/Makefile:37: recipe for target 'silentoldconfig' failed
make[3]: *** [silentoldconfig] Error 1
Makefile:548: recipe for target 'silentoldconfig' failed
make[2]: *** [silentoldconfig] Error 2
The present kernel configuration has modules disabled.
Type 'make config' and enable loadable module support.
Then build a kernel with module support enabled.
Makefile:1271: recipe for target 'modules' failed
make[1]: *** [modules] Error 1
make[1]: Leaving directory '/usr/src/linux-source-4.9'
Makefile:4: recipe for target 'all' failed
make: *** [all] Error 2
Looks better than last time, but still doesn't work. I guess I just have to run a make config or so in some directory of the kernel source tree, but I don't know where. What should I do?
I finally found out the error: I forgot to specify the M variable in my makefile. It works properly now. This is what my makefile looks like right now, if future users want to know:
obj-m := testmodule.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
Thank you all for your help anyways!

How to fix : No rule to make target?

I am trying to build a demo kernel module, but when I do make, I get following,
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-47-generic'
make[2]: *** No rule to make target 'arch/x86/entry/syscalls/syscall_32.tbl', needed by 'arch/x86/entry/syscalls/../../include/generated/asm/syscalls_32.h'. Stop.
arch/x86/Makefile:199: recipe for target 'archheaders' failed
make[1]: *** [archheaders] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-47-generic'
Makefile:4: recipe for target 'all' failed
I am building module across linux kernel - 4.4.0-47 version - 64 bit OS. Can anyone please help me to understand why I am facing this Error.Thank you in advance.
Make sure you have proper make file. this is a very common issue.
or you could use below statement in makefile also.
obj-m += your_module_name.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
it should work.

Linux Kernel Module Programming Guide - Example 2.4

After issuing a make command to compile Example 2.4 from the Linux Kernel Module Programming Guide, I get the following response:
$ make
make -C /lib/modules/3.11.0-12-generic/build M= modules
make[1]: Entering directory `/usr/src/linux-headers-3.11.0-12-generic'
/usr/src/linux-headers-3.11.0-12-generic/arch/x86/Makefile:107: CONFIG_X86_X32 enabled but no binutils support
make[2]: *** No rule to make target `/usr/src/linux-headers-3.11.0-12-generic/arch/x86 /syscalls/syscall_32.tbl', needed by `arch/x86/syscalls/../include/generated /uapi/asm/unistd_32.h'. Stop.
make[1]: *** [archheaders] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.11.0-12-generic'
make: *** [all] Error 2
Here's the content of the appropriate makefile:
obj−m += hello−1.o
obj−m += hello−2.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
I'd appreciate any help, since I'm a complete noob regarding the topic.
EDIT: After rewriting the makefile, the compilation succeeded for some mysterious reason.
it looks like conflicts in your setup, you can do following things may work..
1)if your installation is 64-bit then check following file
vim /boot/config-3.8.0-19-generic
CONFIG_X86_X32=y then there is problem
it should CONFIG_X86_X32=n
and CONFIG_X86_X64=y
2)other option is install remove your binutils using apt-get remove binutils and then install again using apt-get install binutils
Rewriting the makefile solved the problem
A common cause of CONFIG_X86_X32 enabled but no binutils support is spaces in the compilation directory, but that's clearly not the issue in your case.
I've had CONFIG_X86_X32 enabled but no binutils support in some cases if the kernel source directory belongs to root and you're running as an unprivileged user. Building with sudo make fixed this for me.

How to compile a kernel module for Raspberry pi?

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

Resources