Linux内核开发03:内核Hello World模块

环境

Linux Mint 21.3 + GCC 11.4 + Make 4.3

模块

内核模块的全称是动态可加载内核模块(Loadable Kernel Modul,KLM),可以动态载入内核,让它成为内核代码的一部分。

一个模块一般由一组函数和数据结构组成。

开发

创建一个目录用于放置源码

1
2
mkdir hello
cd hello

模块源码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> //用到了printk()函数
#include<linux/init.h>

MODULE_LICENSE("GPL"); //没有指定license会出现error

static int hello_init(void) //static使得该文件以外无法访问
{
printk(KERN_ALERT "Hello World\n"); //只能使用内核里定义好的C函数,printk会根据日志级别将指定信息输出到控制台或日志文件中,KERN_ALERT会输出到控制台
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) modules
clean:
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

加载模块

1
sudo insmod hello.ko

获取已加载模块列表

查看已加载的模块,确定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) #126-Ubuntu SMP Mon Jul 1 10:14:24 UTC 2024 (Ubuntu 5.15.0-116.126-generic 5.15.158)
[ 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模块了。

1
rmmod hello

Linux内核开发03:内核Hello World模块
https://blog.jackeylea.com/linux/hello-world-of-linux-kernel-module/
作者
JackeyLea
发布于
2024年7月28日
许可协议