使用proc文件系统和内核交互

​ 详解Linux内核通信-proc文件系统 使用 /proc 文件系统来访问 Linux 内核的内容,这个虚拟文件系统在内核空间和用户空间之间打开了一个通信窗口:/proc 文件系统是一个虚拟文件系统,通过它可以使用一种新的方法在 Linux内核空间和用户间之间进行通信。在 /proc 文件系统中,我们可以将对虚拟文件的读写作为与内核中实体进行通信的一种手段,但是与普通文件不同的是,这些虚拟文件的内容都是动态创建的。本文对 /proc 虚拟文件系统进行了介绍,并展示了它的用法。最初开发 /proc 文件系统是为了提供有关系统中进程的信息。 阅读详情
《使用proc文件系统和内核交互》
本文档的Copyleft归rosetta所有,使用GPL发布,可以自由拷贝、转载,转载时请保持文档的完整性。
参考资料:IBM developerWorks 《使用/proc文件系统来访问Linux内核的内容》、Linux-2.6.10内核
来源:http://blog.youkuaiyun.com/rosetta/article/details/7563610

    此篇是在《内核模块编写》和《字符设备驱动程序编写基础》基础上写的,但这篇也是基础文章。使用proc文件系统与内核数据交互和之前写的《字符设备驱动程序编写基础》原理非常相似,只不过前者使用的是内核提供给/proc文件系统的一组专用函数,所以本节主要介绍如何使用这组函数,具体原理学习可参考给出的链接。
    可能大家都使用过cat /proc/cpuinfo(meminfo)来查看系统cpu或内存信息,或者也注意到在/proc目录中存在所有以ps -ef进程号为命令的目录,在所有对应的进程号目录中都有许多和该进程相关的文件,具体是些什么文件我不能用最确切的语言来描述或者定义,但我可以肯定的一点是这些文件应该都是由内核里反馈出来的,比如进入某个文件夹,可以cat 对应的status、maps、limits来看看到底包含什么。
    下面首先例出这组函数,再给出一个例子。
一、相关函数和结构体
  1,struct proc_dir_entry *proc_mkdir(const char *name,
        struct proc_dir_entry *parent)//在parent目录创建一个名为name的目录。
   比如:struct proc_dir_entry *proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net);//在proc_net目录创建名为ipsec的目录
  其中proc_net相当于宏,指/proc/net目录,如果第二个参数传NULL,即指默认/proc目录。以下是几个类似的宏。
    proc_root_fs /proc
    proc_net /proc/net
    proc_bus /proc/bus
    proc_root_driver /proc/driver
  2,再继续第二个函数之前有必要先说下porc_mkdir的返回值,它是一个结构体struct pro_dir_entry
  struct proc_dir_entry {
    unsigned int low_ino;
    unsigned short namelen;
    const char *name;
    mode_t mode;
    nlink_t nlink;
    uid_t uid;
    gid_t gid;       
    unsigned long size;
    struct inode_operations * proc_iops;
    struct file_operations * proc_fops;
    get_info_t *get_info;
    struct module *owner;
    struct proc_dir_entry *next, *parent, *subdir;
    void *data;
    read_proc_t *read_proc;
    write_proc_t *write_proc;
    atomic_t count;     /* use count */
    int deleted;        /* delete flag */
  };
  里面包含了一个文件(Linux把所有对象都当文件看代,目录当然也是一个文件)所有属性,比如:文件名、权限、uid、gid、前一级目录、包含的子目录等等,我记得在APUE2e在讲解文件系统时讲到过,所以可以结合上面内容进行理解。
  这次我们不对这些属性感兴趣,主要是关注下目录的读写函数,即read_proc和write_proc,一会例子中会提到。
  3,struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
                     struct proc_dir_entry *parent)//在parent目录创建一个名为name,权限为mode的文件。
    比如:struct proc_dir_entry * item = create_proc_entry("klipsdebug", 0400, "/proc/ipsec")//在/proc/ipsec目录创建一个权限为0400(只读)的文件klipsdebug
  4,create_proc_entry执行后返回的proc_dir_entry可以自己指定read、write等函数,如果只需要read函数,可以使用
    static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
    mode_t mode, struct proc_dir_entry *base,
    read_proc_t *read_proc, void * data)
    它其实是对create_proc_entry进行了封装,把create_proc_read_entry的传入值read_proc赋给了create_proc_entry返回值的read_proc成员,具体可看内核实现。
  5,struct proc_dir_entry *proc_symlink( const char *name,
                                       struct proc_dir_entry *parent,
                                       const char *dest );//在parent目录创建指定dest目录的名为name的符号链接。
  比如: proc_symlink("ipsec_eroute", proc_net, "ipsec/eroute/all");//在/proc/net创建指向/proc/net/ipsec/eroute/all的符号链接ipsec_eroute。
  6,void remove_proc_entry( const char *name, struct proc_dir_entry *parent );//删除parent目录中的名为name的文件
  7,还有两上函数比较重要,就是之前提到的read、write函数中需要调用的函数,这两个函数即完成了用户空间和内核空间的数据交互。
  unsigned long copy_to_user( void __user *to,
                              const void *from,
                              unsigned long n );//

  unsigned long copy_from_user( void *to,
                                const void __user *from,
                                unsigned long n );

