Load and compile kernel module in yocto

Hello Community!,

I am working on a machine verdin am62 with mallow carrier board and built multimedia-image,

now like i have some driver to drive some chip which uses SPI before proceeding with that i would like to do a very basic hello_world module so for that i followed the site
Compile a custom kernel module

i just followed exactly like how its there in that site still getting some errors in the yocto build kindly help me file structure and code for the files

Basically what i want to do is that i want to load as a kernel module so whenever it boots automatically just want to load that module

Best regards,
Raju

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the β€œSolution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

Did you like my answer? :+1: :-1:


Creating a Hello World Kernel Module with Yocto

Hello Raju,

I’ll help you create a hello world kernel module for your Verdin AM62 with Mallow carrier board setup. The Mallow carrier board is compatible with the Verdin AM62 module(1), so this configuration is supported.

File Structure and Code

Based on the Toradex documentation(2), here’s the exact file structure and code you need:

1. Create Meta Layer Structure

First, create your meta layer directory structure(2):

$ cd ../layers/meta-customer/
$ mkdir -p recipes-customer/hello-world/hello-world

(2)

2. Create the Recipe File

Create the recipe file recipes-customer/hello-world/hello-world_1.0.0.bb(2):

# Package summary
SUMMARY = "Hello World"
# License, for example MIT
LICENSE = "MIT"
# License checksum file is always required

LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

# hello-world.c from local file
SRC_URI = "file://hello-world.cpp"

# Set LDFLAGS options provided by the build system
TARGET_CC_ARCH += "${LDFLAGS}"

# Change source directory to workdirectory where hello-world.cpp is
S = "${WORKDIR}"

# Compile hello-world from sources, no Makefile
do_compile() {
    ${CXX} -Wall hello-world.cpp -o hello-world
}

# Install binary to final directory /usr/bin
do_install() {
    install -d ${D}${bindir}
    install -m 0755 ${S}/hello-world ${D}${bindir}
}

(2)

3. Create the Source Code

Add the hello world source code to recipes-customer/hello-world/hello-world/hello-world.cpp(2):

#include <stdio.h>

int main(int argc, char *argv[]){
    printf("Hello world!\n");
    return 0;
}

(2)

4. Add Layer to Build Configuration

Add your meta layer to the build/conf/bblayers.conf file(2):

# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
LCONF_VERSION = "7"

BBPATH = "${TOPDIR}"
BBFILES ?= ""

BBLAYERS ?= " \

  ${TOPDIR}/../layers/meta-toradex-nxp \
  ${TOPDIR}/../layers/meta-freescale \
  ${TOPDIR}/../layers/meta-freescale-3rdparty \
  ${TOPDIR}/../layers/meta-toradex-bsp-common \
  ${TOPDIR}/../layers/meta-openembedded/meta-oe \
  ${TOPDIR}/../layers/meta-openembedded/meta-filesystems \
  ${TOPDIR}/../layers/meta-openembedded/meta-gnome \
  ${TOPDIR}/../layers/meta-openembedded/meta-xfce \
  ${TOPDIR}/../layers/meta-openembedded/meta-networking \
  ${TOPDIR}/../layers/meta-openembedded/meta-multimedia \
  ${TOPDIR}/../layers/meta-openembedded/meta-python \
  ${TOPDIR}/../layers/meta-freescale-distro \
  ${TOPDIR}/../layers/meta-toradex-demos \
  ${TOPDIR}/../layers/meta-qt5 \
  ${TOPDIR}/../layers/meta-toradex-distro \
  ${TOPDIR}/../layers/meta-yocto/meta-poky \
  ${TOPDIR}/../layers/openembedded-core/meta \
  ${TOPDIR}/../layers/meta-customer \
"

(2)

5. Initialize Git Project (Mandatory for Torizon OS)

Since you’re building for Torizon, initialize your custom layer as a Git project(2):

$ git init
$ git commit -m "Initial Commit" -m "Add <meta-mylayer> from template"

(2)

6. Add Package to Image

To add your hello-world package to the existing multimedia image, append it to the IMAGE_INSTALL variable in your build/conf/local.conf file(2):

IMAGE_INSTALL:append = " hello-world"

(2)

7. Build the Package and Image

Build your package first(2):

$ cd build/
$ bitbake hello-world

(2)

Then build your complete image(2):

$ bitbake <your-image>

(2)

Automatic Module Loading

