自己也是刚开始从android framework转到driver,相当于转行了,但是能做自己喜欢的工作还是非常开心的。
driver中基本的结构体:kobject,kobj_type,kset
这三个结构是驱动中一些基本数据结构,其他的device,device_driver,bus_type等都是对上面3个结构体进行封装形成的;
struct kobject {
const char *name; *重要
struct list_head entry; *这个需要参考kernel中怎么实现数据结构的,需要的单独看一下
struct kobject *parent; *父节点
struct kset *kset; *所指向的kset
struct kobj_type *ktype; *类型
struct kernfs_node *sd; ×文件目录对应的路径名
struct kref kref; ×引用计数
#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
struct delayed_work release;
#endif ~
unsigned int state_initialized:1; 一系列状态 ~
unsigned int state_in_sysfs:1; ~
unsigned int state_add_uevent_sent:1; ~
unsigned int state_remove_uevent_sent:1; ~
unsigned int uevent_suppress:1; 禁止发送uevent ~
};
kobj_type
struct kobj_type {
void (*release)(struct kobject *kobj); *release 函数
const struct sysfs_ops *sysfs_ops; ×系统操作函数
struct attribute **default_attrs; ×attribute
const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj); ×字节点用户空间
const void *(*namespace)(struct kobject *kobj); ×用户空间引用
};
ktype用来表示一类kobject的公共内容,主要包括了对该kobject进行操作相关的函数指针信息。每个kobject都要有一个对应的kobj_type结构,
在kobject_init或者kobject_init_and_add调用时给出。
release:函数指针,该类kobject的销毁函数。
sysfs_ops:包含了如何实现kobject的属性信息的函数指针
default_attrs:默认属性链表,这些属性会在这类kobject创建时自动被创建(populate_dir中)。
kobject kobject kobject
| / /
| / /
| / /
kobj_type kobj_type
<pre name="code" class="html"> struct sysfs_ops {
ssize_t (*show)(struct kobject *, struct attribute *, char *);
ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
};
主要就是进行显示和存储的我们在/device目录下看到很多的文件,cat文件时可以看到一些参数,这些参数就是通过show形成文件内容的
我们也可以对文件进行操作,例如echo 100>/device/input/keyboard<随意写的>,可以改变设备参数设置
struct kset {
struct list_head list; *指向一个链表结构
spinlock_t list_lock;
struct kobject kobj; ×指向一个kobject
const struct kset_uevent_ops *uevent_ops; ×能够向用户空间发送的操作
};
限于刚刚开始学习,好多我也不是很清楚,希望看到的大牛不要介意;具体一些,可以引用这篇博客的一个图
http://blog.youkuaiyun.com/ganggexiongqi/article/details/6559966

引用linux系统中一切皆是文件的观点来看这个图
kset一般是一个目录,是一个特殊的kobject,里面包含有一个kobject;里面的一个链表组织包含了这个目录下所有的文件,并且指向链表中的一个头节点(蓝色)
kobject就是一般的文件,就是一个普通节点属性;里面的kset就是说我在哪个节点下面(红色+黑色),我的兄弟节点都有那些(蓝色)
kset中的kset_uevent_ops *uevent_ops;可以向用户空间发送那些的uevent(uevent也需要单独看)
struct kset_uevent_ops {
int (* const filter)(struct kset *kset, struct kobject *kobj);
const char *(* const name)(struct kset *kset, struct kobject *kobj);
int (* const uevent)(struct kset *kset, struct kobject *kobj,
struct kobj_uevent_env *env);
};
http://blog.youkuaiyun.com/goodluckwhh/article/details/18730913
*filter该函数用来阻止kset中某个特定的kobject向用户控件发送uevent。如果函数结果返回0,则不会发送。
name:该函数是用来覆盖uevent发送到用户控件的kset名字。默认情况下,这个名字和kset的名字一样,但如果提供了name函数,这个名字会被覆盖。
*uevent:该函数在uevent将被发送到用户空间时调用,可以在uevent中添加更多的环境变量。
重要的接口及作用:
device_add:
添加一个device,将device中的kobject加入到全局的链表中;
同时也会更新在文件系统中的标识符:
1.根据attribute的name来创建sys下的文件
2.创建链接从class目录下到sys目录下