• 内核交互--procfs


    文档介绍:http://lxr.linux.no/linux+v2.6.37/Documentation/filesystems/proc.txt
    以下内容抄录linux设备驱动开发详解-宋宝华
    在/proc文件系统中,我们可以将对虚拟文件的读写作为与内核中实体进行通信的一种手段。/proc被内核用于向用户导出信息。linux系统的许多命令本身都是通过分析/proc下的文件来完成的,如ps、top、uptime和free等。例如free命令通过分析/proc/meminfo文件得到可用内存信息。

    在linux3.9及以前的内核版本中,proc应用

    可用如下函数创建/proc节点:

    struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent);
    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()用于创建/proc节点,create_proc_read_entry()用于创建只读的/proc节点。参数name为/proc节点名字,parent或base为父目录的节点,若为NULL,则指/proc目录,read_proc为节点的读函数指针。

    创建/proc目录,

    struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent);

    proc_mkdir()和create_proc_entry()使用范例:

    struct proc_dir_entry *example_dir = proc_mkdir(“proc_example”, NULL);
    if(example_dir == NULL){
        rv = -ENOMEM;
        goto out;
    }
    
    example_dir->owner = THIS_MODULE;
    example_file = create_proc_entry(“example_file”, 0666, example_dir);
    if( example_file == NULL){
        rv = -ENOMEM;
        goto out;
    }
    
    example_file->owner = THIS_MODULE;
    example_file->read_proc = example_file_read;
    example_file->write_proc = example_file_write;

    proc节点的读写函数的类型分别为:

    typedef int (read_proc_t)(char *page, char **start, off_t off, int count, int *eof, void *data);
    typedef int (write_proc_t)(struct file *file, const char __user *buffer, unsigned long count, void *data);

    page指向用于写入数据的缓冲区,start用户返回实际的数据并写到内存页的位置,eof用于返回读结束标志,offset是读的偏移,count是要读的数据长度。start参数比较复杂,对于/proc只包含简单数据的情况,通常不需要再读函数中设置*start,这意味着内核将认为数据保存在内存页偏移0的地方。
    写函数与file_operation中的write()成员函数类似,需要一次从用户缓冲区到内存空间的复制过程。
    data是struct proc_dir_entry的私有数据,实际读写就是通过page或buf将数据读取或保存到data所指数据区中。

    void remove_proc_entry(const char *name, struct proc_dir_entry *parent);

    在linux系统中已经定义好的可使用的/proc节点宏包括:proc_root_fs(/proc),proc_net(/proc/net),proc_bus(/proc/bus),proc_root_driver(proc_driver)等,proc_root_fs实际就是NULL。

    linux3.10及以后版本中proc应用

    proc的内核API和实现架构变更较大,create_proc_entry(),create_proc_read_entry()之类的API都被删除了,取而代之的是直接使用proc_create()、proc_create_date()API。同时,也不存在read_proc()、write_proc()之类的针对proc_dir_entry的成员函数了,而是直接把file_operations结构体的指针传入proc_create()或者proc_create_date()函数中。

    static inline struct proc_dir_entry *proc_create(const char *name, mode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops)
    static inline struct proc_dir_entry *proc_create_data(const char *name, mode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops, void *data)

    代码中通过宏定义区分:

    #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)

    #else

    #endif

  • 相关阅读:
    第十四周 Leetcode 315. Count of Smaller Numbers After Self(HARD) 主席树
    POJ1050 To the Max 最大子矩阵
    POJ1259 The Picnic 最大空凸包问题 DP
    POJ 3734 Blocks 矩阵递推
    POJ2686 Traveling by Stagecoach 状态压缩DP
    iOS上架ipa上传问题那些事
    深入浅出iOS事件机制
    iOS如何跳到系统设置里的各种设置界面
    坑爹的私有API
    业务层网络请求封装
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/6512425.html
Copyright © 2020-2023  润新知