How to specific kernel version magic?

I build one kernel module base on Linux_for_Tegra/kernel/kernel_headers.tbz2
But Failed to install it. the error message is “Invalid module format”
the kernel debug message show:
globalmem: version magic ‘4.4.38-tegra SMP preempt mod_unload aarch64’ should be ‘4.4.38+ SMP preempt mod_unload aarch64’

Sorry, I 'm very new for kernel develop, Any guide to fix it?

Did you compile this natively on the TX2, or from a cross compile on a host PC? Usually module format would imply it is the wrong architecture.

Compile this with cross compile on a host pc.

What was your actual compile command? And for the “.config”, what is the “CONFIG_LOCALVERSION”? On the running TX2, what do you see for “uname -r”?

Hi 27653276,

For ensuring you are properly cross compiling your module I suggest taking a look into this wiki (just make sure to use the kernel source and toolchain versions accordingly for the L4T release you are using):

Hope the info helps,

Hi RidgeRun,

Thank you very much for your information.
It is very cleared to describe compile&flash steps on Nvidia TX1/TX2.

Thanks,
Martin

Hi Linuxdev,

Please take a look the following:

Compile command:
make ARCH=arm64 -C /home/myuser/64_TX2/Linux_for_Tegra/kernel/local_src_dir/linux-headers-4.4.38-tegra O=TEGRA_KERNEL_OUT M=(pwd) modules

for the “.config”,
CONFIG_LOCALVERSION=""

nvidia@tegra-ubuntu:~$ uname -r
4.4.38+

I also post my module source here.

ch7.tar.gz (1.85 KB)

Note that if your running system results in a “uname -r” output of “4.4.38-tegra”, then CONFIG_LOCALVERSION must be “-tegra”, otherwise the module won’t be found:

CONFIG_LOCALVERSION="-tegra"

To explain, the base kernel version is “4.4.38”, and CONFIG_LOCALVERSION is appended to this and embedded into the running kernel. The “uname -r” command with “-tegra” reflects this kernel’s settings at the time of its compile. Modules are searched for at:

/lib/modules/$(uname -r)/

Even if you compiled your module correctly it will mismatch the “uname -r”.

For your actual compile command, if you only specify ARCH=arm64, and don’t specify the cross tool chain prefix which works with that architecture, then the wrong compiler will be used. You can specify this in an environment variable, but most likely this did not occur. You will need to specify the prefix to the cross tool chain and assign it to “CROSS_COMPILE=”. Example from a Fedora system (path will differ for you):

make ARCH=arm64 <b>CROSS_COMPILE</b>=/usr/lib64/ccache/<b>aarch64-linux-gnu-</b>

Note that this is the path because I have this file for the cross architecture version of gcc:

/usr/lib64/ccache/aarch64-linux-gnu-<b>gcc</b>

When the compiler looks for “gcc” it prefixes “CROSS_COMPILE”.

my running system results in a “uname -r” output of “4.4.38+”, is not “4.4.38-tegra”.

The module version magic that I build is “4.4.38-tegra” based on Linux_for_Tegra/kernel/kernel_headers.tbz2
By the way, I set environment variable “CROSS_COMPILE=xxx” before build the module.

I should set CONFIG_LOCALVERSION to “+”?

Can you explain how is the generate “4.4.38+” in the kernel source code?

Ahh, that is the pesky “scm” version. Take a look at this file in the kernel source:

scripts/setlocalversion

Find function “scm_version()”. Edit this to force return after variable declaration:

scm_version()
{
        local short
        short=false
        <i><b>**return**</b></i>

This will remove the “+”. From then on you can set “CONFIG_LOCALVERSION” for the actual suffix. To do the equivalent of “+” after removing it from scm_version():

CONFIG_LOCALVERSION="+"

(or it could be “-tegra” if that is what the original “uname -r” responds with as a suffix)

Because your running system has a “uname -r” of “4.4.38+” this implies that if you have either the scm_version or the CONFIG_LOCALVERSION set to be “+”, then the module you build should have the right version if other things are correct, e.g., if you are using the aarch64 cross tools (module and running kernel will have matching “uname -r” expectations).

If the “uname -r” resulting from a kernel build (or modules built in that configuration) do not match, then there is a problem. A system with “uname -r” of “4.4.38+” searches for modules at:

/lib/modules/4.4.38+/

A module compiled during configuration for “4.4.38-tegra” wants to be found in:

/lib/modules/4.4.38-tegra/

Note that the goal is that the configuration during the build of the original Image (4.4.38+) also be used during the build of any module intended to work with a “uname -r” of “4.4.38+”.

1 Like

Hi Linuxdev,

Thank you for your support, I have install the module sucessfully.

Thanks,