二、给出一个具体的例子以便理解,偷懒起见,直接copy链接处的例子,为保证代码完整性,作者及说明在代码中有所体现。

  //proc_study.c
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/proc_fs.h>
  #include <linux/string.h>
  #include <linux/vmalloc.h>
  #include <asm/uaccess.h>
  MODULE_LICENSE("GPL");
  MODULE_DESCRIPTION("Fortune Cookie Kernel Module");
  MODULE_AUTHOR("M. Tim Jones");
  #define MAX_COOKIE_LENGTH       PAGE_SIZE
  static struct proc_dir_entry *proc_entry;
  static char *cookie_pot;  // Space for fortune strings
  static int cookie_index;  // Index to write next fortune
  static int next_fortune;  // Index to read next fortune
 
  int fortune_read( char *page, char **start, off_t off,
                             int count, int *eof, void *data )
  {
      int len;
      if (off > 0) {
          *eof = 1;
          return 0;
      }
 
      /* Wrap-around */
      if (next_fortune >= cookie_index)
          next_fortune = 0;
 
      len = sprintf(page, "%s\n", &cookie_pot[next_fortune]);
      next_fortune += len;
 
      return len;
  }
 
  ssize_t fortune_write( struct file *filp, const char __user *buff,
                                  unsigned long len, void *data )
  {
      int space_available = (MAX_COOKIE_LENGTH-cookie_index)+1;
      if (len > space_available) {
          printk(KERN_INFO "fortune: cookie pot is full!\n");
          return -ENOSPC;
      }
 
      if (copy_from_user( &cookie_pot[cookie_index], buff, len )) {
          return -EFAULT;
      }
 
      cookie_index += len;
      cookie_pot[cookie_index-1] = 0;
 
      return len;
  }
 
  int init_fortune_module( void )
  {
      int ret = 0;
      cookie_pot = (char *)vmalloc( MAX_COOKIE_LENGTH );
      if (!cookie_pot) {
          ret = -ENOMEM;
      } else {
          memset( cookie_pot, 0, MAX_COOKIE_LENGTH );
          proc_entry = create_proc_entry( "fortune", 0644, NULL );
          if (proc_entry == NULL) {
              ret = -ENOMEM;
              vfree(cookie_pot);
              printk(KERN_INFO "fortune: Couldn't create proc entry\n");
          } else {
              cookie_index = 0;
              next_fortune = 0;
              proc_entry->read_proc = fortune_read;
              proc_entry->write_proc = fortune_write;
              proc_entry->owner = THIS_MODULE;
              printk(KERN_INFO "fortune: Module loaded.\n");
          }
      }
 
      return ret;
  }
 
  void cleanup_fortune_module( void )
  {
      remove_proc_entry("fortune", &proc_root);
      vfree(cookie_pot);
      printk(KERN_INFO "fortune: Module unloaded.\n");
  }
 
  module_init( init_fortune_module );
  module_exit( cleanup_fortune_module );

  //Makefile 自己改的一个Makefile
  #ifneq ($(KERNELRELEASE),)
    obj-m := my_proc.o
    my_proc-objs := proc_study.o
  #else
  KERNELDIR ?= /lib/modules/$(shell uname -r)/build
  PWD := $(shell pwd)
 
  default:
      $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
 
  clean:
      rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
      rm -rf Module.* modules.*
 
  .PHONY: default clean
  #endif

  编译生成my_proc.ko
  下面来测试下:
  [root@xxx proc]# ls /proc/fortune -al
  -rw-r--r-- 1 root root 0 05-13 16:23 /proc/fortune

  [root@xxx proc_study]# insmod my_proc.ko
  [root@xxx proc_study]# dmesg
  fortune: Module loaded.
  [root@xxx proc]# echo "Hello, Just a test" > /proc/fortune
  [root@xxx proc]# echo "Secondary test" > /proc/fortune  
  [root@xxx proc]# ls /proc/fortune  -al                     
  -rw-r--r-- 1 root root 0 05-01 07:04 /proc/fortune
  [root@xxx proc]# cat /proc/fortune
  Secondary test
  [root@xxx proc]# cat /proc/fortune

  [root@xxx proc_study]# rmmod my_proc
  [root@xxx proc_study]# dmesg
  fortune: Module loaded.
  fortune: Module unloaded.
 




