Cross compiling a kernel module: how to set configs right - linux

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.

Related

Built kernel for 5.10.0-rc5 but when I do insmod, it complains it's for 5.4.21

I used to build my kernel module against 5.4.21 but today I built it against 5.10.0-rc5.
But when I do insmod after linux 5.10.0-rc5 is booted in a virtual machine, it complains like this.
/test1 # insmod axpu_ldd_kc.ko
[ 3331.286276] axpu_ldd_kc: version magic '5.4.21 SMP preempt mod_unload aarch64' should be '5.10.0-rc5 SMP preempt mod_unload aarch64'
insmod: can't insert 'axpu_ldd_kc.ko': invalid module format
So somewhere the 5.4.21 setting is used for the driver. My Makefile for the module build for 5.10.0-rc5 is like this.
export CROSS_COMPILE:=aarch64-none-linux-gnu-
export ARCH:=arm64
obj-m += axpu_ldd_kc.o
# test for ubuntu
export KDIR:=/home/ckim/ProjX/LinuxDevDrv/kernel-release-RD-INFRA-2020.11.30
ccflags-y:=-I/home/ckim/ProjX/QEMU/qemu-6.2.0/hw/misc
ccflags-y+=-I../../../../../axpusim/axpu
ccflags-y+=-I$(PWD)
all:
make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KDIR) M=$(PWD) modules
clean:
make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KDIR) M=$(PWD) clean
What can be wrong? (the /home/ckim/ProjX/LinuxDevDrv/kernel-release-RD-INFRA-2020.11.30 directory is 5.10.0-rc5)
SOLVED :
thanks for the comments. I found what was wrong. In the VM, I used tftp to get the driver and application. To get the driver I did tftp -g -r axpu_ldd_kc.ko 129.254.32.30. And I thought my tftp server directory of my machine (129.254.32.30) is /opt/tftp and placed the driver and app there. But it turns out my tftp server directory was /srv/tftp (ubuntu 20.04, set in /etc/default/tftpd-hpa). So I was using old driver file in /srv/tftp. :) I have forgot /srv/tftp is the new server directory.

How to compile a linux kernel module for different linux kernel

I am sort of new to kernel programming, but i have been struggling a ton with this issue for days now. I have a machine with linux kernel '5.10.0-kali7-amd64' and im using it for development of a linux kernel module for Ubutnu 16.04.4 '4.4.0-119-generic', but i can't figure out any way that i can compile it on my machine for that version and for it to actually work on the 4.4.0 kernel machine.
The closest i've got is this:
I downloaded source from https://launchpad.net/ubuntu/xenial/+package/linux-headers-4.4.0-119
and installed with dpkg
I then downloaded and installed the 4.4.0-119-generic from https://www.ubuntuupdates.org/package/core/xenial/main/updates/linux-image-4.4.0-119-generic
Both of them installed with no issue.
I compiled my module by using in my Makefile make -C /lib/modules/4.4.0-119-generic/build M=$(PWD) modules which also worked and compiled my hello world module.
However when uploaded to the 4.4.0 machine the insmod errored saying insmod: ERROR: could not insert module rootkitMy.ko: Invalid module format. The dmesg says: module: rootkit: Unknown rela relocation: 4 I then compiled my source code on the 4.4.0 machine and created a module with literally the exact same modinfo, but that one did work.
here are the modinfos for both:
filename: /rootkit.ko
version: 0.01
description: Rootkit hook
author: Bl4ckC4t
license: GPL
srcversion: 46604268C8D1B7FA5115CB4
depends:
vermagic: 4.4.0-119-generic SMP mod_unload modversions retpoline
filename: /rootkitMy.ko
version: 0.01
description: Rootkit hook
author: Bl4ckC4t
license: GPL
srcversion: 46604268C8D1B7FA5115CB4
depends:
vermagic: 4.4.0-119-generic SMP mod_unload modversions retpoline
rootkitMy.ko was compiled on the 5.10 machine and didn't work while the rootkit.ko was compiled on the 4.4.0 machine and did work properly when injected with insmod What can I do to compile a working module from my 5.10 machine?
I managed to resolve the issue. Unknown rela relocation: 4
is an insmod error you get due to a change in the way the kernel handles PLT, more specifically the R_X86_64_PC32 and R_X86_64_PLT32. With binutils >= 2.31, the linker has decided to use R_X86_64_PLT32 relocations, which aren't supported in the older kernel.
To fix this:
I downloaded an older version of binutils (2.26.1) from https://ftp.gnu.org/gnu/binutils/
extracted the folder from the archive
compiled the binutils to /usr/local/binutils-2.6 by running
./configure --prefix=/usr/local/binutils-2.6
make
sudo make install
exported the new binutils to my path and recompiled my module export PATH=/usr/local/binutils-2.6/bin:$PATH
And now it works!

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.

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.

Linux Kernel Module Error on Raspberry Pi

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!

Resources