Linux模块与系统调用

news/2025/3/10 10:46:52/文章来源:https://www.cnblogs.com/Arisf/p/18647281

模块与系统调用

1. 编写内核模块代码

首先,编写一个简单的“Hello World”内核模块文件 hello_module.c

#include <linux/init.h>     // 用于宏 __init 和 __exit
#include <linux/module.h>   // 用于模块编程基本宏
#include <linux/kernel.h>   // 用于 printk 宏MODULE_LICENSE("GPL");               // 指定模块许可证
MODULE_AUTHOR("20242826");          // 指定模块作者
MODULE_DESCRIPTION("A simple hello world kernel module"); // 模块描述
MODULE_VERSION("1.0");               // 模块版本// 初始化函数
static int __init hello_init(void) {printk(KERN_INFO "Hello, Kernel!\n"); // 向内核日志打印信息return 0;  // 返回0表示成功
}// 清理函数
static void __exit hello_exit(void) {printk(KERN_INFO "Goodbye, Kernel!\n"); // 向内核日志打印信息
}// 注册初始化和清理函数
module_init(hello_init);
module_exit(hello_exit);

在这个模块中:

  • hello_init 函数在模块加载时运行。
  • hello_exit 函数在模块卸载时运行。
  • printk 是用于内核日志输出的函数,类似于用户空间的 printf

2. 创建Makefile文件

创建一个 Makefile,用来编译内核模块。文件内容如下:

# Makefile
obj-m += hello_module.o   # 指定编译生成的目标对象all:make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modulesclean:make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

在这个 Makefile 中:

  • obj-m += hello_module.o 指定生成模块的目标文件。
  • make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 命令用当前内核的编译环境编译模块。
  • clean 命令用于清理编译生成的文件。

3. 编译内核模块

在包含 hello_module.cMakefile 的目录中,运行以下命令来编译模块:

make

编译成功后,将生成 hello_module.ko 文件,这就是编译完成的内核模块文件。

01

4. 加载和卸载内核模块

加载模块

要加载模块,可以使用 insmod 命令:

sudo insmod hello_module.ko

成功加载模块后,内核日志中会出现 Hello, Kernel! 的信息。可以通过以下命令查看内核日志:

sudo dmesg | tail

02

卸载模块

要卸载模块,可以使用 rmmod 命令:

sudo rmmod hello_module

卸载模块后,内核日志中会显示 Goodbye, Kernel! 信息。
03

5.编译模块实现输出当前进程信息的功能

#include <linux/init.h>      // 用于宏 __init 和 __exit
#include <linux/module.h>    // 用于模块编程基本宏
#include <linux/kernel.h>    // 用于 printk 宏
#include <linux/sched.h>     // 用于获取当前进程信息
#include <linux/sched/signal.h>MODULE_LICENSE("GPL");               // 模块许可证
MODULE_AUTHOR("20242826");          // 模块作者
MODULE_DESCRIPTION("A module to print current process info"); // 模块描述
MODULE_VERSION("1.0");               // 模块版本// 初始化函数
static int __init module2_init(void) {printk(KERN_INFO "Module2 loaded\n");printk(KERN_INFO "Current Process Info:\n");printk(KERN_INFO "Process ID: %d\n", current->pid);printk(KERN_INFO "Process Name: %s\n", current->comm);return 0;  // 返回0表示成功
}// 清理函数
static void __exit module2_exit(void) {printk(KERN_INFO "Module2 unloaded\n");
}// 注册初始化和清理函数
module_init(module2_init);
module_exit(module2_exit);

代码说明

  • current 是一个指向当前执行进程的 task_struct 指针,task_struct 是包含进程信息的内核结构体。
  • current->pid 表示当前进程的ID。
  • current->comm 表示当前进程的名称。
# Makefile
obj-m += module2.o   # 指定编译生成的目标对象all:# 使用 Tab 键缩进make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modulesclean:# 使用 Tab 键缩进make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
make
sudo insmod module2.ko
sudo dmesg | tail
# 卸载模块
sudo rmmod module2

04

6.编译模块实现读取进程链表的功能

#include <linux/init.h>        // 用于宏 __init 和 __exit
#include <linux/module.h>      // 用于模块编程基本宏
#include <linux/kernel.h>      // 用于 printk 宏
#include <linux/sched.h>       // 用于 task_struct 结构体
#include <linux/sched/signal.h> // 用于 next_task 宏MODULE_LICENSE("GPL");
MODULE_AUTHOR("20242826");
MODULE_DESCRIPTION("A module to list all processes in the process list");
MODULE_VERSION("1.0");static int __init module3_init(void) {struct task_struct *task;printk(KERN_INFO "Module3 loaded: Listing all processes\n");// 遍历进程链表for_each_process(task) {printk(KERN_INFO "Process: %s [PID: %d]\n", task->comm, task->pid);}return 0;
}static void __exit module3_exit(void) {printk(KERN_INFO "Module3 unloaded\n");
}module_init(module3_init);
module_exit(module3_exit);

代码说明

  • for_each_process(task) 是 Linux 内核提供的一个宏,用于遍历所有进程。它会依次遍历所有 task_struct 结构体,将每个进程的指针赋值给 task 变量。
  • task->comm 存储进程名称,task->pid 存储进程 ID。
    该模块在加载时输出所有进程的名称和进程ID。
