当前位置: 首页 > news >正文

【操作系统】实验八 proc文件系统

🕺作者: 主页

我的专栏
C语言从0到1
探秘C++
数据结构从0到1
探秘Linux

😘欢迎关注:👍点赞🙌收藏✍️留言

🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要,有问题可在评论区提出,感谢支持!!!

文章目录

  • 实验八
      • 实验目的
      • 实验准备
      • 编译内核模块
      • 加载内核模块
      • 查看和操作文件内容
      • 卸载内核模块

实验八

实验目的

通过加载内核模块,为/proc文件系统创建以下内容:

  • 一个名叫proc_test的子目录。
  • 一个名叫current的文件,只读,读出的内容是读它的进程的情况。
  • 一个名叫current_too的链接,指向current。
  • 一个名叫hello的文件,可读可写。读出的内容是上次写的内容前面加两句话。

实验准备

  1. 复制文件到工作目录:
    • 使用将 proc_test.c 文件复制到工作目录。

  1. 进入工作目录:
    • 进入工作目录。

编译内核模块

  1. 编译 proc_test.c 模块:
    • 编写proc_test.c代码
#include <linux/sched.h>
#include <linux/init_task.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>#define MAX_LENGTH 1024static char hello_content[MAX_LENGTH] = "hello world\n";  // 初始化一个长度为 1024 的字符数组,并赋值 "hello world\n"//用于处理对 /proc/proc_test/hello 文件的写操作。它从用户空间接收数据并将其复制到内核空间的 hello_content 数组中,偏移量为12。如果写入的字符数超过了数组长度,会返回错误。
static ssize_t hello_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) {if (count > MAX_LENGTH - 1)  // 如果写入的字符数大于 MAX_LENGTH - 1,则返回错误return -EINVAL;if (copy_from_user(hello_content + 12, buffer, count))  // 将用户空间的数据复制到内核空间的 hello_content 数组中,偏移量为 12return -EFAULT;hello_content[count + 12] = '\0';  // 在 hello_content 数组中写入字符串结束符'\0'return count;  // 返回成功写入的字符数
}
//用于处理对 /proc/proc_test/hello 文件的读操作。它将 hello_content 的内容输出到 seq_file 结构体中,从而在读取文件时显示出来。
static int hello_proc_show(struct seq_file *m, void *v) {seq_printf(m, "%s", hello_content);  // 将 hello_content 的内容输出到 seq_file 结构体 m 中return 0;
}
//用于打开 /proc/proc_test/hello 文件。它调用 single_open 函数来打开文件,并指定 hello_proc_show 函数来显示文件内容。
static int hello_proc_open(struct inode *inode, struct file *file) {return single_open(file, hello_proc_show, NULL);  // 打开 proc 文件,调用 hello_proc_show 函数来显示内容
}
//定义了对 /proc/proc_test/hello 文件的操作集合,包括打开、读取、写入、定位和释放文件。
static const struct proc_ops hello_proc_ops = {.proc_open = hello_proc_open,  // 打开文件操作.proc_read = seq_read,  // 读取文件操作.proc_write = hello_proc_write,  // 写文件操作.proc_lseek = seq_lseek,  // 文件定位操作.proc_release = single_release,  // 释放文件操作
};
//用于处理对 /proc/proc_test/current 文件的读操作。它输出当前进程的相关信息,如进程ID、优先级、进程名等。
static int current_proc_show(struct seq_file *m, void *v) {struct task_struct *cur = current;seq_printf(m, "进程ID: %d\n", cur->pid);  // 输出进程IDseq_printf(m, "优先级: %d\n", cur->prio);  // 输出进程优先级seq_printf(m, "静态优先级: %d\n", cur->static_prio);  // 输出静态优先级seq_printf(m, "正常优先级: %d\n", cur->normal_prio);  // 输出正常优先级seq_printf(m, "策略: %d\n", cur->policy);  // 输出进程调度策略seq_printf(m, "进程名: %s\n", cur->comm);  // 输出进程名return 0;
}
//用于打开 /proc/proc_test/current 文件。它调用 single_open 函数来打开文件,并指定 current_proc_show 函数来显示文件内容。
static int current_proc_open(struct inode *inode, struct file *file) {return single_open(file, current_proc_show, NULL);  // 打开 proc 文件,调用 current_proc_show 函数来显示内容
}
// 定义了对 /proc/proc_test/current 文件的操作集合,包括打开、读取、定位和释放文件。
static const struct proc_ops current_proc_ops = {.proc_open = current_proc_open,  // 打开文件操作.proc_read = seq_read,  // 读取文件操作.proc_lseek = seq_lseek,  // 文件定位操作.proc_release = single_release,  // 释放文件操作
};
//模块的初始化函数,它在内核加载模块时被调用。它创建了一个名为 /proc/proc_test 的目录,并在其中创建了文件 current、current_too 和 hello。
static int __init proc_test_init(void) {struct proc_dir_entry *test_dir;test_dir = proc_mkdir("proc_test", NULL);  // 创建一个目录 /proc/proc_testproc_create("current", 0, test_dir, &current_proc_ops);  // 在 /proc/proc_test 目录下创建一个名为 "current" 的文件proc_symlink("current_too", test_dir, "current");  // 在 /proc/proc_test 目录下创建一个名为 "current_too" 的符号链接,指向 "current"proc_create("hello", 0666, test_dir, &hello_proc_ops);  // 在 /proc/proc_test 目录下创建一个名为 "hello" 的文件,可读可写权限为 0666return 0;
}
//模块的退出函数,它在内核卸载模块时被调用。它移除了之前创建的 /proc/proc_test 目录及其下的文件。
static void __exit proc_test_exit(void) {remove_proc_entry("proc_test/current", NULL);  // 移除 /proc/proc_test 目录下的文件 "current"remove_proc_entry("proc_test/current_too", NULL);  // 移除 /proc/proc_test 目录下的文件 "current_too"remove_proc_entry("proc_test/hello", NULL);  // 移除 /proc/proc_test 目录下的文件 "hello"remove_proc_entry("proc_test", NULL);  // 移除 /proc/proc_test 目录
}MODULE_LICENSE("GPL");  // 指定模块的许可证为 GPL
module_init(proc_test_init);  // 指定模块的初始化函数
module_exit(proc_test_exit);  // 指定模块的退出函数
  • 使用makefile文件编译内核模块。
obj-m:=proc_test.o
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD       := $(shell pwd)
default:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
  • 使用make命令编译

make

加载内核模块

  1. 加载编译后的模块:
    • 使用insmod加载模块。

insmod proc_test.ko

  1. 检查是否加载成功:
  • 使用lsmod命令检查模块是否加载。

lsmod | grep proc_test

  1. 检查是否创建了 /proc/proc_test 目录:
    • 进入/proc目录查看。
cd /proc
ls

  1. 检查 /proc/proc_test 目录下是否创建了三个文件:
    • current、current_too 和 hello。
cd /proc/proc_test
ls

查看和操作文件内容

  1. 查看 current 文件的内容:
    • 使用more命令查看。

more current

  1. 查看 current_too 文件的内容:
    • 使用more命令查看。

more current_too

  1. 查看 hello 文件的内容:
    • 使用more命令查看。

more hello

  1. 写入 hello 文件:
    • 使用echo命令将数据输入到hello文件。

  1. 再次查看 hello 文件的内容:
    • 使用more命令查看。

more hello

卸载内核模块

  1. 卸载加载的内核模块:
    • 使用rmmod卸载模块。

rmmod proc_test

  1. 检查是否卸载成功:
    • 使用lsmod命令检查模块是否卸载。

lsmod | grep proc_test

相关文章:

【操作系统】实验八 proc文件系统

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的很重要&…...

基于RMF的信贷风控标签客户分层管理

根据美国 数据库营销研究所Arthur Hughes的研究&#xff0c;客户数据库中有3个神奇的要素&#xff0c;这3个要素构成了数据分析最好的指标&#xff1a;最近一次消费 (Recency)、消费频率(Frequency)、消费金额 (Monetary)。这就是RMF模型&#xff0c;RMF模型是用户分层的重要手…...

