总线设备模型-kobject .

来源:互联网 发布:linux中man的用法 编辑:程序博客网 时间:2024/05/19 19:34
原创kylin_zeng:http://blog.csdn.net/kylin_fire_zeng
总线设备驱动:
一、sysfs文件系统:linux2.6内核引入sysfs文件系统,sysfs可以看成与proc,devfs和devpty同类别的文件系统,该文件系统是虚拟的文件系统,可以更方便对系统设备进行管理。它可以产生一个包含所有系统硬件层次视图,与提供进程和状态信息的proc文件系统十分类似。sysfs把连接在系统上的设备和总线组织成为一个分级的文件,它们可以由用户空间存取,向用户空间导出内核的数据结构以及它们的属性。sysfs的一个目的就是展示设备驱动模型中各组件的层次关系,其顶级目录包括block,bus,drivers,class,power和firmware等.
~$ ls /sys     //运行环境ubuntu8.04(2.6.16)
block bus class devices firmware fskernel module power slab

二、kobject:是一个面向对象的管理机制,是构成设备上述设备模型的核心结构,在内核中注册一个
kobject就对应sysfs文件系统中的一个目录和目录里的一个文件。
1)
struct kobject{
const char  *k_name;//指向kobject名称的起始位置//如果名称长度小于KOBJ_NAME_LEN(20)字节,则kobject的名称便存放到name数组中,k_name指向数组头,如果大于,则动             态分配一个足够大的缓冲区来存放kobject的名称,这是k_name指向缓冲区。
char name[KOBJ_NAME_LEN];
struct kref  kref;//引用计数
struct list_head entry; //在所挂到链表的连接体
struct kobject  *parent; //指向kobject的父对象,以此来在内核中构造一个对象层次结构,并且可以将多个对象之间的关系表现初来,这就是sysfs的真相:一个用户空间的文件系统,用来表示内核中kobject对象的层次结构。
struct kset  *kset; //指向所属的kset*/
struct kobj_type  *ktype;
struct sysfs_dirent *sd;
unsigned intstate_initialized:1;
unsigned int state_in_sysfs:1;
unsigned intstate_add_uevent_sent:1;
unsigned intstate_remove_uevent_sent:1;
struct dentry  *dentry;//目录项 指向dentry结构体,在sysfs中该结构体就表示这个kobject。
};
2)注册:
void kobject_init(struct kobject *kobj)//初始化kobject结构
int kobject_add(struct kobject *kobj) // 将kobject对象注册到Linux系统
或者: int kobject_init_and_add(structkobject *kobj,     struct kobj_type *ktype,
 struct kobject*parent, const char *fmt, ...)//初始化kobject,并将其注册到linux系统
3)删除及计数加减:
void kobject_del(struct kobject *kobj) //从Linux系统中删除kobject对象
struct kobject *kobject_get(structkobject *kobj)//将kobject对象的引用计数加1,同时返回该对象指针。
void kobject_put(struct kobject *kobj)//将kobject对象的引用计数减1,如果引用计数降为0,则调用release方法释放该kobject对象。
4) kobj_type:
Kobject的ktype成员是一个指向kobj_type结构的指针该结构中记录了kobject对象的一些属性。
struct kobj_type
{
void (*release)(struct kobject*kobj);
struct sysfs_ops *sysfs_ops;
struct attribute **default_attrs;//指针数组可以对应多个文件。
};//release:用于释放kobject占用的资源,当kobject的引用计数为0时被调用。
5)attribute:就是目录下的文件。可以对应多个文件。
struct attribute
{
char * name;
struct module * owner;
mode_t mode;
};//struct attribute(属性):对应于kobject的目录下的一个文件,Name成员就是文件名。
6)sysfs_ops :
struct sysfs_ops
{
  ssize_t (*show)(struct kobject *, structattribute *,char *);
  ssize_t (*store)(struct kobject *,structattribute *,const char *,size_t);
};// Show:当用户读属性文件时,该函数被调用,该函数将属性值存入buffer中返回给用户态;
  // Store:当用户写属性文件时,该函数被调用,用于存储用户传入的属性值。
 
 
三、
kset是具有相同类型的kobject的集合,在sysfs中体现成一个目录,在内核中用kset数据结构表示。
1)kset_register(struct kset *kset)  //在内核中注册一个kset
2)vkset_unregister(struct kset *kset)//从内核中注销一个kset
机构体:

struct kset {

struct list_head list; //连接该kset中所有kobject的链表头

spinlock_t list_lock;

struct kobject kobj; //内嵌的kobject

struct kset_uevent_ops *uevent_ops; //处理热插拔事件的操作集合

}

因此kset包含kobject.上述的热拔插是:在Linux系统中,当系统配置发生变化时,如:添加kset到系统;移动kobject, 一个通知会从内核空间发送到用户空间,这就是热插拔事件。热插拔事件会导致用户空间中相应的处理程序(如udev,mdev)被调用, 这些处理程序会通过加载驱动程序, 创建设备节点等来响应热插拔事件。

1)
Struct kset_uevent_ops 
{
int (*filter)(struct kset *kset, struct kobject *kobj);
const char *(*name)(struct kset *kset, struct kobject *kobj);
int (*uevent)(struct kset *kset, struct kobject *kobj,
struct kobj_uevent_env *env);
}
  1.1)当该kset所管理的kobject和kset状态发生变化时即热插拔(如被加入,移动),上述三个函数将被调用。
    1.2)这三个函数的功能:
      filter:决定是否将事件传递到用户空间。如果 filter返回 0,将不传递事件。(例: uevent_filter)
     name:用于将字符串传递给用户空间的热插拔处理程序。
           uevent:将用户空间需要的参数添加到环境变量中。    例:dev_uevent)

原创粉丝点击