5-内核开发-/proc File System 学习 proc 文件系统是一个伪文件系统,它提供有关正在运行的 Linux 内核的信息。它最初旨在允许轻松访问有关进程的信息(因此得名),但现在它被内核的每一小部分使用,这些小部分有一些有趣的信息要报告。总体而言,/proc 文件系统是一个非常有用的工具,可用于获取有关正在运行的 Linux 系统的信息和控制某些内核功能。 阅读详情

相关推荐

对/proc文件系统进行读写操作

http://edsionte.com/techblog/archives/3030/comment-page-1   本博客之前的文章中多次涉及到/proc文件系统,下面的几条命令都在曾经的文章中出现过: view source print? 1 cat /proc/interrupts 2 cat /pro

tycoon的专栏 1895

使用proc文件映射的方式实现用户态跟内核态的数据交互

我们一般的应用程序都是直接跑在用户态的,Lin

WHW的博客 2252

深入理解Linux proc文件系统

和为管理员提供了强大的工具来管理和监控系统进程。通过这些接口,可以获取进程的详细信息、状态和资源使用情况,从而有效地进行进程管理、性能监控和故障排查。这一章节详细介绍了如何利用这些接口进行系统监控和进程管理,确保系统的健康和稳定性。

weixin_42613018的博客 1234

linux proc 文件怎样传入内核的,使用 /proc 文件系统来访问 Linux 内核的内容

内核程序员可以使用的标准 API,LKM 程序员也可以使用。LKM 甚至可以导出内核使用的新变量和函数。有关 API 的完整介绍已经超出了本文的范围,因此我们在这里只是简单地介绍后面在展示一个更有用的 LKM 时所使用的几个元素。要在 /proc 文件系统中创建一个虚拟文件,请使用 create_proc_entry 函数。这个函数可以接收一个文件名、一组权限和这个文件在 /proc 文件系统中出...

weixin_42443651的博客 298

proc文件系统的实现

实验要求: 掌握虚拟文件系统的实现原理 实践文件、目录、索引节点等概念 操作系统的一个实验题目

实验八-proc文件系统的实现.zip

