Install linux headers for kernel module development

I’m trying to compile v4l2loopback, a kernel module to allow for virtual video devices. ResinOS seems to be missing the build dir inside the kernel directory. Is there a way to install the headers on Resin? Could I add them to the SD card?

Hi @CWright017,

Our current recommended approach is to use this project template. If you want to test it, the steps are:

@lekkas thank you that’s amazing. Upon building the module, it has a Makefile with an install location of /lib/modules/build… but when I tired building the module in a separate docker file and copying it over to my resin container - that location was either missing or read only. Will this approach solve that?

hi @CWright017 ,

The module build and install process will take place on our builders and the resulting module should end up under /lib/modules/$(shell uname -r)/build in the generated container image. So yes, adapting the template project and the respective example template Makefile to your own kernel module should work.

@lekkas thanks for the update! Module build worked fine, I copied the build.sh script to my own project - although there is no /lib/modules/$(shell uname -r)/build dir only a /lib/modules/$(shell uname -r) dir, so using modprobe won’t work, but insmod seems to work fine.

I was just wondering, is the lack of build dir a raspian base image thing? Or have I missed a step?

Hi @lekkas ,

I’m currently experiencing a related issue. I followed the ‘kernel-module-build’ example, and successfully built my out-of-tree module into a my_module.ko file.

Installing the module with insmod my_module.ko causes a subsequent lsmod command to list ‘my_module’, but modprobe my_module fails to find the module, stating:

modprobe: FATAL: Module my_module not found.

I suspect this is related to an inability to access the /lib/modules/ due to its ‘read-only filesystem’ permissions, which prevents me from running depmod -a or otherwise copying/linking my module into the appropriate directory.

Is there a workaround that would allow me to properly install and load the module during startup of the container?

I’m having exactly the same problem. depmod can’t run due to read-only filesystem.

I’ve since resolved my issue. Running insmod $mod_dir/my_module.ko successfully loads the module. You will also need to load any dependencies with insmod directly. You cannot use modprobe or depmod.

1 Like

OK, so its no problem if modprobe thinks the module isn’t installed?
Why is it that we can’t use modprobe and depmod? Is it possible to do all the work of modprobe using just insmod?

It wasn’t a problem for me. I’m able to utilize my module after insmod even though modprobe fails.
You can also restart the module with rmmod my_module followed by insmod.
My understanding regarding the file permissions is that resin constrains what’s accessible and modifiable by the end user after the build steps (even during the build steps), for stability and security reasons. You can start reading up on specifics here.

insmod is what should be used indeed for custom built out-of-tree kernel modules. modprobe can be still useful in other cases though, but the module has to be already registered when the OS image is built.

As for the read-only filesystem - it also reduces the chance of SD card corruption due to various reasons like power failures, etc.

For

./build.sh build --device beaglebone-green-wifi --os-version 2.58.3+rev4 my_module

I keep getting an error that headers aren’t found.

I did a list and will try --device beaglebone-black --os-version 2.58.3+rev4.dev.

Is there a reason the latest versions aren’t there for all devices? Is it OK to just use --device beaglebone-black? I mean, it should be the same kernel.

The module built using beaglebone-black headers, but I’m getting funny behavior where the iio subsystem stops responding. Is this the same kernel as for beaglebone-green-wifi?

BTW, I’m not able to tell what beagleboard patch-level a kernel is at using uname -a. The 5.4.70-ti kernel is now at r20. It could be possible just to submit the patches I need to the beagleboard kernel.

Hi Jason,

The kernel headers are published and available for the versions that are listed in the dashboard for image download. For the Beaglebone Green Wireless the 2.58.3+rev4 headers are currently available only in staging, so you can switch “cloud” to “staging” in https://github.com/balena-os/kernel-module-build/blob/93da0fefec03692c0b5a819355d599b449b9c5c7/build.sh#L5 to get the headers from there.

Yes, all beaglebone use the same kernel, and 2.58.3+rev4 uses the kernel revision 5.4.70-ti-r19, as visible here.

Do you need us to update to r20? Also, if you have some kernel module that you need in the OS and it is public, sure, you are welcome to PR it in the balena-beablebone repository.

Please update to r21. I think there is already an effort to do so.

Hi @jkridner,

v2.65.1+rev2 is now available in the staging dashboard for the Beaglebone Black and includes r21 as well as the HM3301 module, let us know if it works for you and we can bring it in production too.

Awesome, thanks! Oh, btw, this is for BeagleBone Green Gateway, currently identified as BeagleBone Green Wireless in the production system.

BTW, I’m still getting the error I mentioned in Update to custom OS version or kernel (confused by error in cloud dashboard). So, I really don’t know how to trigger an update. I’ll see if it is possible in the staging server.

@jkridner I deployed it for the Gateway in staging too, it’s already there at the same 2.65.1+rev2 version. The Gateweay board is scheduled to arrive on Wednesday, as soon as it arrives we can bring that one in production too.

Regarding the error you see, maybe you are trying to perform an update on a device that has the Beaglebone Gateway image flashed but it’s running in the production dashboard, where this new device type is not available yet?

I used the process at https://www.balena.io/docs/learn/more/masterclasses/advanced-cli/ to move one of the (local) device to the staging server. The 2.65.1+rev2 update was then available in the GUI. Thanks!

For remotely deployed devices, is there a process for performing the ‘leave’ and ‘join’ operations on them?

Hi @jkridner, unfortunately once you perform the leave operation, the device becomes inaccessible. There is an option to replace the config.json on a remote device with one downloaded from the staging app dashboard, but this carries a lot of risk of putting the device in a bad state if anything goes wrong.

Here’s some info on working with the config json:

We do plan on deploying the new kernel to production, is this something that can wait until then?