首先看了下/Documentation/kobject.txt文档中的说明,然后结合sample/kobject/kobject-example.c 对kobject做一些初步了解。 在内核配置中将kobject-example配置成model编译成.ko加载到内核之中。 在insmod kobject-example.ko时会用到 module_init(example_init); 而example_init函数如下:
/*
/* Create the files associated with this kobject */
return retval;
kobject_create_and_add ("kobject_example", kernel_kobj);
kobj = kobject_create();
retval = kobject_add(kobj, parent, "%s", name);
在kobject_create_and_add函数中, 首先创建一个kobject: kobj = kobject_create();
struct kobject *kobject_create(void) 在kobject_create函数中首先给kobj分配空间,然后用kobject_init函数初始化kobj,最后返回kobj。 而在kobject_init函数中,
void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
if (!kobj) {
kobject_init_internal(kobj);
error: 先判断kobj和ktype不为null,如果kobj->state_initialized==1(已经被初始化过了),进行错误处理。 最关键的是调用kobject_init_internal(kobj)和将kobj->ktype = ktype; 这里ktype是dynamic_kobj_ktype,我们将kobj->ktype 赋为dynamic_kobj_ktype
static struct kobj_type dynamic_kobj_ktype = {
struct sysfs_ops kobj_sysfs_ops = {
一个release方法用于释放kobject占用的资源;一个sysfs ops指针指向sysfs操作表和一个sysfs文件系统缺省属性列表。Sysfs操作表包括两个函数store()和show()。当用户态读取属性时,show()函数被调用,该函数编码指定属性值存入buffer中返回给用户态;而store()函数用于存储用户态传入的属性值。
以static ssize_t kobj_attr_show(struct kobject *kobj, struct attribute *attr,
kattr = container_of(attr, struct kobj_attribute, attr);
为例子,当cat foo、bar、baz时候,调用kobj_attr_show函数,这里,kobj_attr_show就会调用foo_show函数。 //特别补充一下container_of的介绍,这个在kernel中用的相当多: container_of(ptr, type, member)
kattr = container_of(attr, struct kobj_attribute, attr); 在这里,是通过kobj_attribute结构体的attr变量获得结构体本身的指针:kattr。
在kobject_init_internal(kobj)中,
static void kobject_init_internal(struct kobject *kobj) kobject的create动作完成后,我们再回到kobject_create_and_add函数中的retval = kobject_add(kobj, parent, "%s", name); 其中name这个字符串指针指着字符串“kobject_example”,而parent是指向kernel_kobj这个kobject的指针,其实kernel_kobj就应该是 sysfs下的kernel目录。 kobject_add->kobject_add_varg->1、kobject_set_name_vargs;2、kobj->parent = parent;3kobject_add_internal(kobj); 第一步是设置kobject的名字,即为kobj->name = name;将“kobject_example”这个名字赋给我们的kobject; 第二步将kobj->parent = parent,可以理解为kobject_example的上级为kernel目录。 第三步仔细看下:
static int kobject_add_internal(struct kobject *kobj)
if (!kobj)
if (!kobj->name || !kobj->name[0]) { parent = kobject_get(kobj->parent);
/* join kset if set, use it as parent if we do not already have one */
pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'/n",
error = create_dir(kobj);
/* be noisy on error issues */
return error; 1、parent = kobject_get(kobj->parent);得到新建kobject的parent,所以parent指向name为“kernel”的kobject。
2、 if (kobj->kset) { //这里没有kset,先不看这里,在kset_example文件中再分析这里。 3、error = create_dir(kobj);//以“kobject_example”为名字建立一个目录 //这个函数没懂,以后再看。 4、kobj->state_in_sysfs = 1;//表明该kobj在sysfs中了
那么,到这里,kobject_example就被加到sysfs中了, 下面一步就是: sysfs_create_group(example_kobj, &attr_group);//这个函数还不完全懂 简单的记录一下: attribute_group 的定义:
struct attribute_group {
static struct attribute_group attr_group = {
static struct attribute *attrs[] = {
static struct kobj_attribute baz_attribute = 定义了foo_attribute baz_attribute bar_attribute 因为
#define __ATTR(_name,_mode,_show,_store) { / foo_attribute这个结构体中的attr结构体的name成员为foo,mode成员为0666,foo_attribute的成员函数 show是foo_show,成员函数store是foo_store。
在sysfs_create_group中会添加三个文件,在kobject_example目录中有foo,baz和bar三个文件。 对文件作echo 1 > foo 和 cat foo的操作,就会调用foo_show和foo_store函数。
总结:在kobject_example 模块注册后,sys/kernel/kobject_example目录创建了,里面有三个文件foo、baz和bar。 这三个文件时属性文件。 对三个文件进行echo 1 > foo 和 cat foo的操作,会调用想用的show、store操作。 疑问在于:create_file、create_dir这些函数的具体实现是怎么样的?这个以后循序渐进去理解。 (责任编辑:IT) |