3.11. 编译自定义的内核模块
您可以根据硬件和软件级别的各种配置的要求构建一个采样内核模块。
先决条件
kernel-devel、gcc和elfutils-libelf-devel软件包已安装。# *dnf install kernel-devel-$(uname -r) gcc elfutils-libelf-devel*- 您有 root 权限。
-
您创建了
/root/testmodule/目录,在此编译自定义的内核模块。
步骤
创建包含以下内容的
/root/testmodule/test.c文件:#include <linux/module.h> #include <linux/kernel.h> int init_module(void) { printk("Hello World\n This is a test\n"); return 0; } void cleanup_module(void) { printk("Good Bye World"); } MODULE_LICENSE("GPL");test.c文件是一个源文件,其向内核模块提供主要功能。出于组织需要,该文件已创建在专用的/root/testmodule/目录中。在模块编译后,/root/testmodule/目录将包含多个文件。test.c文件包含来自系统库的文件:-
示例代码中的
printk()函数需要linux/kernel.h头文件。 -
linux/module.h文件包含函数声明和用 C 编程语言编写的在多个源文件之间共享的宏定义。
-
示例代码中的
-
按照
init_module ()和cleanup_module ()函数启动和结束内核日志记录函数printk (),后者会打印文本。 使用以下内容创建
/root/testmodule/Makefile文件。obj-m := test.oMakefile 包含编译器的说明,以生成名为
test.o的对象文件。obj-m指令指定生成的test.ko文件将编译为可加载的内核模块。或者,obj-y指令可指示将test.ko作为内置内核模块构建。编译内核模块:
# make -C /lib/modules/$(uname -r)/build M=/root/testmodule modules make: Entering directory '/usr/src/kernels/6.12.0-55.9.1.el10_0.x86_64' CC [M] /root/testmodule/test.o MODPOST /root/testmodule/Module.symvers CC [M] /root/testmodule/test.mod.o LD [M] /root/testmodule/test.ko BTF [M] /root/testmodule/test.ko Skipping BTF generation for /root/testmodule/test.ko due to unavailability of vmlinux make: Leaving directory '/usr/src/kernels/6.12.0-55.9.1.el10_0.x86_64'编译器将它们链接成最终内核模块(
test.ko)之前,会为每个源文件(test.c)创建一个对象文件(test.c)来作为中间步骤。成功编译后,
/root/testmodule/包含与编译的自定义内核模块相关的其他文件。已编译的模块本身由test.ko文件表示。
验证
可选:检查
/root/testmodule/目录的内容:# ls -l /root/testmodule/ total 152 -rw-r—r--. 1 root root 16 Jul 26 08:19 Makefile -rw-r—r--. 1 root root 25 Jul 26 08:20 modules.order -rw-r—r--. 1 root root 0 Jul 26 08:20 Module.symvers -rw-r—r--. 1 root root 224 Jul 26 08:18 test.c -rw-r—r--. 1 root root 62176 Jul 26 08:20 test.ko -rw-r—r--. 1 root root 25 Jul 26 08:20 test.mod -rw-r—r--. 1 root root 849 Jul 26 08:20 test.mod.c -rw-r—r--. 1 root root 50936 Jul 26 08:20 test.mod.o -rw-r—r--. 1 root root 12912 Jul 26 08:20 test.o将内核模块复制到
/lib/modules/$(uname -r)/目录中:# cp /root/testmodule/test.ko /lib/modules/$(uname -r)/更新模块依赖项列表:
# depmod -a载入内核模块:
# modprobe -v test insmod /lib/modules/6.12.0-55.9.1.el10_0.x86_64/test.ko验证内核模块是否成功载入:
# lsmod | grep test test 16384 0从内核环缓冲中读取最新的消息:
# dmesg [74422.545004] Hello World This is a test