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


2011-07-22

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://wanderer-zjhit.blogbus.com/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 <[email protected]>
 * 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 <[email protected]>");

你可能感兴趣的:(/sysfs探索4--实例教学--kobject-example.c导读 - [linux内核])