Linux内核模块
# Linux内核模块
内核模块是一种用于扩展和定制操作系统内核功能的软件组件。内核模块是操作系统内核的一部分,允许用户或开发人员在运行的操作系统上添加新功能、驱动程序或修改现有功能,而无需重新编译整个内核或重新启动计算机。
# 内核模块简介
模块全称:动态可加载内核模块(loadable kernel module, LKM)。
以下是有关内核模块的一些重要信息:
- 目的和用途:
- 内核模块用于扩展操作系统内核的功能。它们可以用于添加新的设备驱动程序、文件系统支持、网络协议、安全策略等。内核模块通常用于解决特定的问题或满足特定的需求。
- 模块加载和卸载:
- 内核模块可以在运行时动态加载到内核中,也可以在不再需要时动态卸载。这种动态性使得内核可以保持在运行状态,同时允许灵活地添加或移除功能。
- 编写内核模块:
- 编写内核模块通常需要熟悉操作系统内核的编程接口和内核的数据结构。内核模块通常使用C语言编写,并依赖于内核提供的API和头文件。
- 模块通信:
- 内核模块可以与内核和其他模块进行通信,以便访问系统资源、传递信息或协调活动。这种通信通常通过内核提供的API函数完成。
- 使用模块机制的优点:
- 使得内核结构更加紧凑和灵活。
- 系统如果需要新功能,只要编译相应的模块然后插入即可。
- 模块一旦链接到内核,就与内核中原有的代码完全等价。
内核模块是一种强大的工具,用于定制和扩展操作系统内核功能。它们允许开发人员在运行时添加、修改或删除操作系统功能,从而满足特定需求或解决特定问题。然而,内核模块的开发需要深入的操作系统知识和小心谨慎的编程实践,以确保系统的安全性和稳定性。
# 模块操作命令
下面是关于这些与内核模块操作相关的命令的表格总结,包括命令的描述和示例:
命令 | 描述 | 示例 |
---|---|---|
insmod | 向正在运行的内核加载模块。 | sudo insmod my_module.ko |
lsmod | 显示当前加载的内核模块信息。 | lsmod |
rmmod | 从当前运行的内核中卸载内核模块。 | sudo rmmod my_module |
depmod | 处理可加载内核模块的依赖关系。 | depmod -a |
modprobe | 利用depmod创建的依赖文件来自动加载相关的模块。 | sudo modprobe my_module |
modinfo | 获取模块信息。 | modinfo my_module |
上述示例中的"my_module"是一个虚拟模块名称,实际使用时应替换为特定的内核模块名称。
# 模块的编写、加载和卸载
下面我将以Linux内核模块为例,说明如何编写、加载和卸载一个简单的内核模块。
1. 编写内核模块:
首先,你需要编写一个简单的内核模块。下面是一个示例内核模块的C代码,它将在加载时输出一条消息,卸载时输出另一条消息:
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple kernel module");
MODULE_VERSION("0.1");
static int __init hello_init(void) {
printk(KERN_INFO "Hello, kernel!\n");
return 0;
}
static void __exit hello_exit(void) {
printk(KERN_INFO "Goodbye, kernel!\n");
}
module_init(hello_init);
module_exit(hello_exit);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2. 编译内核模块:
在编写完内核模块代码后,需要使用适当的工具编译它。你可以使用Makefile
或者直接使用gcc
。下面是一个简单的Makefile示例:
obj-m += hello_module.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
2
3
4
5
6
7
运行make
命令,它将编译你的内核模块并生成名为hello_module.ko
的二进制文件。
3. 加载内核模块:
使用insmod
命令来加载内核模块:
sudo insmod hello_module.ko
如果一切顺利,模块将被加载到内核中,同时你会看到**"Hello, kernel!"**消息在内核日志中(通常在/var/log/kern.log
或使用dmesg
命令查看)。
使用lsmod
命令来确认当前模块中已经存在了hello_module:
$ lsmod
Module Size Used by
hello_module 16384 0
2
3
4. 卸载内核模块:
使用rmmod
命令来卸载已加载的内核模块:
sudo rmmod hello_module
卸载后,你会看到**"Goodbye, kernel!"**消息在内核日志中。
使用lsmod
命令来确认当前模块中已经卸载了hello_module:
$ lsmod
Module Size Used by
...
2
3
实际编写和加载内核模块需要在具有适当权限的系统上执行。在Linux中,通常需要使用
sudo
来获得超级用户权限。此外,内核模块开发需要在适当的开发环境中进行,包括已安装的内核头文件和编译工具链。
查看内核日志:
$ less /var/log/kern.log | tail -5
Sep 6 21:58:28 xx-pc kernel: [ 533.804119] perf: interrupt took too long (3661 > 3523), lowering kernel.perf_event_max_sample_rate to 54500
Sep 6 22:07:17 xx-pc kernel: [ 1062.320874] hello_module: loading out-of-tree module taints kernel.
Sep 6 22:07:17 xx-pc kernel: [ 1062.320922] hello_module: module verification failed: signature and/or required key missing - tainting kernel
Sep 6 22:07:17 xx-pc kernel: [ 1062.321667] Hello, kernel!
Sep 6 22:08:23 xx-pc kernel: [ 1128.411856] Goodbye, kernel!
2
3
4
5
6
5. 操作步骤总结
make
sudo insmod hello_module.ko
lsmod
sudo rmmod hello_module
lsmod
less /var/log/kern.log | tail -5
2
3
4
5
6
# 附录:与其他内核机制的对比
下面是对微内核体系结构、单一内核体系结构以及采用模块机制的计算机内核结构的对比:
特征 | 微内核体系结构 | 单一内核体系结构 | 采用模块机制 |
---|---|---|---|
内核大小 | 小,核心功能最小化,其余功能模块化。 | 大,包含大多数操作系统功能。 | 中等,核心包含主要功能,其余模块化。 |
性能 | 通常具有较低的性能开销,由于用户态和内核态切换和通信。 | 通常具有较高的性能,因为减少了用户态和内核态之间的开销。 | 通常具有中等性能,依赖于模块的实现方式。 |
可维护性和可扩展性 | 更易于维护和扩展,因为可以独立添加或删除模块。 | 较难维护和扩展,因为所有功能都与内核绑定在一起。 | 中等,允许在运行时添加或删除模块,但可能需要处理依赖关系。 |
定制性 | 高,可以根据需要定制操作系统功能。 | 有限,定制操作系统功能相对困难。 | 中等,允许定制功能,但依赖于可用模块。 |
内核模块加载/卸载 | 可以加载和卸载模块,通常使用insmod和rmmod命令。 | 不适用,内核功能是静态编译到内核中的。 | 允许加载和卸载模块,通常使用modprobe和rmmod命令。 |
例子 | Linux的部分实现,如GNU Hurd。 | 大多数传统的操作系统,如Windows和macOS。 | Linux的内核模块系统。 |
微内核体系结构通常用于需要灵活性和可维护性的系统,而单一内核体系结构通常用于对性能要求较高的系统。采用模块机制的内核结构提供了一种折中的方法,允许在运行时扩展和定制内核。
- 01
- Linux系统移植(五)--- 制作、烧录镜像并启动Linux02-05
- 03
- Linux系统移植(三)--- Linux kernel移植02-05