环境Linux Mint 21.3 + GCC 11.4 + Make 4.3
模块内核模块的全称是动态可加载内核模块(Loadable Kernel Modul,KLM),可以动态载入内核,让它成为内核代码的一部分。
一个模块一般由一组函数和数据结构组成。
开发创建一个目录用于放置源码
模块源码hello.c为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> MODULE_LICENSE("GPL" ); static int hello_init (void ) { printk(KERN_ALERT "Hello World\n" ); return 0 ; }static void hello_exit (void ) { printk(KERN_ALERT "Goodbye World\n" ); } module_init(hello_init); module_exit(hello_exit);
Makefile内容为
1 2 3 4 5 6 7 8 9 obj-m := hello.o KERNEL_DIR := /lib/modules/$(shell uname -r) /build PWD := $(shell pwd) all: make -C $(KERNEL_DIR) M=$(PWD) modulesclean: make -C $(KERNEL_DIR) M=$(PWD) clean
测试 编译模块输出信息为
1 2 3 4 5 6 7 8 9 10 hyper372@hyper372-test:~/Documents/hello$ make make -C /lib/modules/5.15.0-116-generic/build M=/home/hyper372/Documents/hello modules make[1]: Entering directory '/usr/src/linux-headers-5.15.0-116-generic' CC [M] /home/hyper372/Documents/hello/hello.o MODPOST /home/hyper372/Documents/hello/Module.symvers CC [M] /home/hyper372/Documents/hello/hello.mod.o LD [M] /home/hyper372/Documents/hello/hello.ko BTF [M] /home/hyper372/Documents/hello/hello.ko Skipping BTF generation for /home/hyper372/Documents/hello/hello.ko due to unavailability of vmlinux make[1]: Leaving directory '/usr/src/linux-headers-5.15.0-116-generic'
编译结果为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 hyper372@hyper372-test:~/Documents/hello$ ll total 240 drwxrwxr-x 2 hyper372 hyper372 4096 Jul 17 10:24 ./ drwxr-xr-x 7 hyper372 hyper372 4096 Jul 17 10:11 ../ -rw-rw-r-- 1 hyper372 hyper372 611 Jul 17 10:14 hello.c -rw-rw-r-- 1 hyper372 hyper372 61736 Jul 17 10:24 hello.ko -rw-rw-r-- 1 hyper372 hyper372 253 Jul 17 10:24 .hello.ko.cmd -rw-rw-r-- 1 hyper372 hyper372 40 Jul 17 10:24 hello.mod -rw-rw-r-- 1 hyper372 hyper372 856 Jul 17 10:24 hello.mod.c -rw-rw-r-- 1 hyper372 hyper372 148 Jul 17 10:24 .hello.mod.cmd -rw-rw-r-- 1 hyper372 hyper372 50048 Jul 17 10:24 hello.mod.o -rw-rw-r-- 1 hyper372 hyper372 31035 Jul 17 10:24 .hello.mod.o.cmd -rw-rw-r-- 1 hyper372 hyper372 13024 Jul 17 10:24 hello.o -rw-rw-r-- 1 hyper372 hyper372 29739 Jul 17 10:24 .hello.o.cmd -rw-rw-r-- 1 hyper372 hyper372 224 Jul 17 10:15 Makefile -rw-rw-r-- 1 hyper372 hyper372 40 Jul 17 10:24 modules.order -rw-rw-r-- 1 hyper372 hyper372 174 Jul 17 10:24 .modules.order.cmd -rw-rw-r-- 1 hyper372 hyper372 0 Jul 17 10:24 Module.symvers -rw-rw-r-- 1 hyper372 hyper372 224 Jul 17 10:24 .Module.symvers.cmd
查看模块信息1 2 3 4 5 6 7 8 hyper372@hyper372-test:~/Documents/hello$ modinfo hello.ko filename: /home/hyper372/Documents/hello/hello.ko license: GPL srcversion: 5F846D216D4D129E9B3246C depends: retpoline: Y name: hello vermagic: 5.15.0-116-generic SMP mod_unload modversions
加载模块 获取已加载模块列表查看已加载的模块,确定hello模块加载成功
1 2 3 4 5 6 7 8 hyper372@hyper372-test:~/Documents/hello$ lsmod Module Size Used by hello 16384 0 rfcomm 81920 16 bnep 28672 2 vsock_loopback 16384 0 vmw_vsock_virtio_transport_common 40960 1 vsock_loopback vmw_vsock_vmci_transport 32768 2
查看内核信息1 2 3 4 5 6 7 8 9 hyper372@hyper372-test:~/Documents/hello$ sudo dmesg [ 0.000000] Linux version 5.15.0-116-generic (buildd@lcy02-amd64-015) (gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) [ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-5.15.0-116-generic root=UUID=2f7aebd4-6e49-4772-977e-f7ad68635ecb ro quiet splash [ 0.000000] KERNEL supported cpus: [ 0.000000] Intel GenuineIntel ... [ 30.588512] Bluetooth: RFCOMM ver 1.11 [ 556.898154] hello: module verification failed: signature and/or required key missing - tainting kernel [ 556.898755] Hello World
卸载模块执行命令,卸载后lsmod应该找不到hello模块了。