免费咨询热线

13621929115
常见问题
您的位置: 主页 > 新闻动态 > 常见问题

上海模型公司

发布日期:2023-04-04 23:05浏览次数:

前言sysfs是一个基于RAM的文件系统,它和Kobject一起,可以将Kernel的数据结构导出到用户空间,以文件目录结构的形式,提供对这些数据结构(以及数据结构的属性)的访问支持。

    sysfs具备文件系统的所有属性,而本文主要侧重其设备模型上海模型公司的特性,因此不会涉及过多的文件系统实现细节,而只介绍sysfs在Linux设备模型中的作用和使用方法具体包括:sysfs和Kobject的关系attribute的概念

    sysfs的文件系统操作接口2. sysfs和Kobject的关系在"Linux设备模型_Kobject”文章中,有提到过,每一个Ko上海模型公司bject,都会对应sysfs中的一个目录因此在将Kobject添加到Kernel时,create_dir接口会调用sysfs文件系统的创建目录接口,创建和Kobject对应的目录,相关的代码如下:。

    int kobject_add(struct kobject *kobj, struct kobje上海模型公司ct *parent,

        const char *fmt, ...)

        {

        [...]

        retval = kobject_add_varg(kobj, parent, fmt, args);

        [...]

        }

        上海模型公司

        static __printf(3, 0) int kobject_add_varg(struct kobject *kobj,

        struct kobject *parent,

        const char *fmt, va_list vargs)

        上海模型公司 {

        [...]

        return kobject_add_internal(kobj);

        }


        static int kobject_add_internal(struct kobject *kobj)

        {

        上海模型公司 [...]

        error = create_dir(kobj);

        [...]

        }

        static int create_dir(struct kobject *kobj)

        {


        [...]

        上海模型公司 error = sysfs_create_dir_ns(kobj, kobject_namespace(kobj));

        [...]

        }

    

    3. attribute3.1 attribute的功能概述在sysfs中,为什么会有attribute的概念呢?其实它是对应k上海模型公司object而言的,指的是kobject的“属性”我们知道, sysfs中的目录描述了kobject,而kobject是特定数据类型变量(如struct device)的体现。

    因此kobject的属性,就是这些变量的属性它可以是任何东西,名称、一个内部变量、一个字符串等等而attribute,在sy上海模型公司sfs文件系统中是以文件的形式提供的,即:kobject的所有属性,都在它对应的sysfs目录下以文件的形式呈现。

    这些文件一般是可读、写的,而kernel中定义了这些属性的模块,会根据用户空间的读写操作,记录和返回这些attribute的值总结一下:所谓的attibute,就是内核空间和用户空间进行上海模型公司信息交互的一种方法。

    例如某个driver定义了一个变量,却希望用户空间程序可以修改该变量,以控制driver的运行行为,那么就可以将该变量以sysfs attribute的形式开放出来Linux内核中,attribute分为普通的attribute和二进制attribute,如下:

    struct at上海模型公司tribute {

        const char *name;

        umode_t mode;

        #ifdef CONFIG_DEBUG_LOCK_ALLOC

        bool ignore_lockdep:1;

        struct lock_cl上海模型公司ass_key *key;

        struct lock_class_key skey;

        #endif

        };


        struct bin_attribute {

        struct attribute attr;

        siz上海模型公司e_t size;

        void *private;

        struct address_space *(*f_mapping)(void);

        ssize_t (*read)(struct file *, struct kobject *, struct bin上海模型公司_attribute *,

        char *, loff_t, size_t);

        ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,

        char *, loff_上海模型公司t, size_t);

        int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,

        struct vm_area_struct *vma);

        };

    struct att上海模型公司ribute为普通的attribute,使用该attribute生成的sysfs文件,只能用字符串的形式读写(后面会说为什么)而struct bin_attribute在struct attribute的基础上,增加了read、write等函数,因此它所生成的sysfs文件可以用任何方式读写。

    说完基上海模型公司本概念,我们要问两个问题:Kernel怎么把attribute变成sysfs中的文件呢?用户空间对sysfs的文件进行的读写操作,怎么传递给Kernel呢?下面来看看这个过程3.2 attibute文件的创建。

    在linux内核中,attibute文件的创建是由fs/sysfs/file.c中sysf上海模型公司s_create_file接口完成的,该接口的实现没有什么特殊之处,大多是文件系统相关的操作,和设备模型没有太多的关系,这里先略过不提。

    3.3 attibute文件的read和write看到3.1章节struct attribute的原型时,也许我们会犯嘀咕,该结构很简单啊,name表示文件名称,m上海模型公司ode表示文件模式,其它的字段都是内核用于debug Kernel Lock的,那文件操作的接口在哪里呢?

    不着急,我们去fs/sysfs目录下看看sysfs相关的代码逻辑所有的文件系统,都会定义一个struct file_operations变量,用于描述本文件系统的操作接口,sysfs也不例外:/上海模型公司/ 2.6 内核 /fs/sysfs/file.c 新内核已经变化

        const struct file_operations sysfs_file_operations = {

        .read = sysfs_read_file,

        .write = sys上海模型公司fs_write_file,

        .llseek = generic_file_llseek,

        .open = sysfs_open_file,

        .release = sysfs_release,

        .poll = sysfs_poll,

        上海模型公司 };


        /**

        * sysfs_read_file - read an attribute.

        * @file: file pointer.

        * @buf: buffer to fill.

        * @count:上海模型公司 number of bytes to read.

        * @ppos: starting offset in file.

        *

        * Userspace wants to read an attribute file. The attribute descr上海模型公司iptor

        * is in the files ->d_fsdata. The target object is in the directorys

        * ->d_fsdata.

        *

        * We call fill_read_buffer(上海模型公司) to allocate and fill the buffer from the

        * objects show() method exactly once (if the read is happening from

        * the beginning of the 上海模型公司file). That should fill the entire buffer with

        * all the data the object has to offer for that attribute.

        * We then call flush_read_bu上海模型公司ffer() to copy the buffer to userspace

        * in the increments specified.

        */


        static ssize_t

        sysfs_read_file(struct file *上海模型公司file, char __user *buf, size_t count, loff_t *ppos)

        {

        struct sysfs_buffer * buffer = file->private_data;

        ssize_t retval = 0;


        上海模型公司 mutex_lock(&buffer->mutex);

        if (buffer->needs_read_fill || *ppos == 0) {

        retval = fill_read_buffer(file->f_path.dentry,buffer)上海模型公司;

        if (retval)

        goto out;

        }

        pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",

        __func__, count, *ppos, buffer-上海模型公司>page);

        retval = simple_read_from_buffer(buf, count, ppos, buffer->page,

        buffer->count);

        out:

        mutex_unlock(&buffer->mu上海模型公司tex);

        return retval;

        }


        static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer)

        {


        s上海模型公司truct sysfs_dirent *attr_sd = dentry->d_fsdata;

        struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;

        const struct sysfs_ops * ops = b上海模型公司uffer->ops;

        [...]

        count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page);

        [...]

        }。

    

    read处理看着很简单,sysfs_read_file从fil上海模型公司e指针中取一个私有指针(注:大家可以稍微留一下心,私有数据的概念,在VFS中使用是非常普遍的),转换为一个struct sysfs_buffer类型的指针,以此为参数(buffer),转身就调用fill_read_buffer接口。

    而fill_read_buffer接口,直接从buffer指针中取出上海模型公司一个struct sysfs_ops指针,调用该指针的show函数,即完成了文件的read操作那么后续呢?当然是由ops->show接口接着处理咯。

    而具体怎么处理,就是其它模块(例如某个driver)的事了,sysfs不再关心(其实,Linux大多的核心代码,都是只提供架构和机制,具体的实现,也就是上海模型公司苦力,留给那些码农吧!这就是设计的魅力)不过还没完,这个struct sysfs_ops指针哪来的?好吧,我们再看看open(sysfs_open_file)接口吧。

    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;

        int error = -EACCES;

        char *p;


        p = d_path(&file->f_path, las上海模型公司t_sysfs_file, sizeof(last_sysfs_file));

        if (!IS_ERR(p))

        memmove(last_sysfs_file, p, strlen(p) + 1);


        /* need attr_sd for attr 上海模型公司and ops, its parent for kobj */

        if (!sysfs_get_active(attr_sd))

        return -ENODEV;


        /* every kobject with an attribute needs a kt上海模型公司ype assigned */

        if (kobj->ktype && kobj->ktype->sysfs_ops)

        ops = kobj->ktype->sysfs_ops;

        else {

        WARN(1, KERN_ERR "miss上海模型公司ing sysfs attribute operations for "

        "kobject: %s\n", kobject_name(kobj));

        goto err_out;

        }


        /* File needs write suppor上海模型公司t.

        * The inodes perms must say its ok,

        * and we must have a store method.

        */

        if (file->f_mode & FMODE_WRITE) {

        上海模型公司 if (!(inode->i_mode & S_IWUGO) || !ops->store)

        goto err_out;

        }


        /* File needs read support.

        * The inodes perms must s上海模型公司ay its ok, and we there

        * must be a show method for it.

        */

        if (file->f_mode & FMODE_READ) {

        if (!(inode->i_mode & S_IR上海模型公司UGO) || !ops->show)

        goto err_out;

        }


        /* No error? Great, allocate a buffer for the file, and store it

        * it in file->pr上海模型公司ivate_data for easy access.

        */

        error = -ENOMEM;

        buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);

        if (!buffer上海模型公司)

        goto err_out;


        mutex_init(&buffer->mutex);

        buffer->needs_read_fill = 1;

        buffer->ops = ops;

        file->private_dat上海模型公司a = buffer;


        /* make sure we have open dirent struct */

        error = sysfs_get_open_dirent(attr_sd, buffer);

        if (error)

        got上海模型公司o err_free;


        /* open succeeded, put active references */

        sysfs_put_active(attr_sd);

        return 0;


        err_free:

        kfree上海模型公司(buffer);

        err_out:

        sysfs_put_active(attr_sd);

        return error;

        }

    

    哦,原来和ktype有关系这个指针是从该attribute所从属的kobject中拿的再去看一下"Linux设备模上海模型公司型_Kobject”中ktype的定义,还真有一个struct sysfs_ops的指针。

    我们注意一下14行的注释以及其后代码逻辑,如果从属的kobject(就是attribute文件所在的目录)没有ktype,或者没有ktype->sysfs_ops指针,是不允许它注册任何attribute的!

    经上海模型公司过确认后,sysfs_open_file从ktype中取出struct sysfs_ops指针,并在随后的代码逻辑中,分配一个struct sysfs_buffer类型的指针(buffer),并把struct sysfs_ops指针保存在其中,随后(注意哦),把buffer指针交给file的priv上海模型公司ate_data,随后read/write等接口便可以取出使用。

    嗯!惯用伎俩!struct sysfs_ops {

        ssize_t (*show)(struct kobject *, struct attribute *,char *);

        ssize_t (*stor上海模型公司e)(struct kobject *,struct attribute *,const char *, size_t);

        };

    attribute文件的write过程和read类似,这里就不再多说另外,上面只分析了普通attribute的逻辑,而二进制类型的呢?也类似,去看看fs/s上海模型公司ysfs/bin.c吧,这里也不说了讲到这里,应该已经结束了,事实却不是如此。

    上面read/write的数据流,只到kobject(也就是目录)级别哦,而真正需要操作的是attribute(文件)啊!这中间一定还有一层转换!确实,不过又交给其它模块了 下面我们通过一个例子,来说明如何转换的。

    4. s上海模型公司ysfs在设备模型中的应用总结让我们通过设备模型class.c中有关sysfs的实现,来总结一下sysfs的应用方式首先,在class.c中,定义了Class所需的ktype以及sysfs_ops类型的变量,如下:。

    static const struct sysfs_ops class_sysfs_上海模型公司ops = {

        .show = class_attr_show,

        .store = class_attr_store,

        };


        static struct kobj_type class_ktype = {

        .sysfs上海模型公司_ops = &class_sysfs_ops,

        .release = class_release,

        .child_ns_type = class_child_ns_type,

        };

    由前面章节的描述可知,所有class_type的Kobject下面的a上海模型公司ttribute文件的读写操作,都会交给class_attr_show和class_attr_store两个接口处理以class_attr_show为例:。

    #define to_class_attr(_attr) container_of(_attr, struct class_attribute,上海模型公司 attr)


        static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr,

        char *buf)

        {

        struct class_attribu上海模型公司te *class_attr = to_class_attr(attr);

        struct subsys_private *cp = to_subsys_private(kobj);

        ssize_t ret = -EIO;


        if (class_attr上海模型公司->show)

        ret = class_attr->show(cp->class, class_attr, buf);

        return ret;

        }

    该接口使用container_of从struct attribute类型的指针中取得一个class模块的自上海模型公司定义指针:struct class_attribute,该指针中包含了class模块自身的show和store接口。

    下面是struct class_attribute的声明:struct class_attribute {

        struct attribute attr;

        上海模型公司 ssize_t (*show)(struct class *class, struct class_attribute *attr,

        char *buf);

        ssize_t (*store)(struct class *class, struct class_att上海模型公司ribute *attr,

        const char *buf, size_t count);

        };

    

    因此,所有需要使用attribute的模块,都不会直接定义struct attribute变量,而是通过一个自定义的数据结构,该数据结构的一个成员是struct attri上海模型公司bute类型的变量,并提供show和store回调函数。

    然后在该模块ktype所对应的struct sysfs_ops变量中,实现该本模块整体的show和store函数,并在被调用时,转接到自定义数据结构(struct class_attribute)中的show和store函数中。

    这样,每个atr上海模型公司ribute文件,实际上对应到一个自定义数据结构变量中了


标签:

产品推荐

Copyright © 2002-2020 上海润之模型设计有限公司 版权所有 展示模型,展品模型,展厅模型,展示道具,展厅展品,展品道具,模型定制,模型公司,上海模型公司 备案号:沪ICP备20018260号

13621929115