实验八-proc文件系统的实现,一、问题回答 1.如果要求你在psinfo之外再实现另一个结点,具体内容自选,那么你会实现一个给出什么信息的结点?为什么? 答:我会给出CPU的当前信息。因为CPU的信息也是一个重要的计算机参数,用户得到这个参数,就可以知道比如当前进程总数、CPU寄存器的状态等等信息,方便用户了解系统的信息。而linux0.11中没有方便查看这个参数的命令,所以加上这个参数会比较有价值。

开发中proc文件系统的简单使用

在Linux系统中, “/proc”文件系统十分有用, 它被内核用于向用户导出信息。“/proc”文件系统是一个虚拟文件系统, 通过它可以在Linux内核空间和用户空间之间进行通信。在/proc文件系统中, 我们可以将对虚拟文件的读写作为与内核中实体进行通信的一种手段, 与普通文件不同的是, 这些虚拟文件的内容都是动态创建的。“/proc”下的绝大多数文件是只读的, 以显示内核信息为主。

weixin_52849254的博客 1709

opencv+nvcodec实现视频硬解码

最近遇到一个新项目,AI推理在上,为了方便和节省成本的考虑决定研究下模块。根据官网的说法显卡具有独立的和模块,所以理论上和是独立互不干涉的。以前的项目都只是把显卡当成推理工具,没有将它的功能利用起来,本身也是一种浪费。事实真的有这么丝滑吗?看到这里,如果你真的觉得是白叫的那就真的是了,事实究竟如何,请听我娓娓道来。NVCODEC全称是 NVIDIA VIDEO CODEC,是NVIDIA为绝大多数显卡配置的硬件编解码单元。不一定是所有显卡都有,一般来讲越新的显卡硬件编解码就越强,支持的格式也就越新。

jiexijihe945的博客 1万+

proc系统文件及编程

1 proc 简介        1)/proc               Linux内核提供的一种通过/proc系统文件,可在运行时访问内核内部数据结构、改变内核设置机制。               Proc是一种伪文件系统,只在内存中存在,不占用外村空间。以文件系统访问形式向外提供接口。  2)proc_dir_entry 结构                     struc

Keep your mind running!!! 876

VTK实战笔记(1)在win11搭建VTK-9.4.2 + qt5.15.2 + VS2019_x64开发环境

Visual Studio 2019 + qt5.15.2 + vtk9.4.2

心向阳光,斗志昂扬! 975

AxMath行间公式转化为office公式求和符号以及编号显示问题

AxMath行间公式转化为office公式求和符号以及编号显示问题问题描述解决方法 问题描述 首先打出axmath公式,如下: 转换后的OfficeMath公式: 字体先不说,word公式字体默认cambria math且无法编辑。比较难受的一点是求和符号与后面的 ai+bi2a_i+b_i^2ai​+bi2​比例不匹配啊!正常的比例应该是: (虽然也不太正常,将就下) 解决方法 点击变换后的office公式右侧,选择更改为"显示" 可以看到,多了一些软回车符号(⬇),如果你想删除它,不要直接选中

weixin_43543177的博客 4649

【转载】 使用proc文件系统和内核交互

《使用proc文件系统和内核交互》本文档的Copyleft归rosetta所有,使用GPL发布,可以自由拷贝、转载,转载时请保持文档的完整性。参考资料:IBM developerWorks 《使用/proc文件系统来访问Linux内核的内容》、Linux-2.6.10内核来源:http://blog.youkuaiyun.com/rosetta/article/details/7563610 ...

anren7769的博客 144

Maya绑定:人物绑定详细案例(创建骨骼、镜像骨骼、IK创建、IK打组、IK控制器、FK控制器、烘焙动画、导出)

Maya绑定:人物绑定详细案例(创建骨骼、镜像骨骼、IK创建、IK打组、IK控制器、FK控制器、烘焙动画、导出)

m0_45877477的博客 1632

如何使用proc文件系统让用户空间和内核空间进行交互

参考:http://www.ibm.com/developerworks/cn/linux/l-proc.html下面再给出一个proc系统中write_proc函数的例子:static int usb_power = 1;static int usb_proc_write(struct file* file, const char* buffer, unsigned long c

gqwang2005的专栏 872

记录一下本地部署Dify的坑

1. 截止2025-3-4为止,请注意,不要直接拉Dify的1.0.0版本。请先试用0.15.3版本。1.0.0有一个bug需要解决。3. 请使用docker-ce 新版本,docker-engine等老版本可能会有部分容器启动脚本执行莫名报错。2. 注意,请使用docker-compose V2版本,或者V1较高版本,否则会导致解析官方yml模板错误。

哈利路亚的收藏夹 5346

win10和Mac上安装Freesurfer

Mac安装Freesurfer 软件下载地址 可以根据官方给出的demo视频一步一步下载

Daily_365的博客 6077

proc文件系统

proc文件系统是一种虚拟文件系统,其信息不能从块设备读取。只有在读取文件内容时才动态生成响应的信息。使用proc文件系统,可以获得有关内核各子系统的信息(如内存利用率、附接的外设等),也可以在不重新编译内核源代码的情况下修改内核的行为,或重启系统。 proc文件系统提供一种接口,可用于该机制导出所有选项,直接地修改参数无需开发专门程序,只需要一个shell和标准的cat、echo即可。 /proc信息 信息可以分为一下几类: 内存管理,系统进程的特征数据,文件系统,设备驱动程序,系统总线,电源管理,终端,

weixin_42097108的博客 1161

S32K144 UDSdoCAN 升级刷写实现笔记

本篇旨在描述如何开发“车规级”的软件升级程序,通过在S32K144平台上实现基于UDSdoCAN的刷写升级功能,带你一步步建立安全升级的“工程思维”,在这里既能收获经验还能获得工程源码、测试脚本,助你起飞,避坑提速!

汽车电子软件领域知识分享 811

proc文件系统读取

Proc文件系统读取在以前的版本:(copy 学长的)在一般的情况下,需要以下函数:““c struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent)struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,

znr1995的博客 2631

LVGL 蜂巢气泡菜单(Hex Menu)

h。

摸鱼专家 176

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

linux proc 文件系统

proc文件系统源码分析

weird213的博客 1493

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

linux driver和 /proc 文件的交互

static int agile_proc_read(struct seq_file *m, void *v) { char user_str[20] = "user string"; seq_printf(m, "%s\n", user_str); return 0; } static int agile_proc_open(struct inode *inode, struct file *file) { // malloc seq_operations 并初始化; 参3:传递priv...

weixin_40209911的博客 977

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

proc文件系统解析

proc文件系统解析 (1)proc文件系统简介         最初开发 /proc 文件系统是为了提供有关系统中进程的信息。但是由于这个文件系统非常有用,因此内核中的很多元素也开始使用它来报告信息,或启用动态运行时配置。         /proc 文件系统包含了一些目

ylyuanlu的专栏 1700

Linux中的/proc文件操作

广州大学Linux实验3文件操作实验内容:编写一个内核模块,在/proc文件系统中增加一个目录hello,并在这个目录中增加一个文件world,文件的内容为hello world。

jojojojoi的博客 614

[Linux] 内核的 /proc 文件系统介绍及使用方法

内核现在采用的是 sysfs 文件系统。 在 sysfs 诞生之前我们采用的是 proc 文件系统。 sysfs 是一个与 /proc 类似的文件系统,但是它的组织更好(从 /proc 中学习了很多教训)。不过 /proc 已经确立了自己的地位,因此即使 sysfs 与 /proc 相比有一些优点,/proc 也依然会存在。本文对 /proc 文件系统一些基础的知识进行归纳和整理。

Younix凌乱的草稿本 1万+

创建linux内核proc文件并与用户空间接口

创建proc文件并与用户空间接口

Android8.x和Android9.x平台user版本打开UART输出并支持控制台输入和user版本adb root的方法 2864
上一篇: 字符设备驱动程序编写基础
下一篇: ifconfig源码分析之与内核交互数据
sweird
博客等级 码龄20年 336粉丝 103原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值