Once built and deployed, your hello-world binary will be located under /usr/bin/hello-world on the target system(2). Since this is a user-space application rather than a kernel module, it won’t automatically load at boot like a kernel module would.

If you need to create an actual kernel module that loads automatically at boot, you would need to create a proper Linux kernel module with .ko extension using kernel module development practices.

Best regards,
Toradex AI Assistant.

@leonardo.costa.tx @lucas_az.tx

Kindly help for the above topic

regards.
Raju

Hey, @raju3003,

Can you show what exactly are the errors you are getting in the Yocto build? What is the structure of your custom layer and what are the files you created? This information will help find out what is causing the issue.

As a suggestion, if you are having issues integrating your own kernel modules with Yocto, you could try using Torizon OS instead of a Reference Image with our BSP. You could use TorizonCore Builder to easily add your module to the image, which could accelerate developing your application.

Best regards,

Hi @leonardo.costa.tx

Thanks, for the your reply, as u said i can use torizon os and torizon core mine major things i already did with yocto image so i would like to continue with the same

then coming to file structure and files

raju@SYS-TK05:~/Verdin/layers$ tree meta-teckinsoft-hello/
meta-teckinsoft-hello/
β”œβ”€β”€ conf
β”‚   └── layer.conf
β”œβ”€β”€ COPYING.MIT
β”œβ”€β”€ README
└── recipes-kernel
    └── hello-mod
        β”œβ”€β”€ files
        β”‚   β”œβ”€β”€ hello.c
        β”‚   └── Makefile
        └── hello-mod_1.0.bb

4 directories, 6 files
raju@SYS-TK05 :~/Verdin/layers$ cat meta-teckinsoft-hello/conf/layer.conf
# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"

# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
            ${LAYERDIR}/recipes-*/*/*.bbappend"

BBFILE_COLLECTIONS += "meta-teckinsoft-hello"
BBFILE_PATTERN_meta-teckinsoft-hello = "^${LAYERDIR}/"
BBFILE_PRIORITY_meta-teckinsoft-hello = "6"

LAYERDEPENDS_meta-teckinsoft-hello = "core"
LAYERSERIES_COMPAT_meta-teckinsoft-hello = "scarthgap"
raju@SYS-TK05:~/Verdin/layers$ cat meta-teckinsoft-hello/recipes-kernel/hello-mod/files/hello.c 
#include <linux/module.h>
#include <linux/kernel.h>

static int __init hello_init(void)
{
    printk(KERN_INFO "Hello World from Verdin AM62!\n");
    return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_INFO "Goodbye from Verdin AM62!\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Teckinsoft");
MODULE_DESCRIPTION("Simple Hello World kernel module");

raju@SYS-TK05: ~/Verdin/layers$ cat meta-teckinsoft-hello/recipes-kernel/hello-mod/files/Makefile 
obj-m += hello.o

all:
	$(MAKE) -C $(KERNEL_SRC) M=$(PWD) modules

clean:
	$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean
    
raju@SYS-TK05: ~/Verdin/layers$ cat meta-teckinsoft-hello/recipes-kernel/hello-mod/hello-mod_1.0.bb
SUMMARY = "Simple Hello World kernel module"
DESCRIPTION = "A basic kernel module for testing Yocto build system"
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0-only;md5=801f80980d171dd6425610833a22dbe6"

inherit module

SRC_URI = " \
    file://hello.c \
    file://Makefile \
"

S = "${WORKDIR}"

do_compile() {
    oe_runmake -C ${STAGING_KERNEL_DIR} M=${S} modules
}

do_install() {
    install -d ${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/misc
    install -m 0644 ${S}/hello.ko ${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/misc/
}

FILES:${PN} += "${nonarch_base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/misc/hello.ko"

Error i am getting after added hello-mod to local.conf by image_install:append

Sstate summary: Wanted 525 Local 516 Mirrors 0 Missed 9 Current 5761 (98% match, 99% complete)##############################################################################                 | ETA:  0:00:00
Removing 8 stale sstate objects for arch verdin_am62: 100% |#################################################################################################################################| Time: 0:00:00
NOTE: Executing Tasks
ERROR: tdx-reference-multimedia-image-1.0-r0 do_rootfs: Unable to install packages. Command '/home/raju/Verdin/build/tmp/work/verdin_am62-tdx-linux/tdx-reference-multimedia-image/1.0/recipe-sysroot-native/usr/bin/opkg --volatile-cache -f /home/raju/Verdin/build/tmp/work/verdin_am62-tdx-linux/tdx-reference-multimedia-image/1.0/opkg.conf -t /home/raju/Verdin/build/tmp/work/verdin_am62-tdx-linux/tdx-reference-multimedia-image/1.0/temp/ipktemp/ -o /home/raju/Verdin/build/tmp/work/verdin_am62-tdx-linux/tdx-reference-multimedia-image/1.0/rootfs  --force_postinstall --prefer-arch-to-version   install bash connman connman-client connman-plugin-ethernet connman-plugin-loopback connman-plugin-wifi coreutils evtest gpicview less libdrm libgpiod-tools libinput makedevs media-files mime-support nano net-tools opkg packagegroup-base-extended packagegroup-base-tdx-cli packagegroup-basic packagegroup-boot packagegroup-core-boot packagegroup-core-weston packagegroup-fsl-isp packagegroup-machine-tdx-cli packagegroup-tdx-cli packagegroup-tdx-graphical packagegroup-tdx-qt5 packagegroup-tpm2-tdx-cli packagegroup-wifi-fw-tdx-cli packagegroup-wifi-tdx-cli python3 python3-pip python3-pyqt5 python3-spidev run-postinsts spidev-test systemd-analyze timestamp-service udev-extraconf util-linux v4l-utils wayland-qtdemo-launch-analogclock weston weston-xwayland xterm' returned 1:
 * Solver encountered 1 problem(s):
 * Problem 1/1:
 *   - package packagegroup-base-1.0-r0.verdin_am62 requires packagegroup-machine-base, but none of the providers can be installed
 *   - package packagegroup-base-extended-1.0-r0.verdin_am62 requires packagegroup-base, but none of the providers can be installed
 *   - package packagegroup-machine-base-1.0-r0.verdin_am62 requires hello-mod, but none of the providers can be installed
 *   - conflicting requests
 *   - nothing provides kernel-module-hello-6.6.94-7.3.0-devel needed by hello-mod-1.0-r0.verdin_am62
 * 
 * Solution 1:
 *   - do not ask to install a package providing packagegroup-base-extended



ERROR: Logfile of failure stored in: /home/raju/Verdin/build/tmp/work/verdin_am62-tdx-linux/tdx-reference-multimedia-image/1.0/temp/log.do_rootfs.1934745
ERROR: Task (/home/raju/Verdin/build/../layers/meta-toradex-demos/recipes-images/images/tdx-reference-multimedia-image.bb:do_rootfs) failed with exit code '1'
NOTE: Tasks Summary: Attempted 13395 tasks of which 13384 didn't need to be rerun and 1 failed.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 3 seconds
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 3 seconds

Summary: 1 task failed:
  /home/raju/Verdin/build/../layers/meta-toradex-demos/recipes-images/images/tdx-reference-multimedia-image.bb:do_rootfs
    log: /home/raju/Verdin/build/tmp/work/verdin_am62-tdx-linux/tdx-reference-multimedia-image/1.0/temp/log.do_rootfs.1934745
Summary: There was 1 ERROR message, returning a non-zero exit code.
raju@SYS-TK01:~/Verdin/layers/meta-teckinsoft-carrier-board/conf/machine$ bitbake -e virtual/kernel | grep "^PV="

and i am following the above link
Compile a Custom Kernel Module

Hey, @raju3003,

I think the problem is related to your do_compile and do_install functions. They are overwriting the default functions provided by the module class you are inheriting.

Yocto already comes with the functionality of loading your modules automatically. You need to add your module to the KERNEL_MODULE_AUTOLOAD variable. Try the following recipe:

SUMMARY = "Simple Hello World kernel module"
DESCRIPTION = "A basic kernel module for testing Yocto build system"
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0-only;md5=801f80980d171dd6425610833a22dbe6"

inherit module

SRC_URI = " \
    file://hello.c \
    file://Makefile \
"

S = "${WORKDIR}"

RPROVIDES:${PN} += "kernel-module-hello"

KERNEL_MODULE_AUTOLOAD += " hello"

On your local.conf, you should also have the module installed on your image:

IMAGE_INSTALL:append = "kernel-module-hello"

Let me know if this solves the issue.

Best regards,

1 Like

Hi @leonardo.costa.tx,

Thanks very much for sharing the complete recipe, it worked perfectly and the build completed successfully.

Best regards,
Raju

1 Like