I am using the Elroy Carrier with TX2i system. I have installed the 32.2.1 Board Support Package, which resulted in the kernel version (uname –r) being upgraded from “4.9.140-tegra” into “4.9.140-tegra+”, which I assume is expected behavior.
Afterwards, I tried compiling a module from its source code using “sudo make”. It was being compiled without problems before the BSP had been installed. However, after installing the BSP, the “sudo make” command complained about the “/lib/modules/4.9.140-tegra+/build” being a broken symlink (/usr/eadams/trunk_tx2_32.2.1/tegra_kernel_out), therefore I tried copying the symlink from the previous kernel version into the new kernel version. In other words, “/lib/modules/4.9.140-tegra/build” symlink goes into “/lib/modules/4.9.140-tegra+” folder and overwrites the broken symlink. I ran “sudo make” to compile the module again. It compiled successfully. When I inpected the newly compiled module using “modinfo ***” the vermagic line suggested that the newly compiled module is only compatible with “4.9.140-tegra” due to being compiled using the old linux headers. I have tried running the module with “modprobe ***”, and it complained about vermagic inconsistency with the “uname -r”. Therefore, I have tried “modprobe *** -force” in order to ignore the vermagic, expecting it to maybe work, however this time it threw an “exec format error”, implying the newly compiled module is not suitable to be run on the new kernel version no matter what.
From this, I assume that my only solution would be to obtain proper linux kernel headers, that is compatible with the “TX2 L4T r32.2.1 BSP”. Are these header files available to be downloaded from somewhere? I could not find them from the Connect Tech site. Is Connect Tech the only source from which I may expect to obtain these header files? Is there a method through which I can generate these header files?
If they are not available, what would you suggest me to do in order to be able to compile the module successfully?
Sorry for what will be an oblivious question but what do I do with the kernel source in order to obtain the kernel headers? Does it also apply to an “upgraded” kernel (the one where + is appended to the “uname -r”) that is obtained from applying a BSP on a working system?
Like I have explained in the post, I have the source code of a driver for some hardware that I intend to use, the compilation and installation process explained in the “readme.txt” simply suggests me to “sudo make” which ends up with the “/lib/modules/4.9.140-tegra+/build” directory being accessed, which points to nothing. I understand that the header files for the “4.9.140-tegra+” is different from “4.9.140-tegra”, and I need the header files for the former, rather than the latter, is that not true? Am I misunderstanding my goal?
If that’s the case then why does placing the “/lib/modules/4.9.140-tegra/build” symlink into the “/lib/modules/4.9.140-tegra+” folder not work? After doing this the building process completes successfully, but I can not run the resulting module file.
It gets placed into the correct directory, and gets accessed successfully while using modprobe, but does not run, even while using the “–force” option which ignores the mismatch between module vermagic value and uname -r.
using modprobe WITHOUT --force:
modprobe: ERROR: could not insert ‘ngrabber’: Invalid argument
these 4 lines also show up in dmesg:
ngrabber: disagrees about version of symbol _dev_info
ngrabber: Unknown symbol _dev_info (err -22)
ngrabber: disagrees about version of symbol _dev_err
ngrabber: Unknown symbol _dev_err (err -22)
using modprobe WITH --force:
modprobe: ERROR: could not insert ‘ngrabber’: Exec format error
nothing shows up in dmesg.
FYI, the above suggests the configuration has changed and old modules won’t work with the new configuration. The location where a kernel searches for modules (and you have a custom kernel) is compiled into the kernel itself. That location is: /lib/modules/$(uname -r)/kernel
Run command “uname -r”, and you will see “4.9.140-tegra+”, where the 4.9.140 is the base kernel version, the “-tegra” is likely from config item “CONFIG_LOCALVERSION=-tegra”, and the EXTRAVERSION is enabled to append the “+”. For it to work with old modules you’d want to start with an exact match of kernel configuration, and match the original “CONFIG_LOCALVERSION=-tegra”, but remove the EXTRAVERSION. You could then add features with something like “make menuconfig”. This would mean module search would be in the original “uname -r” location of “4.9.140-tegra” (without the “+”), and the actual modules would be compatible (you can’t just copy modules across all configurations because the binary loading has expectations which might change when the wrong config is changed). Fixing that would mean no need for “/lib/modules/4.140-tegra+/”.
The official kernel source from NVIDIA does not enable EXTRAVERSION. This is common though for some externally supplied kernel software. If you look at your kernel build location and examine the “Makefile”, do you see a line such as this? EXTRAVERSION = +
Remove the “+” and just leave it as: EXTRAVERSION =
Be sure to completely clean any previous build source with something like “make mrproper”, and install a new kernel which started as an exact match to what the stock system was built with. You can do this via “make tegra_defconfig” if “CONFIG_LOCALVERSION” was set to “-tegra”, and then you could optionally add features via modules and know the configuration would be compatible with the original modules at: /lib/modules/$(uname -r)/kernel
Two things would happen:
The modules already in place at "/lib/modules/4.9.140-tegra/kernel would have binary compatibility and versioning that kernel.
The kernel would search for modules using the “uname -r” of “4.9.140-tegra” instead of “4.9.140-tegra+”, so those modules would be found. You wouldn’t need to build or install any replacement modules, whereas the way you now have it you must build and reinstall all modules.