How to build a kernel module - linux-kernel

I am trying to compile a hello world module given over here
I have followed the following step.
Downloaded Linux kernel 2.6.35-rc5
extracted to directory /general/source/linux
Complied the entire kernel.
created a dir test in the linux folder.
Created and complied a hello world module as mentioned there.
when I run the insmod command, I get this error
insmod: error inserting 'hello.ko': -1 Invalid module format
How do I sort out this error?
Regards,

Ok the mistake that you are making is the kernel version.
First try
uname -r
You would get the kernel version. The downloaded version mostly likely won't be the kernel version of your system.
So change the make file to
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
.PHONY: build clean
build:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c
else
$(info Building with KERNELRELEASE = ${KERNELRELEASE})
obj-m := hello.o
endif
Make sure the tabs are in the order as mentioned in the above script.

Your kernel module must match the running kernel. If you want to install this specific module, for example, you'd need to also install the kernel that you've built.
Normally, you'd not build the kernel on your own and use a pre-built version that matches your distribution's kernel. Look for a kernel-headers package in your distribution's repository.

Related

how to solve Kernel configuration is invalid issues

I'm trying to build module.
But here's some issues.
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 ./Module.symvers
is missing; modules will have no dependencies and modversions.`
And here's my makefile
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
.PHONY: modules modules_install clean
else
# called from kernel build system: just declare what our modules are
obj-m := hello.o hellop.o seq.o jit.o jiq.o sleepy.o complete.o \
silly.o faulty.o kdatasize.o kdataalign.o
endif
I tried building like this:
export KERNELDIR=/path/to/extern/linux/source
make
How can I solve this problem?
Okay, so I would try to re-install the Linux-headers.
prerequisites
terminal access(bash presumably)
root privileges
(or a user who can do 'sudo')
First, we try to re install (using APT) the linux-headers package but adding your specific version. Which is determined by the following command: $(uname -r)
and to do it all in one line:
sudo apt install --reinstall linux-headers-$(uname -r)
Then, as we talk about the kernel, and making changes to it (quite major too, a reinstall of a kernel that is) we want to reboot as soon as the APT command is done:
sudo reboot
If you get it couldn't find any package, (or similar) (from apt)
try apt update and re-try the above.
Logs
Do check /var/log/kern.log for any messages that is,
cat /var/log/kern.log
I solved this problem with the following commands:
From your built sources take the most recent .config file with kernel configuration. Copy it to kernel-source directory (e.g.: build/tmp/work-shared/lmm-corei7/kernel-source).
Run make prepare.
I spent hours on the same problem, having the same error message : ERROR: Kernel configuration is invalid...
The solution was so simple...
I was running sudo make and this created the errors.
After having done what is suggested by William Martens (reinstall the headers and reboot), I logged as root, and the module built perfectly.
To be sure, I did a second test with an admin account and sudo make, and it failed again. So I am sure this is the reason. I noticed also that after a fail, I have to reinstall the headers otherwise, even in root, it fails.
This happened on a Debian 11 with kernel 5.10.0-16-amd64.

Cross Compile Linux Kernel Module

I am looking into cross compiling a kernel module for an ARM linux. I have my toolchain installed.
But there's something I am not quite getting from various how-tos.
The module I want to build is gadgetfs.
The kernel version on my host is 3.5.0-34-generic while
on the target it's 3.6.9-0.1
Now what kernel sources or headers do I actually need to download and install, and where?
I downloaded linux-3.6.9.tar.bz2 from kernel.org and extracted it.
In drivers/usb/gadget/ there's a Makefile and according to this site I need to append these lines to it, then run make:
KDIR := /lib/modules/`uname -r`/build
PWD := `pwd`
obj-m := dummy_hcd.o gadgetfs.o
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
But what do i have to replace uname -r with? Cause this would give me my host's kernel version. But my target version is different. Where is the /lib/modules/3.6.9 folder?
CROSS_COMPILE and ARCH is both set.
You need to cross compile (or download pre-compiled) matching version of Linux for your target on your host machine with right configuration since Linux doesn't have a stable binary API. Host's kernel version is not relevant.
After having target build available on your host you can build a module via
make -C kernel_build_dir M=`pwd` ARCH=arm CROSS_COMPILE=<...> modules
under that module's directory.

Compile Warning - ARM Cross Compiler

I have been trying to cross compile a loadable kernel module and I have been getting warning message that I would like to get help.
Below is the warning message
make[1]: Entering directory `/home/userid/rowboat-android/kernel'
Building modules, stage 2.
MODPOST 1 modules
WARNING: "omap_device_build" [/home/userid/myfiles/lcdc_load_device.ko] undefined!
WARNING: "omap_hwmod_lookup" [/home/userid/myfiles/lcdc_load_device.ko] undefined!
make[1]: Leaving directory `/home/userid/rowboat-android/kernel'
Below is the Makefile
obj-m :=lcdc_load_device.o
lcdc_load_device-m := ../rowboat-android/kernel/arch/arm/plat-omap/omap_device.o
lcdc_load_device-m += ../rowboat-android/kernel/arch/arm/mach-omap2/omap_hwmod.o
ccflags-m := -I$(src)/../rowboat-android/kernel/arch/arm/plat-omap/include/plat/
KDIR := /home/userid/rowboat-android/kernel/
PWD := $(shell pwd)
default:
$(MAKE) ARCH=arm CROSS_COMPILE=/home/userid/rowboat-android/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
I am suspecting that the makefile is finding the header file for "omap_device_build" and "omap_hwmod_lookup" functions.
Appreciate your help, and thank you advance.
Thank you to mbratch and artless noise for their comments
To address the WARNINGS, the symbols need to be exported. For the above question place
EXPORT_SYMBOL(omap_device_build) in omap_device.c
EXPORT_SYMBOL(omap_hwmod_lookup) in omap_hwmod.c
and compile the kernel. Then compile the loadable kernel module against the compiled kernel. Perform the following to verify if the symbols have been exported
grep omap_device_build /proc/kallsyms
or
grep omap_device_build Module.symvers
For more details reference the following links
Kernel Symbols: What's available to Your Module
Building and Running Modules
Comments are welcome
Thank you

Creating simple kernel module

I've just started learning linux kernel modules and trying to write simple Hello world program.
So mymod.c:
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Author");
MODULE_DESCRIPTION("\"Hello, world!\" minimal module");
MODULE_VERSION("printk");
int init_module(void)
{
printk("<1>Hello world 1.\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_ALERT "Goodbye world 1.\n");
}
Makefile:
obj-m += mymod.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 outout:
make -C /lib/modules/3.2.0-23-generic-pae/build M=/root modules
make[1]: Entering directory `/usr/src/linux-3.2.42'
WARNING: Symbol version dump /usr/src/linux-3.2.42/Module.symvers
is missing; modules will have no dependencies and modversions.
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory `/usr/src/linux-3.2.42'
So it creates files I needed, but when I try to install this by
insmod mymod.ko
I get next output:
insmod: error inserting 'mymod.ko': -1 Invalid module format
So I'd like to know what's the problem?
PS. OS - Ubuntu Server 12.04. Kernel - linux 3.2.0-23 pae
UPDATE:
I've downloaded from kernel.org kernel 3.2.42 and put it in /usr/src and did 'make defconfig && make prepare', 'make modules_prepare'. Also I've created link in /lib/modules/3.2.0-23-generic-pae/build.
Is this the source tree for the running kernel? If not, it should fail.
Install the kernel-devel (or similarly named) package for your distribution, it adds enough machinery to build modules against it.
You missed the module_init and module_cleanup declaration,
module_init (module_init);
module_exit (cleanup_module);
Otherwise it would have no entry point defined, and it wouldn't load.
Because this task requires so many details, and small files to be coordinated it is best to use UML (user mode linux) so that the kprintf (kernel printf) always outputs to the terminal even in a graphical environment.

User Mode Linux - Installing a module error

I am trying to run 'make' on a module in User Mode Linux to install a simple makefile. Here is my make file:
obj-m := hello.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
When I run this in User Mode Linux I get the following error:
make[1]: Entering directory `/lib/modules/2.6.28/build'
make[1]: *** No rule to make target `modules'. Stop.
make[1]: Leaving directory `/lib/modules/2.6.28/build'
make: *** [default] Error 2
The problem is that no files are present under /lib/modules/. There's no directory for 2.6.28 or build. From what I've read, these should be symlinks to /usr/src, but under /usr/src, I don't see any files under that either.
Sources and headers of your UML kernel must be used to compile module for it.
You can compile it either inside UML or just in main system, but you must to use UML's kernel's headers and build scripts
You need to build and install the version of the kernel you are compiling for. Get the source from kernel.org, configure (I think make menuconfig picks the config up from the running kernel), build, and install it. You can do the build in your home directory under regular user, then of course you would need root to install it.
Edit:
Just in case you missed this - here's User Mode Linux HOWTO. It contains specific items for building and installing kernel and modules. Hope this helps.

Resources