【MySQL】如何通过DDL去创建和修改员工信息表

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-fmKISDBsFq74ab2Z {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…...

Spring 事务原理一

从本篇博客开始&#xff0c;我们将梳理Spring事务相关的知识点。在开始前&#xff0c;想先给自己定一个目标&#xff1a;通过此次梳理要完全理解事务的基本概念及Spring实现事务的基本原理。为实现这个目标我想按以下几个步骤进行&#xff1a; 讲解事务中的一些基本概念使用Sp…...

creo草绘3个实例学习笔记

creo草绘3个实例 文章目录 creo草绘3个实例草绘01草绘02草绘03 草绘01 草绘02 草绘03...

Modern C++ std::move的实现原理

前言 有一节我们分析了std::bind的实现原理&#xff0c;本节稍作休息分析一个比较简单的std::move 原理 std::move的原理太简单了&#xff0c;一句话&#xff1a;就是把传进来的参数强转为右值引用类型。作用为调用移动构造函数&#xff0c;或移动赋值函数。下面通过例子和代…...

爬虫工作量由小到大的思维转变---<第四十章 Scrapy Redis 实现IP代理池管理的最佳实践>

前言: 本篇是要结合上篇一起看的姊妹篇:爬虫工作量由小到大的思维转变---&#xff1c;第三十九章 Scrapy-redis 常用的那个RetryMiddleware&#xff1e;-CSDN博客 IP代理池的管理对于确保爬虫的稳定性和数据抓取的匿名性至关重要。围绕Scrapy-Redis框架和一个具体的IP代理池中…...

C# 实现 XOR 密码

XOR密码&#xff08;异或密码&#xff09;是一种简单的加密算法&#xff0c;它使用异或&#xff08;XOR&#xff09;操作来对明文和密钥进行加密和解密。 异或操作是一种位运算&#xff0c;它对两个二进制数的对应位进行比较&#xff0c;如果两个位相同&#xff08;都为0或都为…...

【Web前端开发基础】CSS3之空间转换和动画

CSS3之空间转换和动画 目录 CSS3之空间转换和动画一、空间转换1.1 概述1.2 3D转换常用的属性1.3 3D转换&#xff1a;translate3d&#xff08;位移&#xff09;1.4 3D转换&#xff1a;perspective&#xff08;视角&#xff09;1.5 3D转换&#xff1a;rotate3d&#xff08;旋转&a…...

Go实现一个简单的烟花秀效果(附带源码)

在 Go 语言中&#xff0c;要实现烟花秀效果可以使用 github.com/fogleman/gg 包进行绘图。以下是一个简单的例子&#xff1a; 首先&#xff0c;确保你已经安装了&#xff08;有时候需要梯子才可以安装&#xff09; github.com/fogleman/gg 包&#xff1a; go get -u github.c…...

【数学建模】插值与拟合

文章目录 插值插值方法用Python解决插值问题 拟合最小二乘拟合数据拟合的Python实现 适用情况 处理由试验、测量得到的大量数据或一些过于复杂而不便于计算的函数表达式时&#xff0c;构造一个简单函数作为要考察数据或复杂函数的近似 定义 给定一组数据&#xff0c;需要确定满…...

全卷积网络:革新图像分析

一、介绍 全卷积网络&#xff08;FCN&#xff09;的出现标志着计算机视觉领域的一个重要里程碑&#xff0c;特别是在涉及图像分析的任务中。本文深入探讨了 FCN 的概念、它们的架构、它们与传统卷积神经网络 &#xff08;CNN&#xff09; 的区别以及它们在各个领域的应用。 就像…...

ubuntu20.04 格式化 硬盘 扩展硬盘GParted

如何在 Ubuntu 22.04 LTS 上安装分区编辑器 GParted&#xff1f;_gparted安装-CSDN博客 sudo apt install gparted 步骤5&#xff1a;启动GParted 安装完成后&#xff0c;您可以在应用程序菜单中找到GParted。点击它以启动分区编辑器。 通过以上步骤&#xff0c;您可以在Ubun…...

docker的资源限制(cgroup)

前瞻 Docker 通过 Cgroup 来控制容器使用的资源配额&#xff0c;包括 CPU、内存、磁盘三大方面&#xff0c; 基本覆盖了常见的资源配额和使用量控制。 Cgroup 是 ControlGroups 的缩写&#xff0c;是 Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如 CPU、…...

ChatGPT与文心一言:应用示例与体验比较

ChatGPT 和文心一言哪个更好用&#xff1f; 为了更好地感受ChatGPT和文心一言这两款AI助手如何在实际运用中竞相辉映&#xff0c;我将提供一些典型的应用示例。这些示例都取自真实的用户体验&#xff0c;以帮助解释这两种工具如何让日常生活或工作变得更加轻松。 ChatGPT Ch…...

紫光展锐T760_芯片性能介绍_展锐T760安卓核心板定制

展锐T760核心板是一款基于国产5G芯片的智能模块&#xff0c;采用紫光展锐T760制程工艺为台积电6nm工艺&#xff0c;支持工艺具有出色的能效表现。其采用主流的44架构的八核设计&#xff0c;包括4颗2.2GHz A76核心和4颗A55核心设计&#xff0c;内存单元板载可达8GB Ram256GB ROM…...

从动力系统研究看当今数学界

6.3... Milnor’s definition of “attractors” which has been criticized above by us). The work of [KSS2] of asserting the existence of “nice open set” of Ω(p.148) would be likely not verified, for example we think the first sentence “… since f is nont…...

