记录Linux内核模块最简单的例子
ubuntu内核模块
modtest.c 文件
#include <asm/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
static int __init modtest_init(void)
{
printk("modtest_init()\n");
return 0;
}
static void __exit modtest_exit(void)
{
printk("modtest_exit()\n");
}
module_init(modtest_init);
module_exit(modtest_exit);
MODULE_LICENSE("GPL");
Makefile 文件
obj-m += modtest.o
KDIR :=/lib/modules/$(shell uname -r)/build/
PWD :=$(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.ko *.o *.symvers *.order *.mod.c
obj-m 将modtest编译成内核模块 .ko 文件
KDIR 内编译后的内核地址,其中$(shell uname -r) 当前系统版本
PWD 工程文件目录
make -C $(KDIR) M=$(PWD) modules 指定内核源码目录,内核模块目录,其中modules 让编译器编译成内核模块
编译make
ubuntu@ubuntu22-pc:~/test/module$ make
make -C /lib/modules/6.2.0-32-generic/build/ M=/home/ubuntu/test/module modules
make[1]: 进入目录“/usr/src/linux-headers-6.2.0-32-generic”
warning: the compiler differs from the one used to build the kernel
The kernel was built by: x86_64-linux-gnu-gcc-11 (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
You are using: gcc-11 (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
CC [M] /home/ubuntu/test/module/modtest.o
MODPOST /home/ubuntu/test/module/Module.symvers
CC [M] /home/ubuntu/test/module/modtest.mod.o
LD [M] /home/ubuntu/test/module/modtest.ko
BTF [M] /home/ubuntu/test/module/modtest.ko
Skipping BTF generation for /home/ubuntu/test/module/modtest.ko due to unavailability of vmlinux
make[1]: 离开目录“/usr/src/linux-headers-6.2.0-32-generic”
make -C /lib/modules/6.2.0-32-generic/build/ M=/home/ubuntu/test/module modules 这么多主要是这一行,会根据系统和目录而变
测试
insmod 安装内核模块
rmmod 卸载内核模块
lsmod 打印内核模块列表
modinfo 查看内核文件信息
成功安装到内核
pintk()信息正常打印;
sudo dmesg -c # dmesg 查看日志 -c是打印后删除
嵌入式内核模块
编译make 时要指定ARCH 和 CROSS_COMPILE
make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu-
arm64 CPU类型,aarch64-none-linux-gnu- 编译内核代码所用的编译工具
另外要修改Makefile文件的KDIR为编译后的内核路径。