Yocto: kernel modules not showing up in the rootfs

Introduction

This work is sponsored by Reliable Embedded Systems. You can find more information about our training/consulting services here.

Objectives

The goal of this blog post is to point out a well known and documented issue with kernel modules not ending up on the root file system which is likely overseen by people until they stumble over it.


 

Kernel module(s)

So you created a brand new kernel module, or you just wanted to include all the kernel modules in the root file system, or just one of them.

You reach out to the community mailing list or chat with something like this:

I have
MACHINE_EXTRA_RRECOMMENDS += "kernel-modules"
in my machine configuration. 
When I look into the rootfs I see no modules installed in /lib/modules/$(uname -r). 
I get only a modules tarball in the deploy directory.
I also tried 
MACHINE_EXTRA_RDEPENDS += "kernel-modules"
and it still does not work.
What am I doing wrong?

Check the Mega Manual

If things don't work as expected check out to good old Mega Manual, which you should read every night before falling asleep. And don't forget to have the BitBake manual as well handy (which is not part of the Mega Manual).

MACHINE_EXTRA_RRECOMMENDS

A list of machine-specific packages to install as part of the image being built that are not essential for booting the machine. The image being built has no build dependency on this list of packages.

This variable affects only images based on packagegroup-base, which does not include the core-image-minimal or core-image-full-cmdline images.

This variable is similar to the MACHINE_EXTRA_RDEPENDS variable with the exception that the image being built does not have a build dependency on the variable's list of packages. In other words, the image will build if a file in this list is not found.

An example is a machine that has WiFi capability but is not essential For the machine to boot the image. However, if you are building a more fully-featured image, you want to enable WiFi. In this case, the package containing the WiFi kernel module will not be produced if the WiFi driver is built into the kernel, in which case you still want the build to succeed instead of failing as a result of the package not being found. To accomplish this, assuming the package for the module was called kernel-module-examplewifi, you would use the following in the .conf file for the machine:

     MACHINE_EXTRA_RRECOMMENDS += "kernel-module-examplewifi"

MACHINE_EXTRA_RDEPENDS

A list of machine-specific packages to install as part of the image being built that are not essential for the machine to boot. However, the build process for more fully-featured images depends on the packages being present.

This variable affects all images based on packagegroup-base, which does not include the core-image-minimal or core-image-full-cmdline images.

The variable is similar to the MACHINE_EXTRA_RRECOMMENDS variable with the exception that the image being built has a build dependency on the variable's list of packages. In other words, the image will not build if a file in this list is not found.

An example is a machine that has WiFi capability but is not essential for the machine to boot the image. However, if you are building a more fully-featured image, you want to enable the WiFi. The package containing the firmware for the WiFi hardware is always expected to exist, so it is acceptable for the build process to depend upon finding the package. In this case, assuming the package for the firmware was called wifidriver-firmware, you would use the following in the .conf file for the machine:

     MACHINE_EXTRA_RDEPENDS += "wifidriver-firmware"

IN_PLAIN_ENGLISH

A bit exaggerated:"If the weather is right, the moon is in the seventh house and the image is not too small BitBake will take those variables into account, otherwise - Nope."

So the reason it didn't work is, that you built something like core-image-minimal or core-image-full-cmdline and tried to include kernel-modules via the variables like MACHINE_EXTRA_RRECOMMENDS or MACHINE_EXTRA_RDEPENDS, as mentioned above.

Solution

Use a different variable. Maybe something like:

MACHINE_ESSENTIAL_EXTRA_RDEPENDS

A list of required machine-specific packages to install as part of the image being built. The build process depends on these packages being present. Furthermore, because this is a "machine-essential" variable, the list of packages are essential for the machine to boot. The impact of this variable affects images based on packagegroup-core-boot, including the core-image-minimal image.

This variable is similar to the MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS variable with the exception that the image being built has a build dependency on the variable's list of packages. In other words, the image will not build if a file in this list is not found.

As an example, suppose the machine for which you are building requires example-init to be run during boot to initialize the hardware. In this case, you would use the following in the machine's .conf configuration file:

     MACHINE_ESSENTIAL_EXTRA_RDEPENDS += "example-init"                    

What if you don't want all in-tree kernel modules?

If you do something like this:

MACHINE_ESSENTIAL_EXTRA_RDEPENDS += "kernel-modules" 

You will actually get all kernel-modules into your root file system, which might not be what you want.

You might wonder how to include a single kernel module, no matter if in-tree or out of tree. Well kernel-modules is a meta package which is somehow magically created and contains all the kernel modules. Each kernel module is in a single package as well.

Something like this:

student@e450-tr1:/workdir/build/multi-v7-ml-virt/tmp/deploy$ find | grep kernel-module
./ipk/multi_v7_ml/kernel-module-at91-can-5.4.47-custom-ml-virt_5.4.47-custom-ml-virt+git0+fd8cd8ac94-r0.4_multi_v7_ml.ipk
./ipk/multi_v7_ml/kernel-module-led-class-flash-5.4.47-custom-ml-virt_5.4.47-custom-ml-virt+git0+fd8cd8ac94-r0.4_multi_v7_ml.ipk
...
./ipk/multi_v7_ml/kernel-module-qt1070-5.4.47-custom-ml-virt_5.4.47-custom-ml-virt+git0+fd8cd8ac94-r0.4_multi_v7_ml.ipk
./ipk/multi_v7_ml/kernel-module-xt-length-5.4.47-custom-ml-virt_5.4.47-custom-ml-virt+git0+fd8cd8ac94-r0.4_multi_v7_ml.ipk
./ipk/multi_v7_ml/kernel-module-ebt-ip-5.4.47-custom-ml-virt_5.4.47-custom-ml-virt+git0+fd8cd8ac94-r0.4_multi_v7_ml.ipk
student@e450-tr1:/workdir/build/multi-v7-ml-virt/tmp/deploy$ 

So instead of kernel-modules you could just include "kernel-module-led-class-flash" if that's what you wanted.

Conclusion

Read the fine print carefully. In the Mega Manual things are not highlighted in bold like I did it here so might not notice it. And believe me, you are not the first one who stumbled over this problem. In the bad old days it was even worse, since MACHINE_EXTRA_RRECOMMENDS actually pulled in kernel-modules also on something like core-image-minimal or core-image-full-cmdline, but this behavior was changed way back with the Morty Release in Nov 2016 if I remember well.

Comments

Popular posts from this blog

Yocto: BitBake and Dependencies - e.g. One recipe to use output of another recipe

Compiler tunes benchmarks with the Yocto Project