Building External Kernel Modules With Torizon
Introductionβ
It is often necessary to add a kernel module to a Torizon OS image. There are two possibilities:
- Add a kernel module that is available in the kernel source, or in-tree. In this case, please make a request in our community. If you tell us the exact kernel config that must be enabled and it does not have a negative impact on Torizon OS, we'll add it as a module.
To check whether a given kernel config is already enabled, you can simply check the kernel config of a module running Torizon OS (zcat /proc/config.gz
) or you can search for the configuration on the toradex-kernel-cache repository, which stores the kernel config for official Torizon OS images. When searching in the repository, be sure to choose the correct branch for your Torizon OS version.
- Add an out-of-tree kernel module, in other words, a module that is external to the Linux kernel source tree. In this article, you will learn how to do it.
Some examples where this is necessary:
- When adding support to some device/peripheral you're using.
- When including some proprietary code.
You'll need to compile the kernel module's source code against the kernel source to make it compatible.
The typical way to do this in embedded Linux would be to add your kernel module via the Yocto Project/OpenEmbedded build system. However, this requires quite a bit of knowledge, and as we deliver Torizon OS as a binary distribution, we try to simplify this process greatly in a way that you don't need to fall back to a Yocto build.
This article complies with the Typographic Conventions for Torizon Documentation.
Pre-requisitesβ
The pre-requisite to complete these instructions are:
- Prerequisites from Configure Build Environment for Torizon Containers installed.
- A Toradex SoM with Torizon installed.
- Having read the Torizoncore Builder - Getting Started article can be helpful.
- A Torizon OS image downloaded.
- Source code for whatever kernel module you want to build. We will provide an example code in the exercise below.
Installing TorizonCore Builderβ
To install TorizonCore Builder, read our statements on OS and shell compatibility, then follow the instructions below, in order.
Download the setup script into some writable directory in your system (here we use
~/tcbdir/
):$ mkdir -p ~/tcbdir/ && cd ~/tcbdir/
$ wget https://raw.githubusercontent.com/toradex/tcb-env-setup/master/tcb-env-setup.shnoteIf you did this before then you can skip this step unless you want to update the setup script. When you source the script (next step) it will show you a warning message if it determines an update is advisable.
Source the script:
For usage with direct network connections:
$ cd ~/tcbdir/
$ source tcb-env-setup.sh(With TorizonCore Builder 3.13.0+) For usage with a (non-transparent) proxy server, make sure your Docker client is configured accordingly (see Docker proxy configuration) and source the script passing extra information about your proxy (adjust the variables to your needs):
$ cd ~/tcbdir/
$ source tcb-env-setup.sh -- \
--env HTTP_PROXY="http://proxy.example.com:3128" \
--env HTTPS_PROXY="https://proxy.example.com:3129" \
--env NO_PROXY="*.test.example.com,.example.org,127.0.0.0/8" \
--env DIND_FORWARD_VARS=HTTP_PROXY,HTTPS_PROXY,NO_PROXY
Make sure to do this from every shell instance that you intend to use with TorizonCore Builder. For advanced usage, run
source tcb-env-setup.sh -h
, or see the project README. The latter has information about using the early-access version of the tool for those interested.tip- Remember to source the setup script every time you start a new terminal (or shell instance).
- The setup script installs a Bash completion script for TorizonCore Builder, making it possible to autocomplete commands and parameters by just pressing the TAB key.
Beware that under Windows, you must pass extra parameters to the script when the use of the following commands is intended:
ostree serve
: consult the ostree serve reference.
Verify that the command
torizoncore-builder
is available:$ torizoncore-builder --help
Hello World Kernel Module Exampleβ
Begin by organizing your kernel module source code into a single directory; let's call this your hello-mod
. At a minimum, your source code should have at least one source C file and one Makefile.
To get the kernel module example, called hello-mod
, from our Github repository, run the command below:
$ git clone https://github.com/toradex/hello-mod
Ihe files below are the source C file and the Makefile, respectively, contained in this hello-mod
example:
#include <linux/module.h>
int init_module(void)
{
printk("Hello World!\n");
return 0;
}
void cleanup_module(void)
{
printk("Goodbye Cruel World!\n");
}
MODULE_LICENSE("GPL");
Take extra notice of the Makefile. In particular, notice the environment variable $(KERNEL_SRC)
. The TorizonCore Builder tool uses this variable, so include this in your Makefile as shown below. Alternatively, you can also use $(KDIR)
instead. You do not need to define both these variables, but including at least one is mandatory.
obj-m := hello.o
SRC := $(shell pwd)
all:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules
clean:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC) clean
Development and Production: Add External Kernel Modules with TorizonCore Builderβ
Applying an External Kernel Module to a Custom Imageβ
There are two possible approaches to apply the customization and generate a custom Toradex Easy Installer image, described in the next two sections Approach 1 and Approach 2. These approaches in some cases are interchangeable and in some not as described in the next sections.
To learn about TorizonCore Builder workflow and the different approaches to use the tool, with explanatory diagrams, please refer to the TorizonCore Builder - Workflow article.
Both approaches generate a custom Toradex Easy Installer image as output, so the approaches should be followed alternatively and not in sequence.
Approach 1: Applying an External Kernel Module to a Custom Image Using the Build Commandβ
TorizonCore Builder build command generates a custom Torizon OS image with the external kernel module built, ready to be installed with Toradex Easy Installer, named torizon-core-docker-colibri-imx6-Tezi_5.3.0.CUSTOM
in the example below. This is achieved using a configuration YAML file, tcbuild.yaml
as default.
This is the recommended approach on production programming and on CI/CD (continuous integration / continuous development) pipelines.
To learn about TorizonCore Builder workflow and the different approaches to use the tool, with explanatory diagrams, please refer to the TorizonCore Builder - Workflow article.
It requires a Toradex Easy Installer image of Torizon OS (preferably without containers), torizon-core-docker-colibri-imx6-Tezi_5.3.0+build.7.tar
in this case, as input. The directory with the kernel module source code is passed as customization: kernel: modules: source-dir
.
# Sample configuration file:
input:
easy-installer:
local: images/torizon-core-docker-colibri-imx6-Tezi_5.3.0+build.7.tar
# Sample customization: build hello-mod module into the image
customization:
kernel:
modules:
- source-dir: hello-mod/
autoload: no
output:
easy-installer:
local: torizon-core-docker-colibri-imx6-Tezi_5.3.0.CUSTOM
Notice the kernel: modules: autoload
parameter of the hello-mod
kernel module defined to no
. This means that the kernel module will not be automatically loaded on boot time. To enable loading on boot time just change this parameter to yes
.
The directory with the kernel module source code hello-mod should be available before running the build
command.
Build The Custom Imageβ
To generate the Torizon OS image, run the command below, in the same directory where the tcbuild.yaml file is:
$ torizoncore-builder build
...
1091 metadata, 12741 content objects imported; 412.2 MB content written
Pulling done.
Deploying OSTree with checksum 58629613a342197c31c5911d0874aac1b0fcb46b68a63f59760c03bacc4df08a
Deploying done.
Copy files not under OSTree control from original deployment.
Packing rootfs...
Packing rootfs done.
=>> Build command successfully executed!
In case of using a configuration file with a different name than tcbuild.yaml, run the command specifying the configuration file name:
$ torizoncore-builder build --file <configuration_file_name>
Deploy The Custom Toradex Easy Installer Imageβ
To deploy the custom Toradex Easy Installer image to the board, click on the link below and choose between the available options.
Deploy The Custom Toradex Easy Installer Image
The output image can be deployed in three ways to the board:
- Using Toradex Easy Installer, the recommended method for production programming.
- Directly on the board through SSH, the recommended method during development.
- Through Torizon Cloud server, the recommended method to perform updates on a device already deployed to the field.
- It's also possible to use a static-delta approach, which is more network efficient.
Despite the recommendations, it is also possible to use a different method, using the Torizon Cloud method during development for example.
To learn more about when to use each method, please refer to the Deployment Methods Comparison section of the TorizonCore Builder - Workflow article.
Toradex Easy Installerβ
Toradex Easy Installer Tool allows users to install an image into the internal flash memory of Toradex modules in an extremely simple way.
Copy the output image into a USB stick and follow the steps in the Toradex Easy Installer article linked above. The copy of the output image can be done with the command below:
$ cp -a torizon-core-docker-colibri-imx6-Tezi_5.3.0.CUSTOM /media/user/myUSBstick
Where, in my case, /media/user/myUSBstick is the path to USB stick mount point and torizon-core-docker-colibri-imx6-Tezi_5.3.0.CUSTOM
is the directory containing the custom Toradex Easy Installer image.
Directly, through SSHβ
In this case, before deployment the output image needs to be unpacked, using the command below:
$ torizoncore-builder images unpack torizon-core-docker-colibri-imx6-Tezi_5.3.0.CUSTOM
Change the argument torizon-core-docker-colibri-imx6-Tezi_5.3.0.CUSTOM
to the directory containing your custom Toradex Easy Installer image.
For more details on how this command works, please check the images unpack command in the commands manual.
To deploy it directly to the board, through SSH, use the command below: