Chinaunix首页 | 论坛 | 博客
  • 博客访问: 286162
  • 博文数量: 56
  • 博客积分: 3025
  • 博客等级: 中校
  • 技术积分: 534
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-06 17:28
个人简介

Honesty and diligence should be your eternal mates.

文章分类

全部博文(56)

文章存档

2012年(1)

2011年(27)

2010年(20)

2008年(8)

分类: LINUX

2012-03-22 18:56:35

面向对象的思想的确在应用软件的开发中颇具优势,它让一个个纯逻辑的函数和数据变成了一个个有生命的个体。鉴于性能的考虑,系统软件的实现(例如linux kernel)并没有采用面向对象的语言(如C++、Java)。但这丝毫没有影响到用小c找对象。

简单来说,一个对象包含数据以及对这些数据的操作。如果把银行比作一个对象的话,银行里的RMB就是数据、而银行的工作人员就相当于对象中方法(即操作数据的结构)。如果,我们想打劫银行的话,我们只需要拿着枪指着工作人员说,“亲,给我拿500万出来”。当然,如果你是一个比较牛逼的劫匪你可能要1000万,或者更多。这没有关系,因为无论你要多少钱,你都不必亲自动手去取,工作人员会帮你办好这一切。当你拎着一袋子钱溜走的时候,你可能会想说,“自从有了面向对象,腰不酸了、腿不疼了,打劫也更有效率了”。

这个例子只是想说明面向对象的一个显而易见的优点——给劫匪,哦不,给用户提供了可直接使用的接口。当然,面向对象的优点可不只这一点。

kobject是Linux设备驱动模型的核心部分,它的作用是简单点说就是嵌入到设备和驱动相关的结构体之中。既可以将这些设备和驱动组织成树形结构,又可以让用户通过sysfs直接控制驱动和设备。让我们来搭讪一下kobject,从她那儿看看有对象的好处。

我们哲学老师在提问一个学生之前都会先问学生的家乡在哪儿。据他的逻辑应该是一方水土养一方人,从一个人的家乡可以大致推断出他的性格等。 不管这个理论对不对,我们先看看kobject的家乡——include/linux/kobject.h,kobject在这里定义:


点击(此处)折叠或打开

  1. struct kobject {
  2. const char *name;
  3. struct list_head entry;
  4. struct kobject *parent;
  5. struct kset *kset;
  6. struct kobj_type *ktype;
  7. struct sysfs_dirent *sd;
  8. struct kref kref;
  9. unsigned int state_initialized:1;
  10. unsigned int state_in_sysfs:1;
  11. unsigned int state_add_uevent_sent:1;
  12. unsigned int state_remove_uevent_sent:1;
  13. unsigned int uevent_suppress:1;
  14. };


每一个kobject实例都有一个名字name,用于标识这个实例。还有一个母亲parent,用于建立kobject的家族树。还有一个比较熟悉的面孔struct list_head entry,不用说,它的作用是把我们的kobject组织成双向链表。sd这个成员的作用和sysfs相关,kobject是组成sysfs树形结构的结点。kref是该结构体的引用计数,实质是一个原子型的整形量。下面几个unsigned int型的表示kobject的状态,kobject过得好还是不好,是不是党员,都在这里记录着。每一个kobject的结构体都有一个ktype,用来决定kobject被创建或销毁时应该如何处理:

点击(此处)折叠或打开

  1. struct kobj_type {
  2.     void (*release)(struct kobject *kobj);
  3.     const struct sysfs_ops *sysfs_ops;
  4.     struct attribute **default_attrs;
  5.     const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
  6.     const void *(*namespace)(struct kobject *kobj);
  7. };

release是个回调函数,当kobject的引用计数为0时会被调用。当然,这个函数是需要我们自己完成的。其作用通常是释放kobject守护的结构体。每一类kobject都有自己的默认的属性,它放在结构体数组default_attrs中。每一个属性都应该在sysfs中对应一个文件。而sysfs_ops则存放着读写这些文件时的处理。

每一个kobject都可以属于某一个kset,一个kset就是一群kobject的集合。当然,物以类聚,人以群分,这些kobject要走到一起,当然是要有些共同特点的:

点击(此处)折叠或打开

  1. struct kset {
  2.     struct list_head list;
  3.     spinlock_t list_lock;
  4.     struct kobject kobj;
  5.     const struct kset_uevent_ops *uevent_ops;
  6. };

kset是kobject的容器,也就是说,它把kobject又封装了一下。没一个kset结构体里面存放一个kobject,kset通过list连接起来,从而属于这一集合的所有kobj也连接起来了。uevent_ops这个结构体存放了对这一组object的操作。具体什么操作,咱下回分解。

kobject就好比每个人的守护天使,她通常不单独存在,而是作为其他结构体的成员出现,类似于struct list_head。在一个结构体中,找到嵌入于其中的kobject是很easy的事,就像领导找下属,随叫随到的那种。但是kobject要找到嵌入它的结构体的指针却没那么容易了。幸好,kernel给我们提供了一个可以做这件事的宏:


点击(此处)折叠或打开

  1. contarner_of(pointer, type, member)

这个宏具体怎么用咱就不说了。google上百度一下,或者看下源码很容易就明白的。

有了这个宏,kobject守护的对象(设备和驱动)和kobject之间的联系就完全的建立起来了,kobject它妈叫它回家吃饭的时候就可以先找到设备和驱动,kobject要去打酱油的时候也可以叫上设备和驱动。

有了这个联系,系统里所有的设备和驱动就可以通过kobject给管理起来了。kobject和sysfs勾搭在一起就给用户层提供了修改设备和驱动参数的一种方式。

---

参考文献:
《LINUX设备驱动程序》 第三版  Jonathan Corbet,Alessandro Rubini,Greg Kroah-hartman
http://blog.21ic.com/user1/5593/archives/2010/69112.htmlhttp://blog.csdn.net/yili_xie/article/details/5835935

--------------------------------------------
Kelvin Wang
Blog: E-mail:kelvin.xupt@gmail.com
转载请注明出处!
--------------------------------------------


阅读(1775) | 评论(0) | 转发(0) |
0

上一篇:c常见错误及项目开发经验笔记

下一篇:没有了

给主人留下些什么吧!~~