How does the proc file system work?

foreword

I'm doing a test recently, how did it come true? By implementing a KO, a proc node will be registered after the KO is loaded. Then input instructions to this node through echo, call the corresponding file node, and finally realize the function call of the test.

The proc thing here has always been amazing, and a lot of cat, cpu and other information can be obtained from it. So here is a look at the file system.

1. What is the proc file system

  • (1) proc is a virtual file system . Virtual means that the files in the proc file system do not correspond to any files on the hard disk . We use it to check that the file size in the proc directory is zero;

  • (2) The proc file system is a window open to the upper layer to understand the running status of the kernel . By reading the files in the proc system, you can know the values ​​of some important data structures in the kernel , so as to know the running status of the kernel, and it is also convenient to debug the kernel and application;

  • (3) The idea of ​​the proc file system: build a virtual file system /proc in the kernel. When the kernel is running, some key data structures in the kernel will be presented as files in some specific files in the /proc directory, which is equivalent to Visually present the invisible data structures in the kernel to the kernel developer .

  • (4) The proc file system is a non-storage file system. When a file is read, its content is dynamically generated . When a file is written, the write function associated with the file is called . Each proc file is associated with a byte-specific read and write function , so it provides another mechanism for communicating with the kernel : the kernel component can provide an interface to the user space through the file system to provide query information , modify software behavior , Therefore it is a more important special file system.

2. Introduction to common proc files

insert image description here

3. Comparison with the sys file system

  • (1) The proc file system is mainly used to debug the kernel . When the kernel is running, you can know the values ​​of some important data structures in the kernel, which are generally read and seldom written;

  • (2) The proc file system appeared earlier than the sys file system . The directory structure of the proc file system is relatively chaotic. There are many folders under the proc file system. For example, a process has a folder. Now the kernel is becoming more and more complicated. There are more and more types of equipment, which is very confusing; so the sys system was developed, which can be said to be an upgrade of proc, and the sys system will be the mainstream in the future;

  • (3) Both the proc file system and the sys file system are virtual systems and have a corresponding relationship. For example, "/proc/misc" corresponds to the devices under "sys/class/misc", both of which describe misc-type devices;

4. How to register a node of the proc file system

The /proc directory on the Linux system is a file system, namely the proc file system (procfs), which provides users with an operating interface to access system kernel data in the form of a file system.

The proc filesystem is a mechanism used by the kernel and kernel modules to send information to processes , hence the name proc.

Unlike other common file systems, proc is a pseudo file system (that is, a virtual file system), which only exists in memory , so it will be created and mounted to the /proc directory when the system starts, in the system Unload and release on shutdown.

Below is the mount information for /proc on the device.

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

The proc file system stores a series of special files of the current kernel running state. Users can view the information of the system and processes through these files, or change the running state of the kernel. Therefore, it can be regarded as the control and information that the Linux kernel opens to users . center . In fact, the proc file system is a communication medium between kernel space and user space.

insert image description here

Use proc_create instance analysis

The proc virtual file system can also create virtual file nodes to realize the interaction between user space and kernel space.

Create nodes in the driver to control the hardware. The proc_create function prototype (in the kernel-3.10/include/linux/proc_fs.h file) is as follows:

1-proc_create function prototype

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: Indicates the name of the device node you want to create, you can name it at will;
  • mode: Indicates the authority of the node, generally assigned a value of 0644;
  • parent: Indicates the parent node. If you create a node directly in the proc directory, you can directly assign NULL;
  • proc_fops: indicates the file_operations associated with the node;

The following code is a test program I implemented, which can be used as a reference to learn how to use proc_create:

2-test instance

#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- Try it out

The above code can be compiled into a ko, then compiled into a kernel, and then verified.

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. How to compile into ko

Just write a whole article alone! ! !

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

Guess you like

Origin blog.csdn.net/weixin_45264425/article/details/130393838