Kernel module from TX2 is not working in Nano

Hi,
The kernel module worked (insmod-ed) in Jetson TX2, is not working in Jetson Nano. Both are same architecture.

Could you please let me know, is there any difference between two?
insmod: ERROR: could not insert module cfg80211-tx2.ko: Invalid module format

My expectation was no need to rebuild the module. But it is not the same. In there difference in cross-compiler?

Ubuntu 18.04.3->tx2; nano: 18.04.4.

Thanks.

There are differences (e.g., the module loader software itself), but I couldn’t tell you for sure about your case. You would always want to recompile it anyway since these are directly inserted into the kernel and may involve different address offsets from one kernel to the next. Even on a single kernel on the same system a load of the same module against a kernel compiled with different features would probably fail. For this to succeed your kernel config itself would need to be an exact match between the two systems (changing the config on a running system could invalidate every module currently being used…across two different computers this is quite likely).

OK. But the module, that I built on Nano, itself showing the error insmod: ERROR: could not insert module <module.ko>: Invalid parameters. Nano supports loadable modules right?

The same module built on tx2, worked in TX2.

Yes, Nano is like any other Linux system and supports modules. However, you’ve misinterpreted the meaning of this:

Every program, even kernels and functions within kernels, can be passed arguments (at least in C, which is what we are talking about). Some programs must be passed arguments, or particular arguments, and this is just the programmer’s choice. That error indicates module load works (as a mechanism), but that something needed in addition to the module is missing.

An example which most people would not expect is for a module acting as a driver to a non-plug-n-play hardware. A driver must know the physical address of the hardware it is talking to, and for non-plug-n-play, this tends to mean the device tree passing that information. Whenever a module (or any driver) loads it is given a chance to read the content of the device tree. Parameters not “compatible” with your driver are ignored (there is a “compatible” section in most device tree nodes naming which drivers will be interested in the data). That data includes the physical address. If you require a physical address to find the hardware, then the driver will fail due to lack of being passed a physical address as an argument.

Often the same thing goes on with the kernel command line…everything has the ability to see the kernel command line during kernel startup (and a module loading is a part of the kernel starting up). Those arguments a driver does not care about are ignored, and only arguments the particular module or driver cares about will actually be used.

Also consider that it is possible the module might be looking for the output result of another module, e.g., an encryption module might provide a key, and if that function is not enabled in your kernel, then there would be a failure to pass the key to the module you are loading. It is a tree of dependencies for this case, and not a physical address being passed. It is an example of how missing another module can invalidate a seemingly unrelated module.

Perhaps you need a device tree change? Depends on what the missing argument is. To know this you’d have to research the driver requirements. On the other hand, if you just built the module against the other system, the Kconfig system can be used to make sure you have all of the kernel feature dependencies. This wouldn’t tell you about a device tree requirement since that is a runtime requirement, but it would certainly narrow down the failure.