linux设备模型之kset

同样的,在看kset-example之前我们先看下kset的相关操作函数。


kobject_set_name 设定kobjectname

这个函数就是前面介绍的kobject_set_name_vargs函数的封装。


kset_init 初始化kset

voidkset_init(struct kset *k)

{

kobject_init_internal(&k->kobj);

INIT_LIST_HEAD(&k->list);

spin_lock_init(&k->list_lock);

}


因为kset结构体中内嵌一个kobject结构体,所以初始化时要初始化kset中内嵌的kobject结构体;然后初始化ksetlist双向链表。



kset_create 动态地创建一个kset结构体


staticstruct kset *kset_create(const char *name,

conststruct kset_uevent_ops *uevent_ops,

structkobject *parent_kobj)

给新建的kset结构体分配内存,将kset内嵌的kobjectname设定为constchar *name

设定几个分量:

kset->uevent_ops= uevent_ops;

kset->kobj.parent= parent_kobj;

kset->kobj.ktype= &kset_ktype;

kset->kobj.kset= NULL;



kset_register 初始化并添加一个kset

intkset_register(struct kset *k)

{

interr;


if(!k)

return-EINVAL;


kset_init(k);

err= kobject_add_internal(&k->kobj);

if(err)

returnerr;

kobject_uevent(&k->kobj,KOBJ_ADD);

return0;

}


下面再来分析kset-example.ko的注册过程:

staticint __init example_init(void)

{

/*

* Create a kset with the name of "kset_example",

* located under /sys/kernel/

*/

example_kset= kset_create_and_add("kset_example", NULL, kernel_kobj); -------a-------

if(!example_kset)

return-ENOMEM;


/*

* Create three objects and register them with our kset

*/

foo_obj= create_foo_obj("foo"); -------b---------

if(!foo_obj)

gotofoo_error;


bar_obj= create_foo_obj("bar"); ---------c---------

if(!bar_obj)

gotobar_error;


baz_obj= create_foo_obj("baz"); ---------d---------

if(!baz_obj)

gotobaz_error;


return0;


baz_error:

destroy_foo_obj(bar_obj);

bar_error:

destroy_foo_obj(foo_obj);

foo_error:

return-EINVAL;

}


  1. /sys/kernel/目录下新建一个kset_example的文件夹;

struct kset*kset_create_and_add(const char *name,

const structkset_uevent_ops *uevent_ops,

struct kobject*parent_kobj)

{

struct kset *kset;

int error;


kset = kset_create(name,uevent_ops, parent_kobj); ------a1-------------

if (!kset)

return NULL;

error = kset_register(kset); ------a2-------------

if (error) {

kfree(kset);

return NULL;

}

return kset;

}

A1、将kset内嵌的kobjectname设置为kset-example

kset->uevent_ops= uevent_ops; 这里就是设置为NULL

kset->kobj.parent= parent_kobj; kobj指向kernel_kobj,也就是/sys/kernel

kset->kobj.ktype= &kset_ktype;

设置内嵌kobjktype

static struct kobj_typekset_ktype = {

.sysfs_ops =&kobj_sysfs_ops,

.release= kset_release,

};

kset->kobj.kset= NULL;

A2kset_init(k);初始化k内嵌的kobject并初始化ksetlist

kobject_add_internal(&k->kobj);

创建kset-example的文件夹,因为kset_ktype没有default_attrs,所以不会创建属性文件。

  1. staticstruct foo_obj *create_foo_obj(const char *name)

foo_obj是在kobject结构体之上封装的一个结构体:

struct foo_obj {

struct kobject kobj;

int foo;

int baz;

int bar;

};


B1、新建一个foo_obj结构体

B2foo->kobj.kset= example_kset; 当一个kobject属于kset时,在调用kobject核心函数前我们先设好kset

B3retval= kobject_init_and_add(&foo->kobj, &foo_ktype, NULL, "%s",name);

kset_example目录下新建了一个foo文件夹,并在foo文件夹下新建三个文件,

文件是与attribute相关的:

static struct attribute*foo_default_attrs[] = {

&foo_attribute.attr,

&baz_attribute.attr,

&bar_attribute.attr,

NULL, /* need to NULL terminatethe list of attributes */

};

新建的三个文件是foobarbaz

Foo->kobj->ktype= foo_ktype

在添加kobject的时候,因为kobjectkset已被设好,而kobjectparent没设好,所以将kobjectparent设为kset内嵌的kobject,并将kobj加入ksetlist链表中。

形成下图的结构。


你可能感兴趣的:(linux设备模型之kset)