struct kobj_type
{
void (*release)(struct kobject *kobj);//在kobect_put()中会调用释放kobect对象
struct sysfs_ops *sysfs_ops; //对attribute进行操作
struct attribute **default_attrs; /*每个属性代表一个此目录下的文件
比如在/sys/下加入了cat 这个kobject
那么会有/sys/cat/ 这个目录 那么这个kobect有属性 size color
那就会存在 /sys/cat/size /sys/cat/color 这两个文件 */
};
struct kobject
{
const char *name; //表示kobject对象的名字,对应sysfs下的一个目录
struct list_head entry; //连接到kset 建立层次结构 是kobject中插入的head_list结构
struct kobject *parent;// 是指向当前kobject父对象的指针,体现在sys结构中就是包含当前kobject对象的目录对象
struct kset *kset; //kset代表一个subsystem 其中容纳了一系列同类型的kobject
struct kobj_type *ktype; //该内核对象一组sysfs文件系统相关的操作函数和属性
struct sysfs_dirent *sd; //该内核对象在sysfs文件系统中对应的目录项实例
struct kref kref; //是对kobject的引用计数,当引用计数为0时,就回调之前注册的release方法释放该对象
unsigned int state_initialized:1;//1表示已经初始化 0表示未被初始化
unsigned int state_in_sysfs:1; //表示在sysfs系统中是否建立一个入口点
unsigned int state_add_uevent_sent:1;
unsigned int state_remove_uevent_sent:1;
unsigned int uevent_suppress:1; // 1表示在该对象状态发生变化时 不让所属kset往用户空间发送uevent消息
};
int kobject_set_name(struct kobject *kobj, const char *fmt, ...)
fun:给内核对象kobject设置名字obj->name 将会在sysfs系统中显示
kobj:kobject内核对象
fmt:格式化字符串
返回值: 成功返回0 否则返回负数
头文件:#include <linux/kobject.h>
void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
fun:初始化一个kobject内核对象,需要自己提供kobj_type结构
kobj: kobject内核对象
ktype:为不同类型的kobject提供属性,属性操作集合,和kobject销毁方法,此处的属性的显示在sysfs文件系统中即是在该kobject目录下的文件
头文件:#include <linux/kobject.h>
int kobject_add(struct kobject *kobj, struct kobject *parent,const char *fmt, ...)
fun:建立kobject间的层级关系,以及在sysfs文件系统中建立一个目录,调用此函数必须kobj先进行初始化
kobj:kobject内核对象
parent:指向父目录 若为空并且指向的kset为空 则将sysfs_root作为父目录 即在/sysfs 下创建目录
fmt:此处可以修改kobject内核对象的名字kobj->name
返回值:成功返回0 失败返回负数
头文件:#include <linux/kobject.h>
int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
struct kobject *parent, const char *fmt, ...)
fun:相当于上面的kobject_init和kobject_add的联合使用,具体看上面两个函数的介绍
返回值: 成功返回0 失败返回负数
头文件:#include <linux/kobject.h>
struct kobject *kobject_create(void)
fun:创建一个kobject内核对象并进行初始化 此处初始化不需要自己提供kobj_type内核会使用dynamic_kobj_ktype,所以要使用自己的kobj_type,就不要使用此函数
使用此函数必须使用kobject_put()来释放kobj内核对象
返回值:kobject内核对象
头文件:#include <linux/kobject.h>
struct kobject *kobject_create_and_add(const char *name, struct kobject *parent)
fun:功能类似于kobject_create() 加上 kobject_add() 具体看上面描述
返回值:成功返回一个kobject内核对象
头文件:#include <linux/kobject.h>
int kobject_rename(struct kobject *kobj, const char *new_name)
fun:重新命名kobject对象的名字
kobj:kobject内核对象
new_name:新名字
返回值:成功返回0 失败返回负数
头文件:#include <linux/kobject.h>
struct kobject *kobject_get(struct kobject *kobj)
fun:增加kobj内核对象的引用计数kobj->kref 初始化值为1
返回值:传入的kobj对象
头文件:#include <linux/kobject.h>
void kobject_put(struct kobject *kobj)
fun:递减kobj内核对象的引用计数 当为0的时候调用在kobject_init()中传入的kobj_type{}结构中包含的kobj释放函数
头文件:#include <linux/kobject.h>
(1)举个栗子 使用*kobject_create_and_add()
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/kobject.h>
struct kobject *g_obj = NULL;
struct kobject *g_parobj = NULL;
static int __init test_init(void)
{
g_parobj = kobject_create_and_add("cat2",NULL);
if(NULL == g_parobj)
{
printk("create kobj error\n");
return -1;
}
g_obj = kobject_create_and_add("whitecat",g_parobj);
if(NULL == g_obj)
{
if(g_parobj)
{
kobject_del(g_parobj);
kobject_put(g_parobj);
}
}
return 0;
}
static void __exit test_exit(void)
{
if(g_obj)
{
kobject_del(g_obj);
kobject_put(g_obj);
}
if(g_parobj)
{
kobject_del(g_parobj);
kobject_put(g_parobj);
}
return;
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
(2)第二个栗子自己搭建kobj_type结构
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/kobject.h>
struct kobject *g_obj = NULL;
struct attribute attr1={
.name="color",
.mode = 0644
};
struct attribute attr2={
.name="size",
.mode = 0644
};
//注意此处的最后一个要设置为NULL 在内核populate_dir()中可以看到对最后一个为NULL才会停止判断
struct attribute *pattr[3] = {&attr1,&attr2,NULL};
static void kobj_free(struct kobject *kobj)
{
kfree(kobj);
}
static ssize_t obj_attr_show(struct kobject *kobj, struct attribute *attr,char *buf)
{
printk("read filename[%s]\n",attr->name);
return 0;
}
static ssize_t obj_attr_store(struct kobject *kobj, struct attribute *attr,
const char *buf, size_t count)
{
printk("write filename[%s] buff[%s] \n",attr->name,buf);
//这里一定要返回传入的字节数 表示接受成功
return count;
}
struct sysfs_ops kobj_attr_ops = {
.show = obj_attr_show,
.store = obj_attr_store,
};
static struct kobj_type test_type = {
.release = kobj_free,
.sysfs_ops = &kobj_attr_ops,
.default_attrs = pattr
};
static int __init test_init(void)
{
g_obj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
if(NULL == g_obj)
{
printk("alloc obj error\n");
return -1;
}
kobject_init(g_obj,&test_type);
kobject_set_name(g_obj,"cat2");
kobject_add(g_obj,NULL,NULL);
return 0;
}
static void __exit test_exit(void)
{
if(g_obj)
{
//在sysfs文件系统中将kobj删除
kobject_del(g_obj);
//释放kobj对象将条用test_type{}中的kobj_free()
kobject_put(g_obj);
}
return;
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");