您的位置:首页 > 运维架构 > Linux

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

2015-11-10 20:49 567 查看
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
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>");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: