1. 在实验本节代码前,准备环境一个ubuntu物理机或者虚拟机,下载并使能交叉编译工具链,然后编译好内核源码,参考《编译内核镜像并在云实验室开发板运行》开始第一个内核模块编写和编译运行。
2. 开始第一个内核模块编写和编译运行
在你要写代码的目录下用touch新建两个文件,一个源码文件,一个Makefile。如下:
~/linux_driver/01_hello$ touch helloworld_drvmod.c
~/linux_driver/01_hello$ touch Makefile
~/linux_driver/01_hello$ vim helloworld_drvmod.c
将下面的代码复制到helloworld_drvmod.c, 如下:
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
MODULE_LICENSE("MIT/GPL");
MODULE_AUTHOR("Cloud Lab");
static int __init helloworld_drvmod_init(void)
{
printk(KERN_INFO "Helloworld driver init\n");
return 0;
}
static void __exit helloworld_drvmod_exit(void)
{
printk(KERN_INFO "Helloworld driver exit\n");
}
module_init(helloworld_drvmod_init);
module_exit(helloworld_drvmod_exit);
同时编写Makefile:
~/linux_driver/01_hello$ vim Makefile
输入如下内容:
PWD := $(shell pwd)
KERDIR := /home/test/kernel_build/linux-imx
obj-m += helloworld_drvmod.o
all:
make -C $(KERDIR) M=$(PWD) modules
clean:
make -C $(KERDIR) M=$(PWD) clean
3. 编译
输入如下命令进行编译:
~/linux_driver/01_hello$ export CROSS_COMPILE=~/toolchain/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-
~/linux_driver/01_hello$ export ARCH=arm64
~/linux_driver/01_hello$ make
编译完成后,当前目录下会有如下文件:
~/linux_driver/01_hello$ ls
helloworld_drvmod.c helloworld_drvmod.mod helloworld_drvmod.mod.o Makefile Module.symvers
helloworld_drvmod.ko helloworld_drvmod.mod.c helloworld_drvmod.o modules.order
4. 替换云实验室开发板镜像并重新启动
根据《编译内核镜像并在云实验室开发板运行》替换dtb和image,这里仍然需要这一步,因为内核模块在加载时需要和内核编译版本相匹配。
上传并替换云实验室板子的dtb和Image,依次点击用户网页端下面1,2,3的位置,在点击位置2时,选择TFTP,点击3后选择文件~/kernel_build/linux-imx/arch/arm64/boot/dts/freescale/imx8mp-evk.dtb和~/kernel_build/linux-imx/arch/arm64/boot/Image。
上传成功后,点击下方PowerReset EVK按钮,重启开发板。
至此,开发板开始运行自己修改编译的linux镜像。
5. 上传自己编译的驱动模块
在4中编译出了第一个内核驱动程序helloworld_drvmod.ko,通过一次点击下图中的1,2,3位置,然后切换到本地对应的文件目录上传。
6. 运行驱动模块
执行insmod加载模块,然后执行rmmod卸载模块,log如下,可以看到当加载时,打印出了helloworld_drvmod_init里的log, 当卸载时打印出了helloworld_drvmod_exit里的log,执行加载卸载可以多次执行,也没有问题。
root@imx93evk:~# insmod helloworld_drvmod.ko
[ 78.650821] helloworld_drvmod: loading out-of-tree module taints kernel.
[ 78.657558] helloworld_drvmod: module license 'MIT/GPL' taints kernel.
[ 78.664275] Disabling lock debugging due to kernel taint
[ 78.669870] Helloworld driver init
root@imx93evk:~# rmmod helloworld_drvmod.ko
[ 90.184469] Helloworld driver exit
root@imx93evk:~# insmod helloworld_drvmod.ko
[ 92.815313] Helloworld driver init
root@imx93evk:~# rmmod helloworld_drvmod.ko
[ 95.760867] Helloworld driver exit