可以通过输入命令列出当前加载的所有内核模块,此命令将在三列中列出当前的内核模块:名称、大小和使用模块的位置。
[root@ip-172-16-1-245 ~]# lsmod
Module Size Used by
intel_rapl_msr 16384 0
intel_rapl_common 24576 1 intel_rapl_msr
isst_if_common 16384 0
nfit 65536 0
libnvdimm 192512 1 nfit
ppdev 20480 0
rapl 20480 0
pcspkr 16384 0
parport_pc 32768 0
parport 57344 2 parport_pc,ppdev
i2c_piix4 24576 0
ip_tables 28672 0
xfs 1515520 1
libcrc32c 16384 1 xfs
crct10dif_pclmul 16384 1
crc32_pclmul 16384 0
crc32c_intel 24576 1
nvme 45056 1
ghash_clmulni_intel 16384 0
nvme_core 110592 3 nvme
ena 114688 0
serio_raw 16384 0
t10_pi 16384 1 nvme_core
dm_mirror 28672 0
dm_region_hash 20480 1 dm_mirror
dm_log 20480 2 dm_region_hash,dm_mirror
dm_mod 151552 2 dm_log,dm_mirror
编写内核模块
要编写内核模块,需要有内核源码,内核源码是放到/usr/src/kernels/下面的。我们需要装一个包:
yum install kernel-devel
sudo yum group install "Development Tools" # 开发者套件
装完这个包以后,就能到对应目录下看到内核源码了。
下面的程序编写了一个非常基本的内核模块,它在内核模块加载和卸载时打印适当的消息。
simple.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"); }
Makefile
obj-m := test.o
编译模块
make -C /lib/modules/$(uname -r)/build M=/root/testmodule modules
运行成功后会生成很多文件,其中包括simple.ko 这个就是我们编译出来的内核模块
加载模块
运行时加载内核模块
[root@ip-172-16-1-245 ch2]# insmod simple.ko
[root@ip-172-16-1-245 ch2]# lsmod | grep simple
simple 16384 0
[root@ip-172-16-1-245 ch2]# rmmod simple.ko # 移除模块
The insmod program inserts a single module into the kernel. This process requires you to have already loaded any modules on which the module you’re loading relies. The modprobe program, by contrast, automatically loads any depended-on modules and so is generally the preferred way to do the job.
加载完模块以后可以查看dmesg 日志
[94475.463304] Hello World
This is a test
另一种复制文件的方式加载
Optional: check the contents of the /root/testmodule/ directory:
ls -l /root/testmodule/
total 452
-rw-r—r--. 1 root root 16 Jul 12 10:16 Makefile
-rw-r—r--. 1 root root 32 Jul 12 10:16 modules.order
-rw-r—r--. 1 root root 0 Jul 12 10:16 Module.symvers
-rw-r—r--. 1 root root 197 Jul 12 10:15 test.c
-rw-r—r--. 1 root root 219736 Jul 12 10:16 test.ko
-rw-r—r--. 1 root root 826 Jul 12 10:16 test.mod.c
-rw-r—r--. 1 root root 113760 Jul 12 10:16 test.mod.o
-rw-r—r--. 1 root root 107424 Jul 12 10:16 test.o
Copy the kernel module to the /lib/modules/$(uname -r)/ directory:
# cp /root/testmodule/test.ko /lib/modules/$(uname -r)/
Update the modular dependency list:
# depmod -a
Load the kernel module:
# modprobe -v test
insmod /lib/modules/4.18.0-305.el8.x86_64/test.ko
Verify that the kernel module was successfully loaded:
# lsmod | grep test
test 16384 0
Read the latest messages from the kernel ring buffer:
# dmesg
…
[74422.545004] Hello World
This is a test
# modprobe -r test 移除模块
系统启动时加载内核模块
Select a kernel module you want to load during the boot process.
The modules are located in the /lib/modules/$(uname -r)/kernel/<SUBSYSTEM>/ directory.
Create a configuration file for the module:
# echo <MODULE_NAME> > /etc/modules-load.d/<MODULE_NAME>.conf
NOTE
When entering the name of a kernel module, do not append the .ko.xz extension to the end of the name. Kernel module names do not have extensions; their corresponding files do.
Optionally, after reboot, verify the relevant module was loaded:
$ lsmod | grep <MODULE_NAME>
The example command above should succeed and display the relevant kernel module.
内核模块依赖
依赖关系文件
/lib/modules/4.18.0-305.12.1.el8_4.x86_64/modules.dep
管理依赖关系命令
depmod -a