proc文件系统怎么玩?

简介: proc文件系统怎么玩?

前言

最近在做测试,怎么实现的呢?通过实现了一个KO,然后KO加载后就会注册一个proc节点。然后通过echo给这个节点进行输入指令,调用对应的文件节点,最后实现测试的函数调用。

这里对proc这个东西一直感觉很神奇,很多cat、cpu等信息都可以从里面获取到。于是这里来看看这个文件系统。

1、什么是proc文件系统

  • (1) proc是虚拟文件系统,虚拟的意思就是proc文件系统里的文件不对应硬盘上任何文件,我们用去查看proc目录下的文件大小都是零;
  • (2) proc文件系统是开放给上层了解内核运行状态的窗口,通过读取proc系统里的文件,可以知道内核中一些重要数据结构的数值,从而知道内核的运行情况,也可以方便调试内核和应用程序;
  • (3) proc文件系统的思路:在内核中构建一个虚拟文件系统/proc,内核运行时将内核中一些关键的数据结构以文件的方式呈现在/proc目录中的一些特定文件中,这样相当于将不可见的内核中的数据结构以可视化的方式呈现给内核的开发者
  • (4) proc文件系统是一种无存储的文件系统,当读其中的文件时,其内容动态生成当写文件时,文件所关联的写函数被调用每个proc文件都关联的字节特定的读写函数,因而它提供了另外的一种和内核通信的机制内核部件可以通过该文件系统向用户空间提供接口来提供查询信息修改软件行为,因而它是一种比较重要的特殊文件系统。

2、常见的proc文件介绍

3、和sys文件系统的比较

  • (1)proc文件系统主要是用来调试内核,在内核运行时可以知道内核中一些重要的数据结构的值,一般都是读很少写;
  • (2)proc文件系统出现的比sys文件系统早,proc文件系统的目录结构比较乱,在proc文件系统下面有很多文件夹,比如一个进程就有一个文件夹,现在内核越来越复杂,支持的设备类型也越来越多,显得很混乱;于是又开发出了sys系统,sys系统可以说是proc的升级,将来用sys系统会是主流;
  • (3)proc文件系统和sys文件系统都是虚拟系统,并且有对应关系,比如"/proc/misc"对应于"sys/class/misc"下面的设备,都是描述misc类设备的;

4、怎么注册一个proc文件系统的节点

Linux系统上的/proc目录是一种文件系统,即proc文件系统(procfs),它以文件系统的方式为用户提供访问系统内核数据的操作接口。

proc文件系统是一种内核和内核模块用来向进程(process)发送信息的机制,因此被称为proc。

与其它常见的文件系统不同的是,proc是一种伪文件系统(也即虚拟文件系统),它只存在于内存当中,因此它会在系统启动时创建并挂载到/proc目录,在系统关闭时卸载并释放。

下面是设备上/proc的挂载信息。

$ mount | grep proc
proc on /proc type proc (rw,relatime)

proc文件系统存储的是当前内核运行状态的一系列特殊文件,用户可以通过这些文件查看系统和进程的信息,或者改变内核的运行状态,因此可以把它视为Linux内核开放给用户的控制和信息中心。实际上,proc文件系统是内核空间和用户空间之间的一种通信媒介。

使用proc_create实例分析

proc虚拟文件系统也可以创建虚拟文件节点,实现用户空间与内核空间的交互。

在驱动中创建节点,可以实现对硬件的控制。proc_create函数原型(在kernel-3.10/include/linux/proc_fs.h文件)如下所示:

1-proc_create函数原型

static inline struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops)
{
    return proc_create_data(name, mode, parent, proc_fops, NULL);
}
  • name:表示你要创建的设备节点的名称,可随意命名即可;
  • mode:表示节点的权限,一般赋值0644;
  • parent:表示父节点,如果直接在proc目录创建节点,直接赋值NULL即可;
  • proc_fops:表示与节点相关联的file_operations;

如下代码是我实现的一个test程序,可供参考学习proc_create的使用:

2-test 实例

#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/wait.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/pinctrl/consumer.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#define BUFSIZE  1024 
static char *buf;
static unsigned int len;
/***********************
 * file_operations->open
 * 无操作
 ***********************/
static int test_proc_open(struct inode *inode, struct file *file)
{
    return 0;
}
/************************
 * file_operations->read
 * 可以在adb工具进入机器的pro目录,执行adb shell && cd proc && cat tets_rw,
 * 即可读出节点test_rw的内容是12345
 ************************/
