5-内核开发-/proc File System 学习

5-内核开发-/proc File System 学习

课程简介:
Linux内核开发入门是一门旨在帮助学习者从最基本的知识开始学习Linux内核开发的入门课程。该课程旨在为对Linux内核开发感兴趣的初学者提供一个扎实的基础,让他们能够理解和参与到Linux内核的开发过程中。

课程特点:
1. 入门级别:该课程专注于为初学者提供Linux内核开发的入门知识。无论你是否具有编程或操作系统的背景,该课程都将从最基本的概念和技术开始,逐步引导学习者深入了解Linux内核开发的核心原理。

2. 系统化学习:课程内容经过系统化的安排,涵盖了Linux内核的基础知识、内核模块编程、设备驱动程序开发等关键主题。学习者将逐步了解Linux内核的结构、功能和工作原理,并学习如何编写和调试内核模块和设备驱动程序。

3. 实践导向:该课程强调实践,通过丰富的实例和编程练习,帮助学习者将理论知识应用到实际的Linux内核开发中。学习者将有机会编写简单的内核模块和设备驱动程序,并通过实际的测试和调试来加深对Linux内核开发的理解。

4. 配套资源:为了帮助学习者更好地掌握课程内容,该课程提供了丰富的配套资源,包括教学文档、示例代码、实验指导和参考资料等。学习者可以根据自己的学习进度和需求,灵活地利用这些资源进行学习和实践。

无论你是计算机科学专业的学生、软件工程师还是对Linux内核开发感兴趣的爱好者,Linux内核开发入门课程都将为你提供一个扎实的学习平台,帮助你掌握Linux内核开发的基础知识,为进一步深入研究和应用Linux内核打下坚实的基础。

这一讲主要讲述如何/proc/ 文件系统


有时候,我们后端开发工程师经常会用各种命令去check Linux 服务器机器配置,例如命令:
cat /proc/cpuinfo ,cat /proc/meminfo 但是你想过他们的原理是怎么样的吗?今天讲的这个/proc 文件系统就与这个命令有关。让我们一起来浅显的了解下吧。(后面我们计划定义自己的基于 proc/原理的内核模块)


(1) 介绍

 /proc 文件系统是一个伪文件系统,它提供有关正在运行的 Linux 内核的信息。它最初旨在允许轻松访问有关进程的信息(因此得名),但现在它被内核的每一小
 部分使用,这些小部分有一些有趣的信息要报告。


(2) 常见文件

/proc 文件系统中的一些有用文件包括:

  • /proc/cpuinfo:包含有关 CPU 的信息,例如型号、速度和缓存大小。
  • /proc/meminfo:包含有关内存使用情况的统计信息,例如总内存量、已用内存量和空闲内存量。
  • /proc/uptime:包含有关系统已运行时间的统计信息。
  • /proc/loadavg:包含有关系统负载平均值的统计信息。
  • /proc/diskstats:包含有关磁盘活动和 I/O 统计信息的统计信息。
  • /proc/net/dev:包含有关网络设备和流量的统计信息。
  • /proc/version:包含有关正在运行的内核的版本和编译信息。

此外 /proc 文件系统还可以用于控制某些内核功能。例如,您可以使用 /proc/sys/kernel/printk
文件来更改内核日志记录级别,这个printk 前几节课程中的代码中多次用到。


/proc 文件系统是一个额外的机制,内核和内核模块可以使用它向进程发送信息。
它最初设计为一种轻松访问有关进程信息的方法(例如进程列表、状态和资源使用情况)。
现在,内核中的每个组件都可以使用 /proc 文件系统来报告任何有趣的信息。


内核是操作系统的核心,负责管理硬件、内存和进程。内核模块是可加载到内核中的代码模块,用于添加
额外的功能(例如设备驱动程序或文件系统支持)。

/proc 文件系统为内核和内核模块提供了一种与进程通信的方法。进程可以读取 /proc 文件系统中
的文件以获取有关内核和系统的信息。

因此,/proc 文件系统是一个非常有用的工具,可用于监视系统、诊断问题和控制内核行为。

(3)实现


那么如何实现一个简单的/proc 下的模块呢?


首先
(a)需要实现定义

 proc_ops proc_file_fops 
proc_dir_entry *our_proc_file; 

(a)模块初始化和清理函数:

procfs1_init():此函数在模块加载到内核时调用。它使用 proc_create() 函数创建 /proc/helloworld 文件。如果无法创建文件,该函数将打印错误消息并返回错误代码。
procfs1_exit():此函数在模块从内核卸载时调用。它使用 proc_remove() 函数删除 /proc/helloworld 文件。


(a)文件操作结构:

proc_file_fops:此结构定义了 /proc/helloworld 文件的文件操作。它包含一个条目 proc_read,该条目是处理来自用户空间程序的读取请求的函数。


(a)读取函数:

procfile_read():当用户空间程序从 /proc/helloworld 文件读取时调用此函数。它将字符串 "HelloWorld!\ " 复制到用户空间程序提供的缓冲区中。


全部代码如下:

hello.c 

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
#include <linux/version.h>

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
#define HAVE_PROC_OPS
#endif

#define procfs_name "helloworld"

static struct proc_dir_entry *our_proc_file;

static ssize_t procfile_read(struct file *file_pointer, char __user *buffer,
                             size_t buffer_length, loff_t *offset)
{
    char s[13] = "HelloWorld!\n";
    int len = sizeof(s);
    ssize_t ret = len;

    if (*offset >= len || copy_to_user(buffer, s, len)) {
        pr_info("copy_to_user failed\n");
        ret = 0;
    } else {
        pr_info("procfile read %s\n", file_pointer->f_path.dentry->d_name.name);
        *offset += len;
    }

    return ret;
}

#ifdef HAVE_PROC_OPS
static const struct proc_ops proc_file_fops = {
    .proc_read = procfile_read,
};
#else
static const struct file_operations proc_file_fops = {
    .read = procfile_read,
};
#endif

static int __init procfs1_init(void)
{
    our_proc_file = proc_create(procfs_name, 0644, NULL, &proc_file_fops);
    if (NULL == our_proc_file) {
        proc_remove(our_proc_file);
        pr_alert("Error:Could not initialize /proc/%s\n", procfs_name);
        return -ENOMEM;
    }

    pr_info("/proc/%s created\n", procfs_name);
    return 0;
}

static void __exit procfs1_exit(void)
{
    proc_remove(our_proc_file);
    pr_info("/proc/%s removed\n", procfs_name);
}

module_init(procfs1_init);
module_exit(procfs1_exit);

MODULE_LICENSE("GPL");

Makefile

obj-m += hello.o

CFLAGS := -Wall -O2

all:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

在 /proc 文件系统下创建的模块可以利用工作交互机理来处理来自用户空间进程的请求。

/proc 文件系统是一个伪文件系统,它允许用户空间进程访问内核信息和控制内核行为。在 /proc 文件系统下创建的模块可以导出文件和目录,用户空间进程可以通过这些文件和目录与模块进行交互。

当用户空间进程访问模块导出的文件时,模块可以安排一个工作请求来处理请求。工作请求将被添加到一个工作队列中,并且工作队列线程将执行工作请求。

例如,一个在 /proc 文件系统下创建的模块可以导出一个文件,该文件允许用户空间进程读取内核中的某个数据结构。当用户空间进程读取该文件时,模块可以安排一个工作请求来获取数据结构并将其内容复制到一个缓冲区中。工作队列线程将执行工作请求,并将数据复制到缓冲区中。然后,用户空间进程可以从缓冲区中读取数据。

通过这种方式,/proc 文件系统下的模块可以利用工作交互机理来处理用户空间进程的请求,而无需阻塞调用进程。

运行效果:

peach@peach-VirtualBox:~/ProcModule$ make
make -C /lib/modules/5.15.0-105-generic/build M=/home/peach/ProcModule modules
make[1]: Entering directory '/usr/src/linux-headers-5.15.0-105-generic'
  CC [M]  /home/peach/ProcModule/hello.o
  MODPOST /home/peach/ProcModule/Module.symvers
  CC [M]  /home/peach/ProcModule/hello.mod.o
  LD [M]  /home/peach/ProcModule/hello.ko
  BTF [M] /home/peach/ProcModule/hello.ko
Skipping BTF generation for /home/peach/ProcModule/hello.ko due to unavailability of vmlinux
make[1]: Leaving directory '/usr/src/linux-headers-5.15.0-105-generic'

执行安装 insmod  

然后验证:


(4)总结


总体而言,/proc 文件系统是一个非常有用的工具,可用于获取有关正在运行的 Linux 系统的信息和控制某些内核功能。

(5)参考

The Linux Kernel Module Programming Guide (sysprog21.github.io)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nacos采坑:非集群Nacos不要使用同一个MySQL数据库

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 Nacos 致力于帮助您…

第27章 筹集资金

< 回到目录 第六部分 流程 在各关键职能安排好了关键人员之后&#xff0c;公司有效运作&#xff0c;数据系统正常运行&#xff0c;经理和团队成员之间的双向信息交流顺畅。现在&#xff0c;剩下的就是你与外部世界的交流&#xff0c;包括与投资者、招聘者和客户的互动。这些…

银行买的黄金怎么卖出去?了解黄金交易的步骤和注意事项

黄金一直以来都是备受投资者关注的贵金属之一。银行提供了购买黄金的机会&#xff0c;但投资者也需要了解如何卖出银行买的黄金。 选择适合的购买方式 投资者可以通过多种途径购买黄金&#xff0c;其中包括银行提供的黄金交易服务。银行买黄金的方式可以是通过黄金交易账户、黄…

力扣HOT100 - 114. 二叉树展开为链表

解题思路&#xff1a; class Solution {List<TreeNode> list new ArrayList<>();public void flatten(TreeNode root) {recur(root);for (int i 1; i < list.size(); i) {TreeNode pre list.get(i - 1);TreeNode cur list.get(i);pre.left null;pre.right…

SpringBoot学习之Kafka下载安装和启动【Mac版本】(三十三)

一、配置Java环境变量 在启动Kafka之前,你需要先正确配置好你的Java环境变量。可以在终端输入java -version检查java环境变量是否配置正确,在Mac上如何配置java环境变量,请读者自行网上搜索操作之,此处不赘叙。 二、下载安装Kafka 1、下载Kafka:Apache Kafka,这两个版本…

python简易小时钟

import time import turtledef getTime():tt time.localtime() # 结构化的时间ss time.strftime(%Y年%m月%d日 %H:%M:%S, tt)return sspen turtle.Turtle()pen.backward(100) pen.speed(0)while True:time.sleep(1)times getTime()pen.clear()pen.write(times, font("…

中颖51芯片学习10. Touch Key触摸按键功能

中颖51芯片学习10. Touch Key触摸按键功能 一、SH79F9476 资源介绍1. 特性2. 系统框图&#xff1a;3.准备环境 二、准备工具三、开发步骤1. 新建项目流程&#xff08;1&#xff09;新建工程&#xff08;2&#xff09;选择芯片和封装&#xff08;3&#xff09;触摸配置按键&…

Tomcat架构设计精髓分析-Connector高内聚低耦合设计

优秀的模块化设计通常都会采用高内聚、低耦合 高内聚是指相关度比较高的功能要尽可能集中&#xff0c;不要分散。低耦合是指两个相关的模块要尽可能减少依赖的部分和降低依赖的程序&#xff0c;不要让两个模块产中强依赖。 Tomca连接器需要实现的功能: 监听网络端口 接受网络…

MATLAB将多张小图整合到一张大图形成模板图

MATLAB将多张小图整合到一张大图形成模板图 代码如下: clc;close all;clear all;warning off;%清除变量 rand(seed, 100); randn(seed, 100); format long g;foldername字符模板; [datacell,filenamecell,filenameAllcell]readfun_1n(foldername); K2length(filenamecell);% …

用友 GRP-U8 fastjson远程代码执行漏洞复现(XVE-2024-8863)

0x01 产品简介 用友GRP-U8R10行政事业内控管理软件是用友公司专注于国家电子政务事业,基于云计算技术所推出的新一代产品,是我国行政事业财务领域最专业的政府财务管理软件。 0x02 漏洞概述 用友 GRP-U8 R10系列版本 VerifyToken 接口存在低版本fastjson反序列化漏洞,未经…

