Linux Kernel Module Error on Raspberry Pi - linux

I have got one of the small raspberry pi computers, and i am having my first play with creating a kernel module. I have downloaded the source, and managed to compile my test module but when i try and load it i get this error:
insmod: error inserting 'hello.ko': -1 Invalid module format
and when i look in dmesg i see this error:
hello: version magic '3.1.9+ mod_unload modversions ARMv6 p2v8 ' should be '3.1.9+ mod_unload modversions ARMv6 '
Can anyone point me in the right direction, i'm not sure what its telling me?
Cheers
Luke

It sounds like the kernel source you downloaded does not match the kernel installed on your Pi.
Where did you download it from?
To get the correct source for your kernel type the following on the command line:
sudo apt-get install linux-source
This should download the correct kernel source for you kernel (it is a meta-package). You should now see a directory under /lib/modules/ that matches your kernel version (the version printed out when you type uname -r)
Recompile and link you code - make sure you pick up the correct kernel source by having a line like this in your Makefile:
all:
make -C /lib/modules/$(shell uname -r)/build M=${PWD} modules
You newly compiled .ko module should now match you kernel and insert without complaints.
Good luck!

Related

How to include linux driver source files in a kernel module written in C?

I am currently writing a linux kernel module that needs to include a file from the linux driver source code. The particular file I am trying to include is: https://elixir.bootlin.com/linux/latest/source/drivers/nvme/host/nvme.h
But the /lib/modules/$(shell uname -r)/build directory does not contain the drivers folder. I tried doing sudo apt-get install linux-headers-$(shell uname -r) but that also does not include the driver header files. My Makefile looks like this:
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
I then tried to get a full kernel checkout of the kernel version closest to my kernel version (I couldn't find the exact source code for my kernel version.) I pointed my Makefile to use that version but then when I try to insert the kernel module, it throws Invalid module format error and dmesg shows no symbol version for module layout. My source directory does contain the Module.symvers file but it still throws this error. I believe this error could be resolved if I somehow use my current linux source.
So, what's the best way to get the driver header files and use them in a kernel module. Any help would be appreciated.
I see you are using apt. In such case you can get the correct source for your kernel simply enabling source repositories (see here or here to know how) and then getting the source code of the package:
$ sudo apt-get update
$ sudo apt-get source linux-image-$(uname -r)
After this, you will have the following files in the current directory:
linux-XXX/
linux_XXX.tar.xz
linux_XXX.dsc
linux_XXX.orig.tar.xz
The first one is a folder containing the correct source code for your installed kernel. You'll then be able to #include the header you need for your module.

Compiling mptfc kernel module for CentOS 7 -- insmod returns "invalid parameters"

I'm trying to compile the mptfc driver for a CentOS 7 box. We have some legacy hardware that we need to support on CentOS 7 for dependency reasons.
mptfc was included in CentOS 6, but in CentOS 7 they decided to not include it in the kernel any more. (source: Redhat)
I noticed that elrepo created a RPM for the driver (from this article), but I had to dig for it. Eventually found it in some mirrors that provided archive capabilities, but the computer would not finish booting the kernel. Unfortunately, I don't have that output to display, but it wasn't pretty. Lots of error messages.
Because I can not use CentOS 6, I decided the next choice was to compile the kernel module myself. I have never done that, so I am running into a few issues.
First, I downloaded the headers for the kernel I am running (3.10.0-957.el7.x86_64) using:
yum install linux-headers
Then I downloaded the source code on a different machine for Linux 3.10 from Github. I copied the drivers/message/fusion directory from the source code to the machine I am compiling and put it in my home folder. I modified the Makefile to look like:
...
obj-$(CONFIG_FUSION_SPI) += mptbase.o mptscsih.o mptspi.o
obj-m += mptbase.o mptscsih.o mptfc.o
obj-m += mptbase.o mptscsih.o mptsas.o
obj-$(CONFIG_FUSION_CTL) += mptctl.o
obj-$(CONFIG_FUSION_LAN) += mptlan.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
Then I ran make. It compiles fine, but when I try to do the following:
insmod mptfc.ko
I get the following:
[root#host fusion]# insmod mptfc.ko
insmod: ERROR: could not insert module mptfc.ko: Invalid parameters
And dmesg returns:
[root#host fusion]# dmesg | tail
[184711.751960] mptfc: disagrees about version of symbol mptscsih_qcmd
[184711.751970] mptfc: Unknown symbol mptscsih_qcmd (err -22)
I've never compiled kernel modules before, so I'm not sure where to start debugging this.
My end goal is to get the legacy pci card that uses mptfc working. If there is a better way to get the driver into the kernel, and working, that works as well.

could not insert module after kernel upgrade in VM

I was running Win7 as host and ubuntu14.04 as VM, on Virtualbox I upgraded the VM kernel. Thereafter, after compiling my kernel module again against the new kernel, i am not able to insmoding it.
It gives the following error :
vm#vm:~/Documents/kernelDev/CustomSockets$ sudo insmod CustomSocket.ko
insmod: ERROR: could not insert module CustomSocket.ko: Invalid module format
I dont see any eror message in dmesg logs.
I make sure that i am compiling the module against the correct kernel which is actually running.
vm#vm:/lib/modules/3.12.59UML$ pwd
/lib/modules/3.12.59UML
Makefile to compile the module:
obj-m += CustomSocket.o
all:
make -C /lib/modules/3.12.59UML/build M=$(PWD) modules
clean:
make -C /lib/modules/3.12.59UML/build M=$(PWD) clean
Can anyone pls help me out here ?
My bad, i was compiling against the wrong kernel version headers. Issue has been resolved.

Error when loading cross compiled kernel module

I have cross compiled a simple helloworld kernel module, the host is a x86 machine and the target an ARM board. When I do modprobe to install the module in the target i get this message:
FATAL: Could not load /lib/modules/3.14.0-xilinx-13567-g906a2c9-dirty/modules.dep: No such file or directory
I have make sure that the module is compiled with the same version as the target.
uname -a : 3.14.0-xilinx-13567-g906a2c9-dirty
modinfo: vermagic: 3.14.0-xilinx-13567-g906a2c9-dirty SMP preempt mod_unload modversions ARMv7 p2v8
What can be the problem? What does that error means?
Apparently, you are missing the file specifying module dependencies (generated at build time and installed with make module_install).
The simplest solution is, if your mdule does not have external dependencies, insert it with insmod rather than with modprobe.
Try to run:
depmod -a
on the ARM board.
it should solve your problem.
I would suggest the following steps.
Do insmod $module-name
Check the dmesg commands output. If you see the following message
version magic '3.14.0-xilinx-13567-g906a2c9-dirty xxxxxxxx' should be
'3.14.0-xilinx-13567-g906a2c9-dirty xxxxxxxxxx'
then the problem is because of the changes made to the kernel.
Commit the changes to the git repository and re-build the kernel.
Create a new kernel image and then boot the target with the updated kernel.

Cross compiling a kernel module: how to set configs right

I'm trying to cross-compile an external module for the Beaglebone (Linux, ARM).To avoid kernel version issues I grabbed a kernel tarball and cross-compiled for ARM with the CodeSourcery toolchain on the host machine (x86). Then I cross-compiled an external hello-world module with the exact same toolchain against the exact same kernel sources. I used this simple makefile:
obj-m += hello-1.o
all:
make -C /home/***/****/linux-3.2.0-beaglebone-20120411.00
M=$(PWD) modules
clean:
make -C /home/***/****/linux-3.2.0-beaglebone-20120411.00 M=$(PWD) clean
When I copy the ko-file over to target and try to insmod it I get: "insmod: error inserting 'hello-1.ko': -1 Invalid module format" which (from what I learned in this group and elsewhere) usually stems from conflicting kernel versions, and indeed uname -a on the target gives:
Linux beaglebone 3.2.18 #1 Wed May 30 14:21:54 CEST 2012 armv7l GNU/Linux
while modinfo hello-1.ko gives:
srcversion: 140276773A3090F6F33891F
depends:
vermagic: 3.2.0+ mod_unload modversions ARMv5 p2v8
So version 3.2.18 vs. 3.2.0+ (why the +?) and armv7l vs. ARMv5!
Does anyone know why I get different versions albeit I compiled against the same kernel-sources (maybe some configs)?
Any suggestions are appreciated!
best,
Chris
answer is, you should run 'the kernel you compiled on beagle board.
'+' means that you modified your source tree.
And finally make sure that you're using correct defconfig. 'make beagle_defconfig' should work.

Resources