static ssize_t test_proc_read(struct file *file,
                char __user *buffer,size_t count, loff_t *f_pos) 
{
    if(*f_pos > 0)
        return 0;
printk("---start read---\n");
    printk("the string is >>>>> %s\n", buf);
if(copy_to_user(buffer, buf, len))
        return -EFAULT;
    *f_pos = *f_pos + len;
    return len;
}
/************************
 * file_operations->write
 * 可以在adb工具进入机器的pro目录,
 * 执行adb shell && cd proc && echo 12345 > tets_rw,即可把12345写入节点test_rw
 ************************/
static ssize_t test_proc_write(struct file *file, const char __user *buffer,
                                        size_t count, loff_t *f_pos) 
{
if(count <= 0)
        return -EFAULT;
    printk("---start write---\n");
len = count > BUFSIZE ? BUFSIZE : count;
// kfree memory by kmalloc before
    if(buf != NULL)
        kfree(buf);
    buf = (char*)kmalloc(len+1, GFP_KERNEL);
    if(buf == NULL)
    {
        printk("test_proc_create kmalloc fail!\n");
        return -EFAULT;
    }
//memset(buf, 0, sizeof(buf));
    memset(buf, 0, len+1);
if(copy_from_user(buf, buffer, len))
        return -EFAULT;
    printk("test_proc_write writing :%s",buf);
    return len;
}
static struct file_operations test_fops = {
    .owner  = THIS_MODULE,
    .open   = test_proc_open,
//  .release = single_release,
    .read   = test_proc_read,
//  .llseek = seq_lseek,
    .write  = test_proc_write,
};
static int __init test_init(void)
{
    struct proc_dir_entry* file;
//创建proc文件并关联file_operations
    file = proc_create("test_rw", 0644, NULL, &test_fops);
    if (!file)
        return -ENOMEM;
    printk("test_rw init success!\n");
    return 0;
}
static void __exit test_exit(void)
{
    remove_proc_entry("test_rw", NULL);
    printk("test_exit\n");
}
module_init(test_init);
module_exit(test_exit);
MODULE_AUTHOR("caizd");
MODULE_DESCRIPTION("Proc_create Test Driver");
MODULE_LICENSE("GPL");

3-试一下

可以将上面的代码编译成一个ko,然后编近kernel,然后验证。

root@inwatch_portal:/ # cd proc
cd proc
root@inwatch_portal:/proc # echo 12345 > test_rw
echo 12345 > test_rw
root@inwatch_portal:/proc # cat test_rw
cat test_rw
12345

5、怎么编译成ko

单独整一篇算了!!!

https://zhuanlan.zhihu.com/p/584749553

https://www.elecfans.com/emb/202210101902598.html

https://zhuanlan.zhihu.com/p/584749553

https://zhuanlan.zhihu.com/p/557870063

目录
相关文章
|
2月前
|
存储 安全 Linux
sysfs - 用于导出内核对象的_文件系统 【ChatGPT】
sysfs - 用于导出内核对象的_文件系统 【ChatGPT】
|
存储 缓存 Linux
sysfs文件系统(1)
sysfs是一种虚拟文件系统,旨在提供一种访问内核数据结构的方法,从而允许用户空间程序查看和控制系统的设备和资源。sysfs文件系统通常被挂载在/sys目录下。sysfs提供了一种以树状结构组织的系统信息的方式,其中每个设备都有一个唯一的目录来表示它自己,其中包含有关设备的各种属性和状态信息的文件。这些文件通常是只读的,但有些也可以用于修改设备的某些设置。sysfs还提供了一个机制来通知用户空间程序有关设备状态更改的信息,从而使其能够对这些更改做出反应。sysfs文件系统被广泛用于Linux内核中,它为开发者提供了一种简单的方式来管理和控制系统中的各种设备和资源。
200 0
|
存储 缓存 Linux
从 lsof 开始,深入理解虚拟文件系统
从 lsof 开始,深入理解虚拟文件系统
79 0
|
Linux 程序员 Shell
sysfs文件系统与kobject
sysfs文件系统与kobject
163 0
|
前端开发 Linux
Linux进程管理作业控制及虚拟文件系统
作业控制是一个命令行功能,也叫后台运行。
92 0
|
Unix Linux 容器
sysfs文件系统(2)
每个内核设备直接或间接嵌入kobject属性。在添加到系统之前,必须使用kobject_ create()函数分配kobject,并将已经分配但尚未初始化的kob ject指针及其kobject_type 指针作为参数。kobject_add()函数用于添加kobject并将其链接到系统,同时根据其层次结构创建目录及其默认属性。功能与之相反的函数是kobject_ del(),将kobject删除链接
119 0
|
缓存 Linux Shell
虚拟文件系统
Linux内核中的虚拟文件系统用来管理挂接各种具体文件系统。具体的文件系统可设计成可加载模块,在系统需要时进行加载。 挂载具体文件系统时,VFS读取它的超级块,得到具体文件系统的拓扑结构,并将这些信息映射到VFS超级块结构中。
1011 1