而目前456_test目录下是不存在任何文件的,那是因为我们没有添加该obj的属性,此测试case将在下解完善。
Kobject是linux设备驱动模型的基础,也是设备模型中抽象的一部分。如果想了解设备驱动模型就需要明白Kobject的构成或原理。linux内核为了兼容各种形形色色的设备,就需要对各种设备的共性进行抽象,抽象出一个基类,其余的设备只需要继承此基类就可以了。而此基类就是kobject,但是C语言没有面向对象语法,这时候就需要将此基类(Kobject)嵌入到具体的结构体中,从而就可以访问控制此设备的操作。通常驱动程序员很少使用到kobject结构及其相关接口,而是使用封装之后的更高层的接口函数。
Kobject结构体
内核使用kobject来表示内核一个对象。
struct kobject {
const char *name;
struct list_head entry;
struct kobject *parent;
struct 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;
};
name: 用来表示内核对象的名称,如果该内核对象加入到系统,那么它的name就会出现在sys目录下。
entry: 用来将一系列的内核对象kobject连接成链表
parent: 用来指向该内核对象的上层节点,从而可以实现内核对象的层次化结构
kset: 用来执行内核对象所属的kset。kset对象用来容纳一系列同类型的kobject
ktype: 用来定义该内核对象的sys文件系统的相关操作函数和属性。
sd: 用来表示该内核对象在sys文件系统中的目录项实例
kref: 其核心是原子操作变量,用来表示该内核对象的引用计数。
state_initialized: 用来表示该内核对象的初始化状态,1表示已经初始化,0表示未初始化。
state_in_sysfs: 用来表示该内核对象是否在sys中已经存在。
state_add_uevent_sent: 用来表示该内核对象是否向用户空间发送了ADD uevent事件
state_remove_uevent_sent:用来表示该内核对象是否向用户空间发送了Remove uevent事件
uevent_suppress: 用来表示该内核对象状态发生改变时,时候向用户空间发送uevent事件,1表示不发送。
kobject数据结构通常的用法就是嵌入到某一个对象的数据结构中,比如struct device结构
struct device {
struct device *parent;
struct device_private *p;
struct kobject kobj;
const char *init_name; /* initial name of the device */
const struct device_type *type;
Kobject相关操作函数
kobject相关的操作函数一般驱动程序员是不会直接操作的。
- kobject_init
该函数用于初始化一个kobject结构。
void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
{
char *err_str;
if (!kobj) { //合法性检测
err_str = "invalid kobject pointer!";
goto error;
}
if (!ktype) { //kobject结构必须设置相应的属性
err_str = "must have a ktype to be initialized properly!\n";
goto error;
}
if (kobj->state_initialized) { //如果已经初始化,在打印log
/* do not error out as sometimes we can recover */
printk(KERN_ERR "kobject (%p): tried to init an initialized "
"object, something is seriously wrong.\n", kobj);
dump_stack();
}
kobject_init_internal(kobj);
kobj->ktype = k