# Makefile
obj-m += module3.o   # 指定编译生成的目标对象all:# 使用 Tab 键缩进make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modulesclean:# 使用 Tab 键缩进make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
make
sudo insmod module3.ko
sudo dmesg | tail -n 50
# 卸载模块
sudo rmmod module3

05

7. 清理编译生成的文件

执行以下命令清理生成的文件:

make clean

总结

以上步骤完成了Linux内核模块编写、编译、加载和卸载的流程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/862840.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

visual studio下静态链接库的制作、动态链接库的制作

visual studio下静态链接库的制作、动态链接库的制作 生成动态库dll和静态库与lib 打开VS2022,创建一个桌面向导项目:选择动态链接库 首先,创建四个.c文件,内容为函数定义,即add.c、sub.c、div.c和mul.c四个文件,但需要稍微修改,即在函数面前加上_declspec(dllexport):…

Python实现Zip文件的暴力破解

Python实现Zip文件的暴力破解 实验内容 我们在网上好不容易下载到一个想要的 zip 资源却发现这个 zip 文件是加密的,或者忘掉自己压缩后的密码(一想到就头疼)。这时候我们就会想办法,将里面的内容提取出来。我目前已知的破解 zip 的方式只有 “Known plaintext attack(已知…

DVWA靶场File Upload(文件上传) 漏洞所有级别通关教程及源码审计

文件上传 文件上传漏洞是由于对上传文件的内、类型没有做严格的过滤、检查,使得攻击者可以通过上传木马文件获取服务器的webshell文件 low 上传一个php文件,上传成功,并且可以在WWW\DVWA\hackable\uploads目录下找到该文件此难度没有做任何过滤,所有文件都可以上传 源码审计…

论文阅读:Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context

Transformer可以接收一整段序列,然后使用self-attention机制来学习它们之间的依赖关系,但其在语言建模时受到固定长度上下文的限制(固定长度的输入、绝对位置编码的限制、注意力机制的计算复杂度)。 Transformer-XL以此为基础,引入一个片段级递归机制和一种新的位置编码方…

WPS 关闭个性化推荐

WPS>打开文件位置>打开第一个文件夹>继续打开文件夹>找到ksomisc.exe工具并双击打开>高级>功能定制:关闭个性化推荐I have a dream : Sandy beach B-J-N.

搭建一个简单的UVM验证平台

转载自 https://zhuanlan.zhihu.com/p/713891980 一. UVM 方法学简介 UVM(Universal Verification Methodology),又称作通用验证方法学。它起源于OVM(Open Verification Methdology),是由Cadence,Mentor和Synopsys联合推出的主流验证方法学;UVM方法学可以帮助我们搭建…

react学习之antd

antd为 Web 应用提供了丰富的基础 UI 组件,我们还将持续探索企业级应用的最佳 UI 实践。它最初是基于 React 的组件库,但随着技术的发展,现在也提供了基于 Vue.js 的版本——Antd Vue。无论你是 React 还是 Vue 的开发者,都可以利用 Antd 来丰富你的 Web 应用界面。antd 为…

windos server添加新用户

以Windows Server 2022举例子(该机器本身是一台轻量应用服务器)。 首先添加新用户:以管理员身份登录,选择“更改账户设置”: 选择 “其他用户” --> “将其他人添加到这台电脑”: 选择 “用户”: 单击鼠标右键,选择 “新用户”: 填写要创建的新用户信息: 选…

LLM2Vec: 解锁大语言模型的隐藏能力

LLM2Vec:重新定义大语言模型在自然语言处理中的应用一种名为 ** LLM2Vec ** 的新方法正在改变我们对大语言模型(LLMs)在自然语言处理(NLP)中的使用方式。 研究人员提出了一种创新方法,将通常仅用于生成文本的大型语言模型转化为更强大的文本理解和组织工具。这项技术有可…

将未来帧中的点 pts​ 对齐到当前帧

已知当前的rt矩阵,和未来下一帧的rt矩阵和未来下一帧的5个点pts,求把pts对齐到当前帧。import numpy as npdef align_points(rt_current, rt_future, pts_future):# 计算从未来帧到当前帧的相对变换矩阵rt_relative = np.linalg.inv(rt_current) @ rt_future# 将点转换为齐次…

基于甘特图的任务调度与跟踪工具

在当今复杂的项目管理领域,工具的种类繁多且功能各异。常见的项目管理工具包括禅道、Trello、Jira、Microsoft Project等。这些工具在不同层面上助力项目管理,从任务分配到进度跟踪,从团队协作到资源管理。甘特图作为一种直观且有效的任务调度与跟踪工具,在众多项目管理工具…

2024年项目管理软件的创新突破:数据分析与自动化的结合

项目管理软件在现代企业中的作用愈加重要,尤其是在快速变化和竞争激烈的环境中。随着技术不断发展,项目管理软件也在不断创新,以适应新的工作方式和需求。2024年,项目管理软件将不仅仅是一个任务管理工具,而是一个集成化平台,支持团队协作、数据分析、资源优化等多项功能…