Linux insmod 命令实战示例

LinuxLinuxBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在本实验中,我们将探索 Linux 中的 insmod 命令,该命令用于将内核模块插入正在运行的内核中。内核模块是可以根据需要加载和卸载到内核中的代码片段,提供额外的功能或驱动程序。我们将学习如何编译一个简单的内核模块,并使用 insmod 将其插入正在运行的内核中。

本实验涵盖以下步骤:insmod 命令的介绍、编译内核模块以及使用 insmod 插入内核模块。编译内核模块需要 linux-headers-$(uname -r) 包,而 insmod 命令用于将编译后的模块插入正在运行的内核中。

Linux 命令速查表


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("Linux")) -.-> linux/SystemInformationandMonitoringGroup(["System Information and Monitoring"]) linux/SystemInformationandMonitoringGroup -.-> linux/uname("System Information Displaying") subgraph Lab Skills linux/uname -.-> lab-422737{{"Linux insmod 命令实战示例"}} end

insmod 命令介绍

在这一步中,我们将探索 Linux 中的 insmod 命令,该命令用于将内核模块插入正在运行的内核中。内核模块是可以根据需要加载和卸载到内核中的代码片段,提供额外的功能或驱动程序。

首先,让我们检查当前的内核版本以及可用的内核模块:

uname -r
lsmod

示例输出:

5.15.0-58-generic
Module                  Size  Used by
nvme_core              102400  1
pci_stub                16384  1
vboxpci                 24576  0
vboxnetadp              45056  0
vboxnetflt              49152  0
vboxdrv               1028096  3 vboxnetadp,vboxnetflt,vboxpci

lsmod 命令列出了当前加载的内核模块。我们可以看到有几个与 VirtualBox 相关的模块,VirtualBox 是一种常见的虚拟化软件。

接下来,让我们创建一个简单的内核模块。在 ~/project 目录下创建一个名为 hello.c 的新文件,内容如下:

#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple kernel module");

int init_module(void) {
    printk(KERN_INFO "Hello, kernel!\n");
    return 0;
}

void cleanup_module(void) {
    printk(KERN_INFO "Goodbye, kernel!\n");
}

这个模块在加载时会打印一条 "Hello, kernel!" 消息,在卸载时会打印一条 "Goodbye, kernel!" 消息。

现在,让我们编译这个内核模块:

sudo apt update
sudo apt-get install -y linux-headers-$(uname -r)
gcc -Wall -DMODULE -D__KERNEL__ -I/lib/modules/$(uname -r)/build/include -c hello.c

linux-headers-$(uname -r) 包包含了为当前内核版本编译内核模块所需的头文件。gcc 命令将 hello.c 文件编译成目标文件 hello.o

有了编译好的内核模块,我们现在可以使用 insmod 命令将其插入正在运行的内核中:

sudo insmod hello.o

示例输出:

insmod 命令将 hello.o 模块加载到内核中。你应该会在系统日志(例如 dmesg)中看到 "Hello, kernel!" 消息。

为了验证模块是否已加载,运行:

lsmod | grep hello

示例输出:

hello                  16384  0

输出显示 hello 模块现在已加载到内核中。

编译内核模块

在这一步中,我们将学习如何从源代码编译内核模块。

首先,让我们在 ~/project 目录下创建一个名为 hello2.c 的新内核模块文件,内容如下:

#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Another simple kernel module");

int init_module(void) {
    printk(KERN_INFO "Hello, from the second kernel module!\n");
    return 0;
}

void cleanup_module(void) {
    printk(KERN_INFO "Goodbye, from the second kernel module!\n");
}

这个模块与我们之前创建的模块类似,但消息不同。

现在,让我们编译 hello2.c 模块:

gcc -Wall -DMODULE -D__KERNEL__ -I/lib/modules/$(uname -r)/build/include -c hello2.c

编译过程与之前相同,只是我们现在编译的是 hello2.c 文件,而不是 hello.c

编译完成后,你应该会在 ~/project 目录中看到 hello2.o 目标文件。

使用 insmod 插入内核模块

在这一步中,我们将学习如何使用 insmod 命令将编译好的内核模块插入正在运行的内核中。

首先,确保 hello2.o 模块已编译并存在于 ~/project 目录中:

ls -l ~/project/hello2.o

示例输出:

-rw-r--r-- 1 labex labex 16384 Apr 11 12:34 /home/labex/project/hello2.o

现在,我们可以使用 insmod 命令将 hello2.o 模块插入内核中:

sudo insmod ~/project/hello2.o

示例输出:

insmod 命令将 hello2.o 模块加载到内核中。你应该会在系统日志(例如 dmesg)中看到 "Hello, from the second kernel module!" 消息。

为了验证模块是否已加载,运行:

lsmod | grep hello2

示例输出:

hello2                 16384  0

输出显示 hello2 模块现在已加载到内核中。

总结

在本实验中,我们探索了 Linux 中的 insmod 命令,该命令用于将内核模块插入正在运行的内核中。我们首先使用 uname -rlsmod 命令检查了当前的内核版本以及可用的内核模块。接着,我们创建了一个简单的内核模块,该模块在加载时会打印 "Hello, kernel!" 消息,在卸载时会打印 "Goodbye, kernel!" 消息。我们使用 gcc 命令和 linux-headers-$(uname -r) 包编译了内核模块,该包包含了当前内核版本所需的头文件。最后,我们使用 insmod 命令将编译好的内核模块插入正在运行的内核中。

Linux 命令速查表