当前位置: 技术问答>linux和unix
linux驱动模型问题,大家指教。!!!!!!!!!!!!!谢谢了!!!!!!!!!!!!
来源: 互联网 发布时间:2016-03-20
本文导语: 使一个 kobject 在 sysfs 出现仅仅是调用 kobject_add 的事情. 我们已经见到这个函数作为添加一个 kobject 到一个 kset 的方式; 在 sysfs 中创建入口也是它的工作的一部分. 有一些事情值得知道, 关于 sysfs 入口如何...
使一个 kobject 在 sysfs 出现仅仅是调用 kobject_add 的事情. 我们已经见到这个函数作为添加一个 kobject 到一个 kset 的方式; 在 sysfs 中创建入口也是它的工作的一部分. 有一些事情值得知道, 关于 sysfs 入口如何创建:
1.kobjects 的 sysfs 入口一直为目录, 因此一个对 kobject_add 的调用导致在sysfs 中创建一个目录. 常常地, 这个目录包含一个或多个属性; 我们稍后见到属性如何指定.
2.分配给 kobject 的名字( 用 kobject_set_name ) 是给 sysfs 目录使用的名字. 因此, 出现在 sysfs 层次的相同部分的 kobjects 必须有独特的名字. 分配给 kobjects 的名字也应当是合理的文件名字: 它们不能包含斜线字符, 并且空白的使用强烈不推荐.
3.sysfs 入口位于对应 kobject 的 parent 指针的目录中. 如果 parent 是 NULL 当 kobject_add 被调用时, 它被设置为嵌在新 kobject 的 kset 中的 kobject; 因此, sysfs 层级常常匹配使用 kset 创建的内部层次. 如果 parent 和 kset 都是 NULL, sysfs 目录在顶级被创建, 这几乎当然不是你所要的.
---------------最后一条有点晕,大家帮忙解释下?
1.你可从这个结构中见到每个总线是它自己的子系统; 这个子系统不位于 sysfs 的顶层, 但是. 相反, 它们在总线子系统下面.
2.还有每个kset包含指向他自己的kobject
----------这些都是干什么,这么做有什么用?为什么这样呢?
还有想问一下为什么kobject指向kset,而且找kset还要用container_of函数,为什么这么做?为什么不kset指向kobject,这样做有什么好处?
1.kobjects 的 sysfs 入口一直为目录, 因此一个对 kobject_add 的调用导致在sysfs 中创建一个目录. 常常地, 这个目录包含一个或多个属性; 我们稍后见到属性如何指定.
2.分配给 kobject 的名字( 用 kobject_set_name ) 是给 sysfs 目录使用的名字. 因此, 出现在 sysfs 层次的相同部分的 kobjects 必须有独特的名字. 分配给 kobjects 的名字也应当是合理的文件名字: 它们不能包含斜线字符, 并且空白的使用强烈不推荐.
3.sysfs 入口位于对应 kobject 的 parent 指针的目录中. 如果 parent 是 NULL 当 kobject_add 被调用时, 它被设置为嵌在新 kobject 的 kset 中的 kobject; 因此, sysfs 层级常常匹配使用 kset 创建的内部层次. 如果 parent 和 kset 都是 NULL, sysfs 目录在顶级被创建, 这几乎当然不是你所要的.
---------------最后一条有点晕,大家帮忙解释下?
1.你可从这个结构中见到每个总线是它自己的子系统; 这个子系统不位于 sysfs 的顶层, 但是. 相反, 它们在总线子系统下面.
2.还有每个kset包含指向他自己的kobject
----------这些都是干什么,这么做有什么用?为什么这样呢?
还有想问一下为什么kobject指向kset,而且找kset还要用container_of函数,为什么这么做?为什么不kset指向kobject,这样做有什么好处?
|
给你解释下第3条吧。
sys系统最初的目的是为了管理电源的,因为有父子关系,当一个子设备不用时候,可以把父设备,比如总线关闭,以节省电源。
kobject在sys中是目录,attribute则是文件
kset是多个kobject的集合,当然在sys中就表现为一个目录了,所以它自己也要有个kobject,因为kobject代表的就是个目录。
第3条讲的是kobject这个目录存放位置的问题。
当kobject有parent(KOBJECT)的时候,这个目录是在父目录下创建的。
当kobject没有parent,但指明了所属的kset,则目录放在kset目录下,这个KSET目录就是它的kobject对应的目录。
如果2个都没有的话,就放在SYS跟目录了。
int sysfs_create_dir(struct kobject * kobj)
{
struct sysfs_dirent *parent_sd, *sd;
int error = 0;
BUG_ON(!kobj);
if (kobj->parent)
parent_sd = kobj->parent->sd;
else
parent_sd = &sysfs_root;
error = create_dir(kobj, parent_sd, kobject_name(kobj), &sd);
if (!error)
kobj->sd = sd;
return error;
}
在linux-2.6.25中,kobject_add()->kobject_add_varg->kobject_add_internal->create_dir->sysfs_create_dir
在 kobject_add_internal中会取得parent,如果没有parent,就用kset的kobject作为父目录
static int kobject_add_internal(struct kobject *kobj)
{
int error = 0;
struct kobject *parent;
if (!kobj)
return -ENOENT;
if (!kobj->name || !kobj->name[0]) {
pr_debug("kobject: (%p): attempted to be registered with empty "
"name!n", kobj);
WARN_ON(1);
return -EINVAL;
}
parent = kobject_get(kobj->parent);
/* join kset if set, use it as parent if we do not already have one */
if (kobj->kset) {
if (!parent)
parent = kobject_get(&kobj->kset->kobj);
kobj_kset_join(kobj);
kobj->parent = parent;
}
pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'n",
kobject_name(kobj), kobj, __FUNCTION__,
parent ? kobject_name(parent) : "",
kobj->kset ? kobject_name(&kobj->kset->kobj) : "");
error = create_dir(kobj);
if (error) {
kobj_kset_leave(kobj);
kobject_put(parent);
kobj->parent = NULL;
/* be noisy on error issues */
if (error == -EEXIST)
printk(KERN_ERR "%s failed for %s with "
"-EEXIST, don't try to register things with "
"the same name in the same directory.n",
__FUNCTION__, kobject_name(kobj));
else
printk(KERN_ERR "%s failed for %s (%d)n",
__FUNCTION__, kobject_name(kobj), error);
dump_stack();
} else
kobj->state_in_sysfs = 1;
return error;
}
sys系统最初的目的是为了管理电源的,因为有父子关系,当一个子设备不用时候,可以把父设备,比如总线关闭,以节省电源。
kobject在sys中是目录,attribute则是文件
kset是多个kobject的集合,当然在sys中就表现为一个目录了,所以它自己也要有个kobject,因为kobject代表的就是个目录。
第3条讲的是kobject这个目录存放位置的问题。
当kobject有parent(KOBJECT)的时候,这个目录是在父目录下创建的。
当kobject没有parent,但指明了所属的kset,则目录放在kset目录下,这个KSET目录就是它的kobject对应的目录。
如果2个都没有的话,就放在SYS跟目录了。
int sysfs_create_dir(struct kobject * kobj)
{
struct sysfs_dirent *parent_sd, *sd;
int error = 0;
BUG_ON(!kobj);
if (kobj->parent)
parent_sd = kobj->parent->sd;
else
parent_sd = &sysfs_root;
error = create_dir(kobj, parent_sd, kobject_name(kobj), &sd);
if (!error)
kobj->sd = sd;
return error;
}
在linux-2.6.25中,kobject_add()->kobject_add_varg->kobject_add_internal->create_dir->sysfs_create_dir
在 kobject_add_internal中会取得parent,如果没有parent,就用kset的kobject作为父目录
static int kobject_add_internal(struct kobject *kobj)
{
int error = 0;
struct kobject *parent;
if (!kobj)
return -ENOENT;
if (!kobj->name || !kobj->name[0]) {
pr_debug("kobject: (%p): attempted to be registered with empty "
"name!n", kobj);
WARN_ON(1);
return -EINVAL;
}
parent = kobject_get(kobj->parent);
/* join kset if set, use it as parent if we do not already have one */
if (kobj->kset) {
if (!parent)
parent = kobject_get(&kobj->kset->kobj);
kobj_kset_join(kobj);
kobj->parent = parent;
}
pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'n",
kobject_name(kobj), kobj, __FUNCTION__,
parent ? kobject_name(parent) : "",
kobj->kset ? kobject_name(&kobj->kset->kobj) : "");
error = create_dir(kobj);
if (error) {
kobj_kset_leave(kobj);
kobject_put(parent);
kobj->parent = NULL;
/* be noisy on error issues */
if (error == -EEXIST)
printk(KERN_ERR "%s failed for %s with "
"-EEXIST, don't try to register things with "
"the same name in the same directory.n",
__FUNCTION__, kobject_name(kobj));
else
printk(KERN_ERR "%s failed for %s (%d)n",
__FUNCTION__, kobject_name(kobj), error);
dump_stack();
} else
kobj->state_in_sysfs = 1;
return error;
}
|
2.还有每个kset包含指向他自己的kobject
KSET是KOBJECT集合,在SYS中是含有多个KOBJECT的目录,在SYS中只有KOBJECT表示目录,所以它自己也要有个了
1.你可从这个结构中见到每个总线是它自己的子系统; 这个子系统不位于 sysfs 的顶层, 但是. 相反, 它们在总线子系统下面.
PROC系统也可以表示内核信息,但是太混乱了,为了表示层次结构,所以才用了SYS,SYS目录下有多个子目录,每个都代表一个系统。
BUS目录则表示系统中所有的总线,它下面当然要包含所有总线。
这样做是放了方便明了,一看就知道有哪些了。
最后一句话,不知道你指的是哪里
KSET是KOBJECT集合,在SYS中是含有多个KOBJECT的目录,在SYS中只有KOBJECT表示目录,所以它自己也要有个了
1.你可从这个结构中见到每个总线是它自己的子系统; 这个子系统不位于 sysfs 的顶层, 但是. 相反, 它们在总线子系统下面.
PROC系统也可以表示内核信息,但是太混乱了,为了表示层次结构,所以才用了SYS,SYS目录下有多个子目录,每个都代表一个系统。
BUS目录则表示系统中所有的总线,它下面当然要包含所有总线。
这样做是放了方便明了,一看就知道有哪些了。
最后一句话,不知道你指的是哪里
|
所谓驱动,就是一些写在一个结构体里面的函数指针,表明这个设备可以做什么,怎么去做,比如怎么去打开,关闭阿,要处理什么中断阿,每种设备有不同的方法,所以你需要不同的驱动,你把这些方法都实现写写完了,驱动也就写好了