I'm trying to cross compile a helloworld kernel module with specifications:
host: intel x86 32 bit, linux-3.0.0
target: ARM machine (Parrot AR.Drone), linux-2.6.27.47
I'm using the makefile:
PWD := $(shell pwd)
obj-m := test.o
all:
$(MAKE) -C /path/to/kernel M=$(PWD) CROSS_COMPILE=arm-none-linux-gnueabi- ARCH=arm modules
Where arm-none-linux-gnueabi- is the prefix of the arm toolchain.
As kernel, I tried using a clone from git://github.com/CyanogenMod/cm-kernel.git as kernel. This is a 2.6 kernel fork. Using this kernel, compilation was successfull. When trying to insert the module, it gives the error:
invalid module format
Which, sadly, says very little.
Thanks to the hint of Eugene to use dmesg, I found the error:
version magic '2.6.37.6 mod_unload modversions ARMv5 ' should be '2.6.27.47-parrot preempt mod_unload ARMv5 '
Conclusion: when compiling a kernel module, not only versions need to match, but also some config-parameters. My problem was solved by using the right version and editing the configuration.
If you don't want to reconfigure everything, a quick (ugly) fix is to edit include/generated/autoconf.h
my ugly fix is modifing script file
"scripts/setlocalversion"
170 if test "${LOCALVERSION+set}" != "set"; then
171 scm=$(scm_version --short)
172 # res="$res${scm:++}"
173 res="${res}"
174 fi
Hi, everyone.. I did found simple soulution.
just modify envirionment vairable
export LOCALVERSION=
that's all
Related
I have a Makefile made by following this example:
cross compile kernel module
I built a 4.14 Linux kernel from an older Xilinx source, and then built a out-of-kernel module with that script, pointing it to the said 4.14 kernel sources, and filling in the blanks for my particular platform architecture.
That worked.
(It's based on this code, if that matters: dma-proxy.c)
Now I need a newer version, and got Xilinx sources with a kernel named 5.6.0-rc1.
(--branch "zynqmp-soc-for-v5.7" from here)
Building that kernel also worked fine.
If I now use a scrubbed clean directory (incl. hidden files) with my module source code and that Makefile again, pointing to the newer kernel sources, it does neither produce a .ko file nor an error message.
All I get is:
make ARCH=arm64 CROSS_COMPILE="aarch64-linux-gnu-" -C /home/sk/src/XILINX/linux-xlnx SUBDIRS=/home/sk/src/XILINX/dma-proxy/driver modules
make[1]: Entering directory '/home/sk/src/XILINX/linux-xlnx'
CALL scripts/checksyscalls.sh
CALL scripts/atomic/check-atomics.sh
MODPOST 28 modules
make[1]: Leaving directory '/home/sk/src/XILINX/linux-xlnx'
No .ko file in my folder as it was before when building with 4.14, and it doesn't list actually compiling anything.
I find it curious that it says "MODPOST 28 modules", whereas with pointing it to kernel 4.14, it expectedly says "1 modules"
Has anything changed between 4.14 and 5.x that would cause this?
Mkay, here is the suggested makefile template by the tutorial I referenced in the question:
PWD := $(shell pwd)
obj-m += hello.o
all:
make ARCH=arm CROSS_COMPILE=$(CROSS) -C $(KERNEL) SUBDIRS=$(PWD) modules
clean:
make -C $(KERNEL) SUBDIRS=$(PWD) clean
Turns out that if I replace SUBDIRS=$(PWD) with M=$(PWD), it works. Now if I google explicitly for that M variable in conjunction with building kernel modules, I do find text that show it that way. But the net is also littered with examples using SUBDIRS, and it worked for me with a fairly recent kernel (4.14).
Then I did find references hinting at this being an old way of doing it, like from here:
make -C $KDIR SUBDIRS=$PWD
Same as M=. The SUBDIRS= syntax is kept for backwards compatibility.
In fact, this seems to be really old, like, kernel 2.6.7 old. Unfortunately, fairly recent tutorials show the old way.
I need to build kernel to have vermagic
3.10.28-gbc1b510-33899-g9fa745e SMP preempt mod_unload modversions ARMv7
but after building and verification some module via modinfo it displays
3.10.28 preempt mod_unload modversions ARMv6
Looks like I can't load module because different vermagic. How to build kernel and modules for vermagic to be axactly the same ?. I'm using buildroot.
I created this shell script in order to prepare for build
#!/bin/sh
export PATH=$PATH:/buildroot-2018.02.3/output/host/arm-buildroot-linux-gnueabi/bin:/buildroot-2018.02.3/output/host/bin:/buildroot-2018.02.3/output/host/sbin:/buildroot-2018.02.3/output/host/bin
export LD_LIBRARY_PATH=/buildroot-2018.02.3/output/host/lib
export LIBRARY_PATH=/buildroot-2018.02.3/output/host/lib
export PKG_CONFIG_PATH=/buildroot-2018.02.3/output/host/arm-buildroot-linux-gnueabi/sysroot/usr/lib/pkgconfig
exec /bin/bash
then I enter folder
/buildroot-2018.02.3/output/build/linux-3.10.28/
and
make distclean
make clean
then copy .config and
make ARCH=arm menuconfig
and
make -j9 ARCH=arm
I'm using original kernel konfig with additionaly selected a few options to build as modules without modifications of any other.
There is linux-3.10.28/arch/arm/Makefile file. In this file there are those defines
arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
I found suggestion somewhere which lead me to replace
arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
with
arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
I olso uncommented these two:
tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
tune-$(CONFIG_CPU_V6K) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
I added
-gbc1b510-33899-g9fa745e SMP
as local_version in kernel .config
and now version string print by modinfo is the same.
Some time ago, I developed a kernel module for ARMv7 (Cortex-A5). This module worked fine, but I needed to add a feature to it. Unfortunately, the machine that had the cross-compiler toolchain installed got repurposed in the mean time, so I had to set it up again. Of course, I found that I hadn't documented all the details, and I have been struggling to get a module that would actually load. After a day or so, I managed to compile something that was accepted by insmod on the target.
But the module does nothing.
insmod does not give me any errors. dmesg doesn't show anything, although the module is supposed to print some info from its probe routine. Also, the character device it's supposed to create does not exist, obviously the module's probe routine didn't run.
If I do modinfo on both the old .ko (which I still have) and new .ko, there are no differences. file also shows the same output, except for the sha1 checksum, which is to be expected:
module_old.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=1f55850e8da4b3b5931536060d62193d94730cf6, not stripped
module_new.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=c3b1f6fdcb72381beb7b8a766c70af7a1252a78f, not stripped
The only difference I see is that the new .ko is about 10x bigger than the old one:
-rw-r--r-- 1 root root 154504 Apr 21 23:38 module_new.ko
-rw-rw-r-- 1 root root 17956 Oct 4 2017 module_old.ko
My Makefile is as follows:
obj-m += mymodule.o
KERNEL_SOURCE_DIR = /home/ludo/linux-at91-linux4sam_5.3
all:
make -C $(KERNEL_SOURCE_DIR) CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm M=$(PWD) modules
clean:
make -C $(KERNEL_SOURCE_DIR) CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm M=$(PWD) clean
I tried adding
CFLAGS_mymodule.o := -march=armv7-a -mtune=cortex-a5
but this made no difference.
I'm building on Debian Jessie (8.10) with gcc 4.9. I do not recall exactly with what GCC version I built the old version, but it was 4.x, not newer.
Any ideas how I can debug this problem?
I forgot to document a very important step in the build process. Before building the module, one needs to ensure that the configuration is consistent. This can be done by executing, from the root of the kernel source tree:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- sama5_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules
Then the module can be compiled and all is good.
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.
I made certain modifications in hid module.
I can make it and load (insmod) it on kernel v 2.6.27.14 sucessfully
Now I am willing to load the same kernel module on kernel v 2.6.27.11
As there is no differance in the kerbel source files for both the kernel versions
I can make it sucessfully, but I cannot add / insmod in this .11 kernel version
**
ERROR: Module myhid does not exist in /proc/modules
insmod: error inserting 'myhid.ko': -1 Invalid module format
**
Regards,
You can't load a module compiled for another kernel version. That the source code of the module did not change does not mean that the binary will be the same for another kernel version. Any interface change of kernel internal APIs (even when not directly visible) will break the module...
Therefore, the kernel stays on the safe side by disallowing loading of modules that were built for another kernel version. Alternatively, you can set the MODVERSIONS configuration option when building your kernel. This will embed version information into all symbols used by your module and with luck you can load it on another kernel version.
If any interface used by your module changed, the result will be the same though.
see what "modinfo" tells you about your module:
Check that it's compiled properly, linked to the right kernel.
$ modinfo hid
filename: /lib/modules/2.6.27.7/kernel/drivers/hid/hid.ko
license: GPL
depends:
vermagic: 2.6.27.7 mod_unload 486
parm: pb_fnmode:Mode of fn key on Apple keyboards (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst) (int)
When you compile/install modules, don't forget that you have to run "depmod" (as root) to rebuild the modules dependancies before running insmod/modprobe.
Thanks ! Here is the make file . I dowload all the dependent source files for HID.O and rename them
MAKEFILE
obj-m := myhid.o
myhid-objs := my-hiddraw.o my-hid-core.o my-hid-input.o my-hid-input-quirk.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules