LOCALVERSION=-tegra - how to differentiate kernels?

Hi,

I need to enable a couple of kernel modules, which are not enabled by default in the tegra kernel. I want to distinguish my ‘custom’ kernel from the standard Tegra kernel (only modules, but resulting in a new /boot/Image too). When I add some specifics to “LOCALVERSION”, kernel doesn’t load. Only works when left empty or set to “-tegra” by default (as the documentation says as well). Could you advice how to add a distinguishing element to uname -r? What’s the recommended way?

Thanks!

If you are only adding modules, then your kernel itself does not need to be “custom”. What you would do is to configure your kernel source to match the running kernel, including matching CONFIG_LOCALVERSION to be “-tegra”. Then you would use a dependency-aware editor, e.g., menuconfig or nconfig (my favorite since it has symbol search), and build. The modules which you add from your customization would be simple file copies to the appropriate subdirectory of:
/lib/modules/$(uname -r)/kernel/

The base kernel (the Image file) knows what its base version is, as well as it’s CONFIG_LOCALVERSION. For example, if the kernel source is 5.15.0, and you compiled it with “CONFIG_LOCALVERSION=-tegra”, then it would respond to “uname -r” with “5.15.0-tegra”. Any module compiled under those same settings can load into that kernel. There is no need to change the Image.

If you were to change an integrated feature of the Image (meaning changing something with the “-y” config instead of “=m”), then you risk modules which originally worked not being able to load. In that case you would change CONFIG_LOCALVERSION to something like “-new” (or better yet, named after the change). You would then require installing the entire kernel and module set. The new “uname -r” would turn into “5.15.0-new”, and modules would be searched for at “/lib/modules/5.15.0-new/kernel/”.

Keep in mind that you can have boot entries for the original Image, plus maybe you’ve added “Image-new” to “/boot” (and modules to the new module location). The boot entry will gladly load either Image or Image-new. There is no requirement to remove the old kernel, but you do have to point to the kernel you are going to use.

Incidentally, after you copy a module file to the correct subdirectory of “/lib/modules/$(uname -r)/kernel/” you would run “sudo depmod -a”. Then either the module load or reboot and it should “just work”.

2 Likes

This is really helpful, thanks a lot. You’re right I likely don’t need to have a new Image at all. I thought so since after make menuconfig(I’ll try nconfig too!) and enabling the required modules (all ‘M’ as far as I recall) a make did result in a new Image too, with make install copying that to /boot. But it ought not to be different, true.

(Yes, I put an Image.backup there for fallback and a second boot entry listed in /boot/extlinux/extlinux.conf, so I can boot either Image).

But I guess you’re right even though a new Image is built from source (and it’s different in size than the original) if it’s all M modules, it should actually be the same kernel and then it’s just copying the modules. I’ll try “sudo depmod -a”!

I often build Image as the target as a kind of “acid test”, once for a given build, even if I’m not going to use the Image. Then I build modules. Incidentally, building Image has a side-effect many people do not think about when they start building kernels: This also propagates all of your configuration throughout the source tree.

If you start with purely clean source (using “make mrproper”), then set up config in whatever method, you wouldn’t be able to compile modules as a next step. However, you can run “make modules_prepare”. This will propagate the configuration. Since you’ve run “make Image”, you’ve done more work than is needed, but this also (A) tested the validity of your configuration, and (B) propagated the configuration throughout the source using the Kconfig mechanism.

1 Like