Chinaunix首页 | 论坛 | 博客
  • 博客访问: 631346
  • 博文数量: 1008
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 5175
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-31 09:44
文章分类
文章存档

2012年(1008)

我的朋友

分类:

2012-08-01 10:57:01

原文地址:Linux内核驱动之Kobject 作者:luozhiyong131

    Kobject Linux 2.6引入的新的设备管理机制,在内核中由struct kobject表示。通过这个数据结构使所有设备在底层都具有统一的接口kobject提供基本的对象管理,是构成Linux2.6设备模型的核心结构,它与sysfs文件系统紧密关联,每个在内核中注册的kobject对象都对应于sysfs文件系统中的一个目录

    Kobject是组成设备模型的基本结构。类似于C++中的基类,它嵌入于更大的对象的对象中--所谓的容器--用来描述设备模型的组件。如bus,devices, drivers 都是典型的容器。这些容器就是通过kobject连接起来了,形成了一个树状结构。这个树状结构就与/sys向对应。

   

kobject 结构为一些大的数据结构和子系统提供了基本的对象管理,避免了类似机能的重复实现。这些机能包括
-
对象引用计数.
-
维护对象链表(集合).
-
对象上锁.
-
在用户空间的表示.

 

Kobject结构定义为:

struct kobject {

    char * k name;          //指向设备名称的指针

    char name[KOBJ NAME LEN];   //设备名称

    struct kref kref;           //对象引用计数

    struct list head entry;     //挂接到所在kset中去的单元

    struct kobject * parent;    //指向父对象的指针

    struct kset * kset;         //所属kset的指针

    struct kobj type * ktype;   //指向其对象类型描述符的指针

    struct dentry * dentry;     //sysfs文件系统中与该对象对应的文件节点路径指针

};

 

其中的kref域表示该对象引用的计数,内核通过kref实现对象引用计数管理,内核提供两个函数kobject_get()kobject_put()分别用于增加和减少引用计数,当引用计数为0时,所有该对象使用的资源释放。Ktype 域是一个指向kobj type结构的指针,表示该对象的类型。

相关函数


void kobject_init(struct kobject * kobj)
//kobject初始化函数。

int kobject_set_name(struct kobject *kobj, const char *format, ...)

//设置指定kobject的名称。

struct kobject *kobject_get(struct kobject *kobj)

//kobj 对象的引用计数加1,同时返回该对象的指针。

void kobject_put(struct kobject * kobj)

//kobj对象的引用计数减1,如果引用计数降为0,则调用kobject release()释放该kobject对象。

int kobject_add(struct kobject * kobj)

//kobj对象加入Linux设备层次。挂接该kobject对象到ksetlist链中,增加父目录各级kobject的引用计数,在其parent指向的目录下创建文件节点,并启动该类型内核对象的hotplug函数。

int kobject_register(struct kobject * kobj)

//kobject注册函数。通过调用kobject init()初始化kobj,再调用kobject_add()完成该内核对象的注册。

int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,struct kobject *parent, const char *fmt, ...) //初始化kobject,并将其注册到linux系统

void kobject_del(struct kobject * kobj)

//Linux设备层次(hierarchy)中删除kobj对象。

void kobject_unregister(struct kobject * kobj)

//kobject注销函数。与kobject register()相反,它首先调用kobject del从设备层次中删除该对象,再调用kobject put()减少该对象的引用计数,如果引用计数降为0,则释放kobject对象。


Kobj type
struct kobj_type

{

    void (*release)(struct kobject *);

    struct sysfs_ops * sysfs_ops;

    struct attribute ** default_attrs;

};

Kobj type数据结构包含三个域:一个release方法用于释放kobject占用的资源;一个sysfs ops指针指向sysfs操作表和一个sysfs文件系统缺省属性列表。

 

Sysfs操作表包括两个函数store()show()。当用户态读取属性时,show()函数被调用,该函数编码指定属性值存入buffer中返回给用户态;而store()函数用于存储用户态传入的属性值。

struct sysfs_ops

{

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

ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);

};

? Show:当用户读属性文件时,该函数被调用,该函数将属性值存入buffer中返回给用户态;

? Store:当用户写属性文件时,该函数被调用,用于存储用户传入的属性值。


attribute
struct attribute

{

    char * name;

    struct module * owner;

    mode_t mode;

};

attribute, 属性。它以文件的形式输出到sysfs的目录当中。在kobject对应的目录下面。文件名就是name。文件读写的方法对应于kobj type中的sysfs ops

点击(此处)折叠或打开

  1. /**
  2.  * Kobject
  3.  * 2012-7-27
  4.  */
  5. #include <linux/device.h>
  6. #include <linux/module.h>
  7. #include <linux/kernel.h>
  8. #include <linux/init.h>
  9. #include <linux/string.h>
  10. #include <linux/sysfs.h>
  11. #include <linux/stat.h>

  12. ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr,char *buf)
  13. {
  14.     printk("have show.\n");
  15.     printk("attrname:%s.\n", attr->name);
  16.     sprintf(buf,"%s\n",attr->name);
  17.     return strlen(attr->name)+2;
  18. }

  19. ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf, size_t count)
  20. {
  21.     printk("havestore\n");
  22.     printk("write: %s\n",buf);
  23.     return count;
  24. }

  25. struct sysfs_ops obj_test_sysops =
  26. {
  27.     .show = kobj_test_show,
  28.     .store = kobj_test_store,
  29. };

  30. void obj_test_release(struct kobject *kobject)
  31. {
  32.         printk("eric_test: release .\n");
  33. }

  34. struct attribute test_attr = {
  35.         .name = "kobj_config",
  36.         .mode = S_IRWXUGO,
  37. };

  38. static struct attribute *def_attrs[] = {
  39.         &test_attr,
  40.         NULL,
  41. };

  42. struct kobj_type ktype =
  43. {
  44.     .release = obj_test_release,
  45.     .sysfs_ops = &obj_test_sysops,
  46.     .default_attrs=def_attrs,
  47. };


  48. struct kobject kobj;
  49. static int kobj_test_init(void)
  50. {
  51.     printk("kboject test init.\n");
  52.     kobject_init_and_add(&kobj, &ktype, NULL, "kobject_test");
  53.     return 0;
  54. }

  55. static void kobj_test_exit(void)
  56. {
  57.         printk("kobject test exit.\n");
  58.         kobject_del(&kobj);
  59. }

  60. module_init(kobj_test_init);
  61. module_exit(kobj_test_exit);

  62. MODULE_AUTHOR("Lzy");
  63. MODULE_LICENSE("GPL");


 

阅读(119) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~