长生栈 长生栈
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Living Team

编程技术分享
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 编程语言

  • 数据结构和算法

  • 计算机组成原理

  • 操作系统

    • Linux内核模块
      • 内核模块简介
      • 模块操作命令
      • 模块的编写、加载和卸载
      • 附录:与其他内核机制的对比
  • 计算机网络

  • 数据库

  • 设计模式

  • 基础
  • 操作系统
DC Wang
2023-09-06
目录

Linux内核模块

# Linux内核模块

内核模块是一种用于扩展和定制操作系统内核功能的软件组件。内核模块是操作系统内核的一部分,允许用户或开发人员在运行的操作系统上添加新功能、驱动程序或修改现有功能,而无需重新编译整个内核或重新启动计算机。

# 内核模块简介

模块全称:动态可加载内核模块(loadable kernel module, LKM)。

以下是有关内核模块的一些重要信息:

  1. 目的和用途:
    • 内核模块用于扩展操作系统内核的功能。它们可以用于添加新的设备驱动程序、文件系统支持、网络协议、安全策略等。内核模块通常用于解决特定的问题或满足特定的需求。
  2. 模块加载和卸载:
    • 内核模块可以在运行时动态加载到内核中,也可以在不再需要时动态卸载。这种动态性使得内核可以保持在运行状态,同时允许灵活地添加或移除功能。
  3. 编写内核模块:
    • 编写内核模块通常需要熟悉操作系统内核的编程接口和内核的数据结构。内核模块通常使用C语言编写,并依赖于内核提供的API和头文件。
  4. 模块通信:
    • 内核模块可以与内核和其他模块进行通信,以便访问系统资源、传递信息或协调活动。这种通信通常通过内核提供的API函数完成。
  5. 使用模块机制的优点:
    • 使得内核结构更加紧凑和灵活。
    • 系统如果需要新功能,只要编译相应的模块然后插入即可。
    • 模块一旦链接到内核,就与内核中原有的代码完全等价。

内核模块是一种强大的工具,用于定制和扩展操作系统内核功能。它们允许开发人员在运行时添加、修改或删除操作系统功能,从而满足特定需求或解决特定问题。然而,内核模块的开发需要深入的操作系统知识和小心谨慎的编程实践,以确保系统的安全性和稳定性。

# 模块操作命令

下面是关于这些与内核模块操作相关的命令的表格总结,包括命令的描述和示例:

命令 描述 示例
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);
1
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
1
2
3
4
5
6
7

运行make命令,它将编译你的内核模块并生成名为hello_module.ko的二进制文件。

3. 加载内核模块:

使用insmod命令来加载内核模块:

sudo insmod hello_module.ko
1

如果一切顺利,模块将被加载到内核中,同时你会看到**"Hello, kernel!"**消息在内核日志中(通常在/var/log/kern.log或使用dmesg命令查看)。

使用lsmod命令来确认当前模块中已经存在了hello_module:

$ lsmod 
Module                  Size  Used by
hello_module           16384  0
1
2
3

4. 卸载内核模块:

使用rmmod命令来卸载已加载的内核模块:

sudo rmmod hello_module
1

卸载后,你会看到**"Goodbye, kernel!"**消息在内核日志中。

使用lsmod命令来确认当前模块中已经卸载了hello_module:

$ lsmod
Module                  Size  Used by
...
1
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!
1
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
1
2
3
4
5
6

# 附录:与其他内核机制的对比

下面是对微内核体系结构、单一内核体系结构以及采用模块机制的计算机内核结构的对比:

特征 微内核体系结构 单一内核体系结构 采用模块机制
内核大小 小,核心功能最小化,其余功能模块化。 大,包含大多数操作系统功能。 中等,核心包含主要功能,其余模块化。
性能 通常具有较低的性能开销,由于用户态和内核态切换和通信。 通常具有较高的性能,因为减少了用户态和内核态之间的开销。 通常具有中等性能,依赖于模块的实现方式。
可维护性和可扩展性 更易于维护和扩展,因为可以独立添加或删除模块。 较难维护和扩展,因为所有功能都与内核绑定在一起。 中等,允许在运行时添加或删除模块,但可能需要处理依赖关系。
定制性 高,可以根据需要定制操作系统功能。 有限,定制操作系统功能相对困难。 中等,允许定制功能,但依赖于可用模块。
内核模块加载/卸载 可以加载和卸载模块,通常使用insmod和rmmod命令。 不适用,内核功能是静态编译到内核中的。 允许加载和卸载模块,通常使用modprobe和rmmod命令。
例子 Linux的部分实现,如GNU Hurd。 大多数传统的操作系统,如Windows和macOS。 Linux的内核模块系统。

微内核体系结构通常用于需要灵活性和可维护性的系统,而单一内核体系结构通常用于对性能要求较高的系统。采用模块机制的内核结构提供了一种折中的方法,允许在运行时扩展和定制内核。

编辑 (opens new window)
上次更新: 2023/09/17, 16:44:05
Leetcode-90-子集 II
设计模式介绍

← Leetcode-90-子集 II 设计模式介绍→

最近更新
01
ESP32-网络摄像头方案
06-14
02
ESP32-PWM驱动SG90舵机
06-14
03
ESP32-实时操作系统freertos
06-14
更多文章>
Theme by Vdoing | Copyright © 2019-2025 DC Wang All right reserved | 辽公网安备 21021102001125号 | 吉ICP备20001966号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式