上一篇中有说道Linux device driver拓扑结构-用户视角,不过里面还是太抽象,那么今天就从一个简单的实例看下其中的kobject进行操作时,会有什么行为。
1. 使用kobject_init_and_add注册kobject
MODULE_LICENSE("GPL");
static int __init Hello_kobject_init(void)
{
printk(KERN_ALERT "wj: Hello kobject!\n");
kobject_init_and_add(&myKobj, &myKobj_type,NULL,"my_kobj");
return 0;
}
static void __exit Hello_kobject_exit(void)
{
kobject_del(&myKobj);
printk(KERN_ALERT "wj: Bye kobject!\n");
}
module_init(Hello_kobject_init);
module_exit(Hello_kobject_exit);
MODULE_AUTHOR("wj");
MODULE_DESCRIPTION("Hello_kobject");
其他相关的参数定义如下:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
/*
struct kobj_type {
void (*release)(struct kobject *kobj);
const struct sysfs_ops *sysfs_ops;
struct attribute **default_attrs;
const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
const void *(*namespace)(struct kobject *kobj);
};
*/
struct kobject myKobj;
/****************************************
* define kobj attribute
****************************************/
static struct attribute myKobj_atrribute = {
.name = "my_kobj_attr",
.mode = S_IRWXUGO
};
static struct attribute *default_attrs[] = {
&myKobj_atrribute,
NULL
};
/****************************************
* define kobj release function!
****************************************/
void my_kobj_release(struct kobject *kobj){
printk(KERN_ALERT "wj: Hello my_kojb_release!\n");
}
/****************************************
* define kobj sysfs_ops
****************************************/
ssize_t myKobj_sysfs_show(struct kobject * kobj, struct attribute * attr, char * buf)
{
printk(KERN_ALERT "wj: myKobj_sysfs_show is called!\n");
strcpy(buf,kobj->name);
return strlen(buf);
}
//sysfs allocate buf with size PAGE_SIZE
ssize_t myKobj_sysfs_store(struct kobject * kobj, struct attribute * attr, const char * buf, size_t size)
{
printk(KERN_ALERT "wj: myKobj_sysfs_store is called!\n");
return strlen(buf);
}
struct sysfs_ops mykobj_sysfs_ops = {
.show = myKobj_sysfs_show,
.store = myKobj_sysfs_store
};
/****************************************
* define kobj myKobj_type
****************************************/
struct kobj_type myKobj_type = {
.release = my_kobj_release,
.sysfs_ops = &mykobj_sysfs_ops,
.default_attrs = default_attrs
};
2. koject定义与kobject_type的呈现
struct kobject myKobj;
/****************************************
* define kobj myKobj_type
****************************************/
struct kobj_type myKobj_type = {
.release = my_kobj_release,
.sysfs_ops = &mykobj_sysfs_ops,
.default_attrs = default_attrs
};
编译OK后,调用insmod成功,我们注册的myKobj怎么呈现给用户呢?
2.1 sys目录下创建了my_kobj.
我们在另外一个文章中有说明,kobject被注册后,就会在/sys目录下创建目录,而且我们没有设置parent,所以它出现在/sys的根目录下,【如下图出现】
parallels@laptop:~/LinuxModule/LinuxKernel/kojbect_test$ ls /sys/
block bus class dev devices firmware fs hypervisor kernel module my_kobj power
2.2 my_kobj目录下的 myKobj_atrribute 文件
再看下my_kobj下面的就什么,注意一下它的属性
1. S_IRWXUGO,正好与ls出来的一致。
2. 文件的名字my_kobj_attr 上面的名称一致。
parallels@laptop:~/LinuxModule/LinuxKernel/kojbect_test$ ls /sys/my_kobj/ -l
total 0
-rwxrwxrwx 1 root root 4096 May 24 14:52 my_kobj_attr
2.3 mykobj_sysfs_ops
在这个定义中,我们定义了两个函数一个show一个store,那什么时候会被调用呢?
1.常用命令中,cat会调动到show,
2. echo XXXX > /sys/my_kobj/my_kobj_attr就会调用store函数。
/****************************************
* define kobj sysfs_ops
****************************************/
ssize_t myKobj_sysfs_show(struct kobject * kobj, struct attribute * attr, char * buf)
{
printk(KERN_ALERT "wj: myKobj_sysfs_show is called!\n");
strcpy(buf,kobj->name);
return strlen(buf);
}
//sysfs allocate buf with size PAGE_SIZE
ssize_t myKobj_sysfs_store(struct kobject * kobj, struct attribute * attr, const char * buf, size_t size)
{
printk(KERN_ALERT "wj: myKobj_sysfs_store is called!\n");
return strlen(buf);
}
struct sysfs_ops mykobj_sysfs_ops = {
.show = myKobj_sysfs_show,
.store = myKobj_sysfs_store
};
从我们的实现来看,show函数看buffer里面保存的是attribute的名字,而store函数中也会有相应的打印,那我们来测试下。
parallels@laptop:/sys/my_kobj$ cat my_kobj_attr
my_kobj
parallels@laptop:/sys/my_kobj$ echo "hello" > my_kobj_attr
而dmesg时可以看到:相应的打印信息。
[11953.047408] wj: Hello kobject!
[13447.028815] wj: myKobj_sysfs_show is called!
[13492.105824] wj: myKobj_sysfs_store is called!
3. 小结
当使用kobject_init_and_add时,
1.我们就会在sys目录下创建相应的目录,【如果有设置parent,则根据上面文章中提到进行分析】
2. 在相应的目录下会创建attribute文件,以及store和show操作。
以上,收工。
后面功能kobject相关的还有kset,以及bus,device,device_driver等,我们慢慢来举例子!