ESP32环境下基于SD卡与FTP实现温湿度数据采集与存储

本篇文章将介绍如何利用ESP32开发板结合SD卡与FTP服务器功能&#xff0c;实现温湿度数据的实时采集、存储与远程访问。项目代码基于Arduino IDE平台编写&#xff0c;主要依赖于以下库&#xff1a; SPIDHTWiFitime.hESP-FTP-Server-LibSDSPIFFSFS 1. 硬件连接与配置 1.1 所需…

Python | Leetcode Python题解之第46题全排列

题目&#xff1a; 题解&#xff1a; class Solution:def permute(self, nums):""":type nums: List[int]:rtype: List[List[int]]"""def backtrack(first 0):# 所有数都填完了if first n: res.append(nums[:])for i in range(first, n):# 动…

漫谈AI 时代的信息模型

模型化- 数字化转型的重要基石 在各行各业推行数字化转型过程中&#xff0c;构建信息化模型十分重要&#xff0c;它是数字化转型的基石。事实上&#xff0c;数字化转型的核心是“万物皆模型”&#xff0c;在工业领域&#xff0c;以德国为主导的工业4.0 发展进程中&#xff0c;…

超越5G:迈向6G网络传感前沿的革命性飞跃

6G推动的传感技术发展有望将人类感官拓展到目前的极限。从精确测绘到活动识别&#xff0c;联网传感揭示了看不见的事物&#xff0c;使我们能够理解和预测以前未知的周围环境。高精度定位、增强人类感官和手势/活动识别的无缝集成预示着未来机器将以前所未有的自主性运行... 在飞…

安全AI未来 | C3安全大会 · 2024,数据驱动 AI原生

数字为时代变革注入动力&#xff0c;AI为重塑社会文明带来原力。数智浪潮中&#xff0c;我们见证着时代跃迁的巨变&#xff0c;面临着适变、应变、驭变的挑战。 数字驱动、AI原生。数字的流动不仅承载着信息&#xff0c;更将激活未来的无限价值&#xff1b;AI&#xff0c;不…

为什么要写技术方案?

技术方案是为研究解决各类技术问题&#xff0c;有针对性&#xff0c;系统性的提出的方法、应对措施及相关对策。技术方案设计是一个技术开发者必备的能力&#xff0c;特别是对于高级、资深、架构师等角色。技术方案设计不仅能够帮助我们明确需求&#xff0c;规划架构&#xff0…

【数据库】三、数据库SQL语言命令(基础从入门到入土)

【全文两万多字&#xff0c;涵盖大部分常见情况&#xff0c;建议点赞收藏】 目录 文章目录 目录安装SQL语言1.使用2.DATABASE查看所有库新建数据库修改数据库删除数据库连接数据库 3.TABLE创建表查看库所有表删除表查看表信息重命名表修改表字段&#xff08;列&#xff09;表中…

自动批量将阿里云盘文件发布成WordPress文章脚本源码(以RiPro主题为例含付费信息下载地址SEO等自动设置)源码

背景 很多资源下载站&#xff0c;付费资源下载站&#xff0c;付费内容查看等都可以用WordPress站点发布内容&#xff0c;这些站点一般会基于一个主题&#xff0c;付费信息作为文章附属的信息发布&#xff0c;底层存储在WP表里&#xff0c;比如日主题&#xff0c;子比主题等。 …

js的算法-插入排序(直接插入排序)

插入排序 插入排序是一种简单直接的排序方法&#xff0c;其基本思想是每次将一个待排序的记录按其关键字大小插入到前面已经排好序的子序列&#xff0c;直到全部记录插入完成。由插入排序的思想可以引申出三个重要的排序算法&#xff1a; 直接插入排序、折半插入排序和希尔排序…

一份本金 能得两份利息?

构建完善的量化交易策略&#xff0c;需要了解多种交易标的。有的产品在特殊时间可以产生超额收益。 1天期的国债逆回购的手续费为万0.1。 看似较低&#xff0c;因为每笔最小手续费是0.1元&#xff0c;如果投资者买入的金额较小&#xff08;比如小于1w&#xff09;&#xff0c;…