Loadable Kernel Module issue on Debian 19.01 Release

To cross-compile latest kernel I just followed the instructions on
https://releases.linaro.org/96boards/dragonboard410c/linaro/debian/latest/
as I needed specific modules I choosen then using make menuconfig on host computer to customize .config

After loading the new kernel with fastboot, the make command correctly compiled the LKM generating object files:

$ make
make -C /lib/modules/4.14.0-qcomlt-arm64/build M=/home/linaro/Desktop modules
make[1]: Entering directory '/usr/src/linux-headers-4.14.0-qcomlt-arm64'
  CC [M]  /home/linaro/Desktop/mymodule.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/linaro/Desktop/mymodule.mod.o
  LD [M]  /home/linaro/Desktop/mymodule.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.14.0-qcomlt-arm64'

But when trying to perform insmod, it is not working:

$ sudo insmod mymodule.ko
insmod: error inserting 'mymodule.ko': -1 Invalid module format

Using dmesg I found the issue:

[ 66.415846] mymodule: version magic '4.14.96 SMP preempt mod_unload aarch64' should be '4.14.0-qcomlt-arm64 SMP preempt mod_unload aarch64'

I tried to recompile Kernel modifying the KERNELRELEASE argument during make but did not work.

Please, someone has any idea on how to solve this issue ?

The simplest thing to do it to compile the modules against the headers of your kernel instead of using the 4.14.0-qcomlt-arm64 headers. Can you cross-compile mymodule instead?

You can try passing KERNELRELEASE argument for your module make command as below:

$(MAKE) -C $(KDIR) M=$$PWD modules KERNELRELEASE=4.14.0-qcomlt-arm64

Original Makefile:

obj-m += mymodule.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 tried your suggestion, follows Makefile:

KDIR := /usr/src/linux-headers-4.14.0-qcomlt-arm64

obj-m += mymodule.o
all:
	$(MAKE) -C $(KDIR) M=$(PWD) modules KERNELRELEASE=4.14.0-qcomlt-arm64

clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Unfortunately the output was the same when inspecting dmesg:

mymodule: version magic '4.14.96 SMP preempt mod_unload aarch64' should be '4.14.0-qcomlt-arm64 SMP preempt mod_unload aarch64'

Is the expected $KDIR value correct ?

Now I understood how to perform the cross-compiling of the module, follows the steps to be performed on host computer:

Step 1)
extracted the gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz downloaded from Linaro to /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu

Step 2)
$ export PATH="/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin:$PATH"

Makefile source code

PWD := $(shell pwd)
obj-m += mymodule.o

all:
        make ARCH=arm64 CROSS_COMPILE=$(CROSS) -C $(KERNEL) SUBDIRS=$(PWD) modules
clean:
        make -C $(KERNEL) SUBDIRS=$(PWD) clean

Compiling
make KERNEL=/home/host_computer/Desktop/kernel CROSS=aarch64-linux-gnu-

The kernel folder is the one obtained throught git clone on host computer

Sending module to db410c
$ scp mymodule.ko linaro@IP_OF_DB410C:~/Desktop

Running module on db410c

$ sudo insmod mymodule.ko
$ sudo rmmod mymodule
$ dmesg | tail
[ 2263.856533] Registering Simple Filter.
[ 2280.432232] Simple Filter is being removed.

Reference:
https://blukat29.github.io/2017/12/cross-compile-arm-kernel-module/

The cross-compiling approach seems as a workaround for the issue:

[ 66.415846] mymodule: version magic '4.14.96 SMP preempt mod_unload aarch64' should be '4.14.0-qcomlt-arm64 SMP preempt mod_unload aarch64'

From rebuild instruction (debian/latest):

  • Kernel package name: linux-image-4.14.0-qcomlt-arm64
  • Kernel package version: 4.14.96-00726-g8bdd343f96dc-45

Unfortunately, I am not proficient enough to understand why the Kernel rebuild presented this conflict :cry:

Glad to hear you got this working.

To some extent consider this a case of learning the rules before learning how to break them!

Kernel modules are only guaranteed to work when compiled against the headers (including the config headers that are automatically generate during things like menuconfig and friends). Changing the configuration can change the binary interfaces used by the kernel and therefore influences whether the module will load-and-work, load-and-break or fail-to-load. Hence in general the rule is use the headers for your kernel.

It is true there are ways to bend this rule a bit (proprietary kernel modules in particular often to this) but there are some nasty gotchas meaning whilst experts could break the rule many will choose not to!

Daniel,
Thank you for you support, more questions just for learning purpose:

On previous attempts I had performed the linux headers download:

$ sudo apt-get install linux-headers-4.14.0-qcomlt-arm64

Also performed the modules copy and paste from host computer (responsible for build) to DB410c /lib/modules.

Also had confirmed that .config file on /usr/src/linux-headers-4.14.0-qcomlt-arm64 at db410c is with the configuration from make menuconfig on host computer.

It still seems inexplicable the reference to kernel reference to 4.14.96 as error for “normal” make procedure.