提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
linux内核kobject使用示例。
提示:以下是本篇文章正文内容,下面案例可供参考
一、kobject是什么?
kobject 是 Linux 内核中的一个核心数据结构,用于管理和表示内核中的各种对象。它是 Linux 设备模型的基础,用于表示设备、子系统和其他内核对象。
kobject 是一个基础的内核对象,它提供了一些基本的功能,
如引用计数、对象的创建和销毁、以及事件通知。
任何需要这些功能的内核对象都可以从 kobject “继承”这些特性。
kobject本身基本不会单独出现,一般使用是将kobject嵌入其他结构体中使用,通过这种方式来使用kobject特性。
kset是kobj的一个集合,本身也是一个kobj
subsystem 是由一些kset组成。
class结构是为了描述device设备的子类型,比如
class内核注释:
类是设备的更高级别视图,用于抽象出低级实现细节。驱动程序可能会看到 SCSI 磁盘或 ATA 磁盘,但在类级别,它们都只是磁盘。类允许用户空间根据设备的功能(而不是设备的连接方式或工作方式)来使用设备。
如下代码仅创建和使用了kobj,并未使用其全部特性。
二、使用步骤
创建kset,然后在kset下创建两个kobj
#include <linux/kobject.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
struct my_object {
struct kobject kobj;
int value; /* 可以添加其他成员 */
};
static struct kset *my_kset;
struct my_object *obj;
struct kobject *dynamic_obj;
static void my_release(struct kobject *kobj)
{
struct my_object *obj = container_of(kobj, struct my_object, kobj);
pr_info("Releasing my_object with value %d\n", obj->value);
kfree(obj);
}
static ssize_t show_value(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct my_object *obj = container_of(kobj, struct my_object, kobj);
return sprintf(buf, "%d\n", obj->value);
}
static ssize_t store_value(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
struct my_object *obj = container_of(kobj, struct my_object, kobj);
int new_value;
if (sscanf(buf, "%d", &new_value) != 1)
return -EINVAL;
obj->value = new_value;
return count;
}
static struct kobj_attribute value_attr = __ATTR(value, 0644, show_value, store_value);
static struct attribute *my_object_attrs[] = {
&value_attr.attr,
NULL,
};
/* default kobject attribute operations */
static ssize_t my_kobj_attr_show(struct kobject *kobj, struct attribute *attr,
char *buf)
{
int ret = 0;
printk("my_kobj_attr_show eneter\n");
return ret;
}
static ssize_t my_kobj_attr_store(struct kobject *kobj, struct attribute *attr,
const char *buf, size_t count)
{
int ret = 0;
printk("my_kobj_attr_store eneter\n");
return count;
}
static struct sysfs_ops my_sysfs_ops = {
.show = my_kobj_attr_show,
.store = my_kobj_attr_store,
};
static struct kobj_type my_ktype = {
.default_attrs = my_object_attrs,
.release = my_release,
.sysfs_ops = &kobj_sysfs_ops, //使用内核默认操作结构,也可以使用自定义
};
static int __init my_object_init(void)
{
int ret;
/* 创建并初始化 my_object 实例 */
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (!obj) {
pr_err("Failed to allocate memory for my_object\n");
return -ENOMEM;
}
my_kset = kset_create_and_add("my_kset", NULL, NULL);
if(NULL == my_kset)
{
printk("kset_create_and_add failed\n");
kfree(obj);
return -1;
}
/* 初始化 kobject */
kobject_init(&obj->kobj, &my_ktype);
/* 注册 kobject */
ret = kobject_add(&obj->kobj, &my_kset->kobj,"%s", "my_object_instance");
if (ret < 0) {
pr_err("Failed to register kobject: %d\n", ret);
kfree(obj);
kset_unregister(my_kset);
return ret;
}
pr_info("my_object module loaded\n");
dynamic_obj = kobject_create_and_add("dynamic_obj", &my_kset->kobj);
if(dynamic_obj == NULL)
{
printk("dynamic_obj kobject_create_and_add failed\n");
kfree(obj);
kset_unregister(my_kset);
return -1;
}
printk("my_kset kset_register\n");
return 0;
}
static void __exit my_object_exit(void)
{
/* 卸载 kobject */
kobject_del(&obj->kobj);
pr_info("my_object module unloaded\n");
if(dynamic_obj)
kobject_del(dynamic_obj);
kfree(obj);
kset_unregister(my_kset);
printk("my_kset kset_unregister\n");
}
module_init(my_object_init);
module_exit(my_object_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple kernel object example.");
总结
linux内核kobject使用示例,创建kset后会在/sys 目录下创建kset name的目录,kobj也会自动创建对应name的目录。