Hello! In this post, we’ll cross-compile a kernel module for Linux 6.12.
This can be done either using a standalone kernel or a Yocto-built kernel.
Requirements:
This process applies to any i.MX processor, including i.MX8, i.MX8M, i.MX8MM, i.MX8MN, i.MX8MP, i.MX93, i.MX91, i.MX95, as well as the i.MX6 and i.MX7 families.
Step 1: Compile the Linux Kernel and get the Toolchain
First, you need to compile the Linux kernel (6.12 in this case).
You can do this in a standalone environment or using Yocto.
If you are using a Standalone environment, please refer to the Chapter 4.5.12 How to build U-Boot and Kernel in standalone environment of i.MX Linux User's Guide.
Also, in that document section, you will see how to obtain the cross-compiler toolchain.
NOTE: To get the toolchain you need use Yocto at least once (for more information please refer to i.MX Yocto Project User's Guide
$ DISTRO=fsl-imx-xwayland MACHINE=Target-Machine bitbake core-image-minimal -c populate_sdk
At the end of the building, you can install your toolchain populated under:
yocto-bsp/build/tmp/deploy/sdk
There you will find a file called:
fsl-imx-wayland-glibc-x86_64-imx-image-core-armv8a-your-machine-name-toolchain-6.12-walnascar.sh
Execute with:
$ sudo ./fsl-imx-wayland-glibc-x86_64-imx-image-core-armv8a-your-machine-name-toolchain-6.12-walnascar.sh
If you use the default installation, you will have your toolchain under /opt in your host machine.
(If you will use the compiled kernel from Yocto, you can avoid below step)
Download Standalone Kernel source by cloning with:
$ git clone https://github.com/nxp-imx/linux-imx -b lf-6.12.y
$ cd linux-imx
To build the kernel in the standalone environment for i.MX 6 and i.MX 7, execute the following commands:
$ make imx_v7_defconfig
$ Make
To build the kernel in the standalone environment for i.MX 8 and i.MX 9, execute the following commands:
$ make imx_v8_defconfig
$ make
The full kernel compilation is required to generate headers and symbol files required for external module compilation, even if you don't plan to boot this kernel directly.
Step 2: Write a simple Kernel Module to test
Now that your kernel is compiled, you can write a basic kernel module for testing.
Create a new directory. It will have our hello.c and Makefile.
We will create the file hello.c:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Salas");
MODULE_DESCRIPTION("A simple kernel module example for cross-compilation.");
MODULE_VERSION("0.1");
static int __init hello_init(void) {
printk(KERN_INFO "Hello from the kernel module!\n");
return 0;
}
static void __exit hello_exit(void) {
printk(KERN_INFO "Goodbye from the kernel module!\n");
}
module_init(hello_init);
module_exit(hello_exit);
Then, create a basic Makefile to compile the modules:
# Module name
obj-m += hello.o
# Build flags
ldflags-y += --strip-debug
# Kernel source directory (provided by Yocto)
KERNEL_SRC ?= /path/to/your/compiled/kernel
# Build target
all:
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) modules
# Clean target
clean:
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean
# Install target
modules_install:
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) modules_install
KERNEL_SRC should be your compiled kernel from your Yocto build:
yocto-bsp/build/tmp/work/your-machine-poky-linux/linux-imx/6.12.20+git/build
Or the Standalone :
path/to/linux-imx/
Step 3: Set the toolchain and compile the kernel module
Finally, we can compile the kernel module.
First, set the toolchain (in my case):
$ source /opt/fsl-imx-wayland/6.12-walnascar/environment-setup-armv8a-poky-linux
Then, compile using the makefile:
$ make
f everything goes well, at final you will have the generated files:
hello.ko
hello.mod
hello.mod.c
hello.mod.o
hello.o
Makefile
modules.order
Module.symvers
The one we need is the hello.ko (Kernel Object).
We can check if the file was created correctly using:
$ readelf -h hello.ko
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: AArch64
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 33992 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
Number of section headers: 41
Section header string table index: 40
We can see the Machine is AArch64 and the Type is a Relocatable file.
Step 4: Running the Kernel Object/Module in the board
Transfer the generated hello.ko file from your host machine to your board.
Then, In your board you can run with:
root@imx93evk:~# ls
hello.ko
root@imx93evk:~# insmod hello.ko
root@imx93evk:~# dmesg | tail
[ 5140.547447] Hello world from kernel!
root@imx93evk:~# rmmod hello.ko
root@imx93evk:~# dmesg | tail
[ 5140.547447] Hello world from kernel!
[ 5153.415215] Goodbye world from kernel!
I hope this can helps to you.
Best regards,
Salas.