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.o
Makefile 包含编译器必须专门生成名为
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/5.14.0-70.17.1.el9_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/5.14.0-70.17.1.el9_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/5.14.0-1.el9.x86_64/test.ko
验证内核模块是否已成功载入:
# lsmod | grep test test 16384 0
从内核环缓冲中读取最新信息:
# dmesg [74422.545004] Hello World This is a test
其他资源