【征服redis15】分布式锁的功能与整体设计方案

目录 1. 分布式锁的概念 2.基于数据库做分布式锁 2.1 基于表主键唯一做分布式锁 2.2 基于表字段版本号做分布式锁 2.3 基于数据库排他锁做分布式锁 3.使用Redis做分布式锁 3.1 redis实现分布式锁的基本原理 3.2 问题一&#xff1a;增加超时机制&#xff0c;防止长期持有…...

MATLAB中实现机械臂逆运动学求解的方法之一是使用阻尼最小二乘法

MATLAB中实现机械臂逆运动学求解的方法之一是使用阻尼最小二乘法。阻尼最小二乘法通常用于处理数值求解问题中的不稳定性和噪声。以下是一个简单的MATLAB代码示例&#xff0c;演示了机械臂逆运动学的阻尼最小二乘法求解&#xff1a; % 机械臂参数 L1 1; % 机械臂长度 L2 1;…...

2024.1.24 GNSS 学习笔记

1.伪距观测值公式 2.载波相位观测值公式 3.单点定位技术(Single Point Positionin, SPP) 仅使用伪距观测值&#xff0c;不使用其他的辅助信息获得ECEF框架下绝对定位技术。 使用广播星历的轨钟进行定位&#xff0c;考虑到轨钟的米级精度&#xff0c;所以对于<1米的误差&…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

消息队列系统设计与实践全解析

文章目录 &#x1f680; 消息队列系统设计与实践全解析&#x1f50d; 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡&#x1f4a1; 权衡决策框架 1.3 运维复杂度评估&#x1f527; 运维成本降低策略 &#x1f3d7;️ 二、典型架构设计2.1 分布式事务最终一致…...

倒装芯片凸点成型工艺

UBM&#xff08;Under Bump Metallization&#xff09;与Bump&#xff08;焊球&#xff09;形成工艺流程。我们可以将整张流程图分为三大阶段来理解&#xff1a; &#x1f527; 一、UBM&#xff08;Under Bump Metallization&#xff09;工艺流程&#xff08;黄色区域&#xff…...

高保真组件库:开关

一:制作关状态 拖入一个矩形作为关闭的底色:44 x 22,填充灰色CCCCCC,圆角23,边框宽度0,文本为”关“,右对齐,边距2,2,6,2,文本颜色白色FFFFFF。 拖拽一个椭圆,尺寸18 x 18,边框为0。3. 全选转为动态面板状态1命名为”关“。 二:制作开状态 复制关状态并命名为”开…...