/sysfs探索4--实例教学--kobject-example.c导读 - [linux内核]

本文深入探讨了Linux内核中sysfs与kobject的交互方式,通过创建自定义目录、绑定属性并实现读写操作,展示了如何在sysfs系统中高效管理内核资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://www.blogbus.com/wanderer-zjhit-logs/149965638.html

    注:样例结合/sysfs探索2阅读,效果较好
    简单分析:
    1 本样例主要测试kobject结构,kobject对应sysfs文件系统中的一个目录,该目录对应一个具体的事物。
    2 首先通过example_kobj = kobject_create_and_add("kobject_example", kernel_kobj);将该结构加入   到/sys/kernel目录下[kernel_kobj为kernel子系统的kobject结构],形成层次结构,并且在父目录下建立该子目录[kobject->sd指向该kobject所在的目录节点]。
    3 通过retval = sysfs_create_group(example_kobj, &attr_group)将事物的3个特色属性与其对应的kobject绑定起来,将该文件操作接口和sysfs系统结合起来。使得可以通过kobj_attribute中的show何store进行实际的内核读写操作,该函数实际上在父目录下新建3个文件,结构用sysfs_dirent表示。且sysfs_dirent->s_attr.attr=相应属性结构,据此可获得读写该文件的方法。
    4 每个struct attribute结构对应kobject目录下一个文件,文件的读写方法由kobj_attribute中的show和store指定,kobj_attribute是kobject属性导出的接口
     struct attribute{
               const char *name;
               struct module* owner;
               mode_t mode;
    }
     struct kobj_attribute{
              struct attribute attr;
              ssize_t (*show)(struct kobject* kobj,struct kobj_attribute* attr,char* buf);
              ssize_t (*store)(struct kobject* kobj,struct kobj_attribute* attr,const char* buf,size_t count);
    }
    5当使用结束时,调用kobject_put(example_kobj)删除该kobject结构,及其对应的目录和文件。
    扩展:实际上对于不同子系统有不同的属性和属性操作函数
    比如:在genhd.h文件中,磁盘属性操作结构为,disk_attribute是磁盘属性导出的接口:
    struct disk_attribute{
            struct attribute attr;
            ssize_t (* show)(struct gendisk*,char*);
            ssize_t (* store)(struct gendisk*,const char*,size_t);//新内核中该函数取消,磁盘属性只有只读操作
    }
    在device.h文件中,外设属性操作结构为,device_attribute是外设属性导出的接口:
    struct device_attribute{
            struct attribute attr;
            ssize_t (* show)(struct device*dev,struct device_attribute*attr,char* buf);
            ssize_t (*store)(struct device *dev,struct device_attribute*attr,const char*buf,size_t count);
    }
    源代码如下:
    /*
     * Sample kobject implementation
     *
     * Copyright (C) 2004-2007 Greg Kroah-Hartman <greg@kroah.com>
     * Copyright (C) 2007 Novell Inc.
     *
     * Released under the GPL version 2 only.
     *
     */
    #include <linux/kobject.h>
    #include <linux/string.h>
    #include <linux/sysfs.h>
    #include <linux/module.h>
    #include <linux/init.h>

    /*
     * This module shows how to create a simple subdirectory in sysfs called
     * /sys/kernel/kobject-example  In that directory, 3 files are created:
     * "foo", "baz", and "bar".  If an integer is written to these files, it can be
     * later read out of it.
     */

    static int foo;
    static int baz;
    static int bar;

    /*
     * The "foo" file where a static variable is read from and written to.
     */
    static ssize_t foo_show(struct kobject *kobj, struct kobj_attribute *attr,
       char *buf)
    {
     return sprintf(buf, "%d\n", foo);
    }

    static ssize_t foo_store(struct kobject *kobj, struct kobj_attribute *attr,
        const char *buf, size_t count)
    {
     sscanf(buf, "%du", &foo);
     return count;
    }

    static struct kobj_attribute foo_attribute =
     __ATTR(foo, 0666, foo_show, foo_store);

    /*
     * More complex function where we determine which variable is being accessed by
     * looking at the attribute for the "baz" and "bar" files.
     */
    static ssize_t b_show(struct kobject *kobj, struct kobj_attribute *attr,
            char *buf)
    {
     int var;

     if (strcmp(attr->attr.name, "baz") == 0)
      var = baz;
     else
      var = bar;
     return sprintf(buf, "%d\n", var);
    }

    static ssize_t b_store(struct kobject *kobj, struct kobj_attribute *attr,
             const char *buf, size_t count)
    {
     int var;

     sscanf(buf, "%du", &var);
     if (strcmp(attr->attr.name, "baz") == 0)
      baz = var;
     else
      bar = var;
     return count;
    }

    static struct kobj_attribute baz_attribute =
     __ATTR(baz, 0666, b_show, b_store);
    static struct kobj_attribute bar_attribute =
     __ATTR(bar, 0666, b_show, b_store);


    /*
     * Create a group of attributes so that we can create and destroy them all
     * at once.
     */
    static struct attribute *attrs[] = {
     &foo_attribute.attr,
     &baz_attribute.attr,
     &bar_attribute.attr,
     NULL, /* need to NULL terminate the list of attributes */
    };

    /*
     * An unnamed attribute group will put all of the attributes directly in
     * the kobject directory.  If we specify a name, a subdirectory will be
     * created for the attributes with the directory being the name of the
     * attribute group.
     */
    static struct attribute_group attr_group = {
     .attrs = attrs,
    };

    static struct kobject *example_kobj;

    static int __init example_init(void)
    {
     int retval;

     /*
      * Create a simple kobject with the name of "kobject_example",
      * located under /sys/kernel/
      *
      * As this is a simple directory, no uevent will be sent to
      * userspace.  That is why this function should not be used for
      * any type of dynamic kobjects, where the name and number are
      * not known ahead of time.
      */
     example_kobj = kobject_create_and_add("kobject_example", kernel_kobj);
     if (!example_kobj)
      return -ENOMEM;

     /* Create the files associated with this kobject */
     retval = sysfs_create_group(example_kobj, &attr_group);
     if (retval)
      kobject_put(example_kobj);

     return retval;
    }

    static void __exit example_exit(void)
    {
     kobject_put(example_kobj);
    }

    module_init(example_init);
    module_exit(example_exit);
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值