zoukankan      html  css  js  c++  java
  • Linux设备管理(三):sysfs文件系统的功能及其应用

    /************************************************************************************

    *本文为个人学习记录,如有错误,欢迎指正。

    *本文参考资料:

    *        http://www.wowotech.net/linux_kenrel/dm_sysfs.html

    *        https://blog.csdn.net/skyflying2012/article/details/11783847

    *        http://www.cnblogs.com/xiaojiang1025/p/6202298.html

    *        http://www.wowotech.net/linux_kenrel/dm_sysfs.html

    ************************************************************************************/

    1. sysfs的简介

    sysfs是一个基于ramfs的文件系统,在2.6内核开始引入,用来导出内核对象(kernel object)的数据、属性到用户空间,以文件目录结构的形式为用户空间提供对这些数据、属性的访问支持。

    从驱动开发的角度,/sysfs为用户提供了除了设备文件/dev和/proc之外的另外一种通过用户空间访问内核数据的方式。使用sysfs,编译内核的时候需要定义CONFIG_SYSFS,可以通过mount -t sysfs sysfs /sys命令来挂载sysfs到"/sys"目录。

    2. sysfs的目录结构

    /sys

    /sys/block/

    块设备的存放目录,这是一个过时的接口,按照sysfs的设计理念,所有的设备都存放在"sys/devices/"同时在"sys/bus/"或(和)"sys/class/"存放相应的符号链接,所以现在这个目录只是为了提高兼容性的设计,里面的文件已经被全部替换成了符号链接,只有在编译内核的时候勾选CONFIG_SYSFS_DEPRECATED才会有这个目录。

    /sys/bus/

    bus包含了系统中所有的总线,每一种总线通常还有两个子目录:device和driver。

    /sys/class/

    按照设备功能对系统设备进行分类的结果放在这个目录,如系统所有输入设备都会出现在 "/sys/class/input"之下。和sys/bus一样,sys/class最终的文件都是符号链接,这样设备可以保证整个系统中每一个设备都只有一个实例。

    /sys/dev/

    按照设备号对字符设备和块设备进行分类的结果放在这个目录,同样,文件依然是使用符号链接的形式链接到"sys/devices/"中的相应文件。

    /sys/devices

    所有的设备文件实例都在"sys/devices/"目录下。

    /sys/fs

    这里按照设计是用于描述系统中所有文件系统,包括文件系统本身和按文件系统分类存放的已挂载点,但目前只有 fuse,gfs2 等少数文件系统支持 sysfs 接口,一些传统的虚拟文件系统(VFS)层次控制参数仍然在 sysctl (/proc/sys/fs) 接口中。

    /sys/kernel

    这里是内核所有可调整参数的位置,目前只有 uevent_helper, kexec_loaded, mm, 和新式的 slab 分配器等几项较新的设计在使用它,其它内核可调整参数仍然位于 sysctl (/proc/sys/kernel) 接口中。

    /sys/module

    这里有系统中所有模块的信息,不论这些模块是以内联(inlined)方式编译到内核映像文件(vmlinuz)中还是编译为外部模块(ko文件),都可能会出现在 /sys/module 中:编译为外部模块(ko文件)在加载后会出现对应的/sys/module/。

    /sys/power

    这里是系统中电源选项,这个目录下有几个属性文件可以用于控制整个机器的电源状态,如可以向其中写入控制命令让机器关机、重启等。

     "sys/class/","sys/bus/","sys/devices"是设备开发中最重要的几个目录。他们之间的关系可以用下图表示。

    3.attribute

    3.1 attribute的功能

    在sysfs中,设备的kobject的属性(kobject.ktype.attribute)以文件的形式被导出,sysfs还提供了使用文件I/O直接修改内核属性的机制,为用户提供访问设备的接口。kobject的所有属性,都在它对应的sysfs目录下以文件的形式呈现。这些文件一般是可读、可写的,而kernel中定义了这些属性的模块,会根据用户空间的读写操作,记录和返回这些attribute的值。

    所谓的属性(attibute),就是内核空间和用户空间进行信息交互的一种方法。例如某个driver定义了一个变量,却希望用户空间程序可以修改该变量,以控制driver的运行行为,那么就可以将该变量以sysfs attribute的形式开放出来。

    3.2 attribute的创建

    在linux内核中,attibute文件的创建是由fs/sysfs/file.c中sysfs_create_file接口完成的,该接口的实现大多是文件系统相关的操作,和设备模型没有太多的关系,此处先略过不提。

    3.3 attribute的读写

    所有的文件系统,都会定义一个struct file_operations变量,用于描述本文件系统的操作接口,sysfs也不例外:

     /* fs/sysfs/file.c, line 472 */
     const struct file_operations sysfs_file_operations = 
    {
         .read    = sysfs_read_file,
         .write   = sysfs_write_file,
         .llseek  = generic_file_llseek,
         .open    = sysfs_open_file,
         .release = sysfs_release,
         .poll    = sysfs_poll,
    };

     对attribute的读写,是通过sysfs的操作集(sysfs_file_operations)来进行的,实质是通过获取属性(kobject.ktype.attribute)对应的操作集(kobject.ktype.sysfs_ops)来对属性进行操作。具体代码分析如下:

    static int sysfs_open_file(struct inode *inode, struct file *file)
    {
        struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
        struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
        struct sysfs_buffer *buffer;
        const struct sysfs_ops *ops;
    
      //获取kobj的属性的操作集ops。如果该设备从属的kobject没有ktype,或者没有ktype->sysfs_ops指针,是不允许它注册任何attribute的
        if (kobj->ktype && kobj->ktype->sysfs_ops) 
            ops = kobj->ktype->sysfs_ops;
        else {
            WARN(1, KERN_ERR "missing sysfs attribute operations for "
                   "kobject: %s
    ", kobject_name(kobj));
            goto err_out;
        }
    
        buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
        if (!buffer)
            goto err_out;
    
        buffer->ops = ops;
        file->private_data = buffer; //将获取的属性操作集ops写入struct file,随后read、write接口便可取出来使用
      
      ............................
     }

    attribute的操作集操作集(kobject.ktype.sysfs_ops)在内核中定义如下:

    struct sysfs_ops 
    {
        ssize_t    (*show)(struct kobject *, struct attribute *,char *);
        ssize_t    (*store)(struct kobject *,struct attribute *,const char *, size_t);
    };

    4. sysfs的应用示例

    以Linux内核中的LED设备驱动框架为例,对sysfs的应用进行总结。详见:Linux字符设备驱动框架(二):Linux内核的LED设备驱动框架

  • 相关阅读:
    Win7怎么进入安全模式 三种轻松进入Win7安全模式方法
    Eclipse中新建applet 错误
    经典语录
    轻松一刻
    WIN XP蓝屏代码大全
    大话设计模式简单总结
    生命是闹着玩儿,事事显出如此 (转)
    Educational Codeforces Round 42 (Rated for Div. 2) A
    2018年东北农业大学春季校赛----不完整题解
    POJ
  • 原文地址:https://www.cnblogs.com/linfeng-learning/p/9313757.html
Copyright © 2011-2022 走看看