procfs文件系统

 
用户空间和内核空间交互方式有:文件I/O,ioctl、procfs、debugfs、sysfs等
 
procfs 是 Linux 内核中的一个虚拟文件系统,通常挂载在 /proc 目录下,用于向用户空间提供内核状态信息和运行时数据。通过 procfs,用户可以访问和操作内核的各种参数、统计数据、进程信息等,而无需直接访问内核数据结构或重新编译内核。
以下是 procfs 的一些主要特点和用途:
  1. 提供内核信息:
procfs 提供了访问内核信息的接口,用户可以读取和修改内核运行时的参数、状态信息等。
  1. 进程信息:
在 /proc 目录下,每个数字命名的子目录对应一个正在运行的进程,其中包含该进程的信息,如状态、命令行参数、文件描述符等。
  1. 系统信息:
用户可以通过 procfs 获取系统的各种信息,比如 CPU 信息、内存使用情况、设备信息等。
  1. 动态调试:
procfs 提供了方便的接口,用于动态调试和跟踪内核和进程的状态,例如通过 /proc/sys/kernel 目录可以调整内核参数。
  1. 性能分析:
通过 procfs,用户可以获取系统性能数据,如 CPU 使用率、内存占用情况等,用于性能分析和优化。
 
proc常用API:
  1. create_proc_entry / proc_create:用于创建一个新的 procfs 文件。原型如下:
  • struct proc_dir_entry *create_proc_entry(const char *name, umode_t mode, struct proc_dir_entry *parent);
  • struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops);
  1. remove_proc_entry:用于删除一个已存在的 procfs 文件。
  • void remove_proc_entry(const char *name, struct proc_dir_entry *parent_dir);
  1. proc_mkdir:用于创建一个新的 procfs 目录。
  • struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent);
  1. proc_remove:用于删除一个已存在的 procfs 目录。
  • void proc_remove(struct proc_dir_entry *entry);
  1. PDE_DATA:宏定义,用于获取与 proc_dir_entry 结构关联的私有数据。
  • #define PDE_DATA(inode) PDE(inode)->data
  1. PDE:宏定义,用于获取指定 inode 对应的 proc_dir_entry 结构。
  • #define PDE(inode) (container_of((inode), struct proc_dir_entry, pde_inode))
 
demo举例:
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/fs.h>

#define PROCFS_FILENAME "my_procfs"

static int my_proc_show(struct seq_file *m, void *v) {
    seq_printf(m, "Hello from my_procfs!\n");
    return 0;
}

static int my_proc_open(struct inode *inode, struct file *file) {
    return single_open(file, my_proc_show, NULL);
}

static ssize_t my_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) {
    // 在这里实现写入操作的逻辑
    return -EINVAL; // 暂时返回无效参数错误
}

static const struct proc_ops my_proc_ops = {
    .proc_open = my_proc_open,
    .proc_read = seq_read,
    .proc_write = my_proc_write,
    .proc_lseek = seq_lseek,
    .proc_release = single_release,
};

static int __init my_module_init(void) {
    struct proc_dir_entry *entry;

    entry = proc_create(PROCFS_FILENAME, 0, NULL, &my_proc_ops);
    if (!entry) {
        pr_err("Failed to create /proc/%s\n", PROCFS_FILENAME);
        return -ENOMEM;
    }

    return 0;
}

static void __exit my_module_exit(void) {
    remove_proc_entry(PROCFS_FILENAME, NULL);
}

module_init(my_module_init);
module_exit(my_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("lethe1203");
MODULE_DESCRIPTION("procfs demo");

 

 
posted @ 2024-03-25 14:34  lethe1203  阅读(50)  评论(0编辑  收藏  举报