I.MX8 Yocto 构建SDK编译内核模块.ko方法
最近在I.MX8 的环境下想编译一个.ko内核模块做测试,就按照传统的方法去编译内核,产生了以下的问题。
环境
mechine : imx8mqevk
kernel : fsl-release-yocto
cross-compile : aarch64-poky-linux-
make -C /opt/fsl-imx-xwayland/5.4-zeus/sysroots/aarch64-poky-linux/usr/src/kernel M=/home/ysfedorov/my_c modules
make[1]: Entering directory ‘/opt/fsl-imx-xwayland/5.4-zeus/sysroots/aarch64-poky-linux/lib/modules/5.4.47-2.2.0+g5ec03d06f54e/build’
CC [M] /home/ysfedorov/my_c/my_module.o
In file included from ./include/linux/types.h:6,
from ./include/linux/list.h:5,
from ./include/linux/module.h:9,
from /home/ysfedorov/my_c/my_module.c:1:
./include/uapi/linux/types.h:5:10: fatal error: asm/types.h: No such file or directory
5 | #include <asm/types.h>
| ^~~~~~~~~~~~~
compilation terminated.
make[2]: *** [scripts/Makefile.build:266: /home/ysfedorov/my_c/my_module.o] Error 1
make[1]: *** [Makefile:1703: /home/ysfedorov/my_c] Error 2
make[1]: Leaving directory ‘/opt/fsl-imx-xwayland/5.4-zeus/sysroots/aarch64-poky-linux/lib/modules/5.4.47-2.2.0+g5ec03d06f54e/build’
make: *** [Makefile:6: all] Error 2
#include <linux/module.h>static int __init hello_init(void)
{
pr_info("hello from init\n");return 0;
}static void __exit hello_exit(void)
{
pr_info("hello from exit\n");
}module_init(hello_init);
module_exit(hello_exit);MODULE_LICENCE("GPL");
MODULE_AUTHOR("ysfedorov");
MODULE_DESCRIPTION("This is simple hello world example of module");
KERNELDIR := /home/zacha/imx8/fsl-release-yocto/linux-imx
CURRENT_PATH := $(shell pwd)
export ARCH=arm64
export CROSS_COMPILE=aarch64-poky-linux-target := hello
obj-m := $(target).o
APP_NAME := $(target)_appbuild: kernel_moduleskernel_modules:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules CROSS_COMPILE=aarch64-poky-linux- ARCH=arm64
clean:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean
代码就是相对标准的hello.ko 和Makefile , 不会有什么问题,但是出现了头文件找不到的情况,就去搜索
asm 的文件夹下的文件,发现在arch/arm64 的目录下并没有asm,就利用网上软连接的方法去尝试连接asm-generic ,然而会出现更多的头文件找不到的问题,显然是kernel 和 交叉编译器出现了问题。
然后仔细阅读NXP提供的官方开发文档,发现所需要指定的kernel并不是官方提供的kernel,而是通构建SDK下载kernel src 的方法,提供开发环境。
下面就介绍一下如何通过构建SDK 去编译.ko 内核模块的方法
具体环境以IMX8mqevk 参考
#添加Kernel src
cd fsl-release-yocto
. ./setup-environment build-xwayland
sudo gedit /conf/local.conf
#添加这行代码
TOOLCHAIN_TARGET_TASK_append = " kernel-devsrc"
# yocto 编译kernel
cd fsl-release-yocto
. ./setup-environment build-xwayland
bitbake -c cleansstate virtual/kernel
bitbake -c patch virtual/kernel
bitbake -c compile virtual/kernel -f
# yocto 构建SDK工具
cd fsl-release-yocto
. ./setup-environment build-xwayland
bitbake meta-toolchain
#安装SDK
cd fsl-release-yocto/build-xwayland/tmp/deploy/sdk
./fsl-imx-xwayland-glibc-x86_64-meta-toolchain-aarch64-toolchain-4.19-warrior.sh
按着上面步骤就已经完成了SDK的构建,它安装在默认目录 :/opt/fsl-imx-xwayland
在下目录可以看到有个kernel, 所以如果最初的问题,那么就很明显,指定的kernel很可能就是构建SDK得到的kernel。
zacha@orbita:/opt/fsl-imx-xwayland/4.19-warrior/sysroots/aarch64-poky-linux/usr/src$ ls
debug kernel
然后执行
cd /opt/fsl-imx-xwayland/4.19-warrior/sysroots/aarch64-poky-linux/usr/src/kernel
sudo bash -c "source /opt/fsl-imx-xwayland/4.19-warrior/environment-setup-aarch64-poky-linux && make syncconfig scripts"
可以看到arch/arm/include存在asm 和 uapi 。
然后修改Makefile ,在进行编译。
KERNELDIR := /opt/fsl-imx-xwayland/4.19-warrior/sysroots/aarch64-poky-linux/usr/src/kernel
CURRENT_PATH := $(shell pwd)export ARCH=arm64
export CROSS_COMPILE=aarch64-poky-linux-CFLAGS = -I/home/zacha/imx8/fsl-release-yocto/linux-imx/arch/arm64/includetarget := hello
obj-m := $(target).o
APP_NAME := $(target)_appbuild: kernel_moduleskernel_modules:$(MAKE) $(CFLAGS) -C $(KERNELDIR) M=$(CURRENT_PATH) modules CROSS_COMPILE=aarch64-poky-linux- ARCH=arm64
clean:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean
make -I/home/zacha/imx8/fsl-release-yocto/linux-imx/arch/arm64/include -C /opt/fsl-imx-xwayland/4.19-warrior/sysroots/aarch64-poky-linux/usr/src/kernel M=/home/zacha/imx8/Code modules CROSS_COMPILE=aarch64-poky-linux- ARCH=arm64
make[1]: Entering directory ‘/opt/fsl-imx-xwayland/4.19-warrior/sysroots/aarch64-poky-linux/lib/modules/4.19.35-1.1.0+gace9526cc/build’
CC [M] /home/zacha/imx8/Code/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/zacha/imx8/Code/hello.mod.o
LD [M] /home/zacha/imx8/Code/hello.ko
make[1]: Leaving directory ‘/opt/fsl-imx-xwayland/4.19-warrior/sysroots/aarch64-poky-linux/lib/modules/4.19.35-1.1.0+gace9526cc/build’
看到已经生成了hello.ko 。
移植到开发板下insmod.
root@imx8mqevk:/mnt/usb# insmod hello.ko
[ 103.964043] hello, world!
成功!
要注意!!!!!
官方提供的Ubuntu镜像的内核版本,与自己yocto构建的内核镜像kernel是不一致的,要执行自己的生成的内核模块,不能使用官方提供的Ubuntu镜像版本!
root@MYD-JX8MX:/mnt/usb# uname -r
4.19.35-1.1.0+g62c5516
root@MYD-JX8MX:/mnt/usb# insmod hello.ko
[ 56.092063] hello: version magic ‘4.19.35-1.1.0+gace9526cc SMP preempt mod_unload aarch64’ should be ‘4.19.35-1.1.0+g62c5516 SMP preempt mod_unload aarch64’
insmod: ERROR: could not insert module hello.ko: Invalid module format
root@MYD-JX8MX:/mnt/usb#
root@imx8mqevk:/mnt/usb# uname -r
4.19.35-1.1.0+gace9526cc
root@imx8mqevk:/mnt/usb# insmod hello.ko
[ 6363.901642] hello, world!
root@imx8mqevk:/mnt/usb#