sys文件系统中文件、文件夹与kobject、kset、kobj_type的对应关系

来源:互联网 发布:mysql官方下载教程 编辑:程序博客网 时间:2024/05/22 15:10
网上对sys文件系统与kobject的文章很多,但对初学者的我越看越乱。几经辗转总结出如下结论,如有误恳请讨论指出,直接给出:
1,kobject,kset对应sysfs里面的文件夹,目录的名字就是结构体中的 name
2,kobj_type对应sysfs里面的文件,这些文件是kobject的属性的外在表现
3,kobject是linux设备树的核心结构体,整个设备树都是围绕kobject建立起来的,维系这种树关系的是kobject结构体里面的parent指针。parent指针指向本节点的父节点,赋值为null时该节点直接出现在/sys/根目录下。
4,kset结构体中包含一个kobject结构体,在分析sysfs中目录与kobject的对应关系时,可认为kobject与kset等同。
5,kset比kobject多一个list双向链表,可以按设备类型关系将其下的节点加入链表。但这种关系在sysfs中的目录结构中不显现。
6,kobject中包含一个kobj_tpye指针,kobj_type中的default_attrs即为是该kobject的各项属性。属性必须存在于kobject之下,不能直接出现在/sys根目录。


kobject,kset,kobj_tpye的定义在kernel\include\linux\kobject.h
struct kobject {const char*name;struct list_headentry;struct kobject*parent;struct kset*kset;struct kobj_type*ktype;struct kernfs_node*sd;struct krefkref;#ifdef CONFIG_DEBUG_KOBJECT_RELEASEstruct delayed_workrelease;#endifunsigned int state_initialized:1;unsigned int state_in_sysfs:1;unsigned int state_add_uevent_sent:1;unsigned int state_remove_uevent_sent:1;unsigned int uevent_suppress:1;};struct kset {struct list_head list;spinlock_t list_lock;struct kobject kobj;const struct kset_uevent_ops *uevent_ops;};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);};

在sys目录下创建文件夹
使用kset_create_and_add、kobject_create_and_add函数
如/sys/class 的创建
代码位于kernel\drivers\base\class.c
int __init classes_init(void){class_kset = kset_create_and_add("class", NULL, NULL);if (!class_kset)return -ENOMEM;return 0;}
/sys/devices /sys/dev /sys/block /sys/char的创建
代码位于kernel\drivers\base\core.c
int __init devices_init(void){devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);if (!devices_kset)return -ENOMEM;dev_kobj = kobject_create_and_add("dev", NULL);if (!dev_kobj)goto dev_kobj_err;sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj);if (!sysfs_dev_block_kobj)goto block_kobj_err;sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);if (!sysfs_dev_char_kobj)goto char_kobj_err;return 0;}
/sys/bus目录的创建
代码位于kernel\drivers\base\bus.c
int __init buses_init(void){bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);if (!bus_kset)return -ENOMEM;system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);if (!system_kset)return -ENOMEM;return 0;}
在/sys/class下创建目录,如input目录
使用class_register()
代码位于kernel\drivers\input\input.c
static int __init input_init(void){int err;err = class_register(&input_class);if (err) {pr_err("unable to register input_dev class\n");return err;}err = input_proc_init();err = register_chrdev_region(MKDEV(INPUT_MAJOR, 0),     INPUT_MAX_CHAR_DEVICES, "input");if (err) {pr_err("unable to register char major %d", INPUT_MAJOR);goto fail2;}return err;}

在sysfs中创建文件,即为某个kobject增加属性文件

static ssize_t manual_offset_calibration_show(struct device *dev,struct device_attribute *attr, char *buf){u8 reg_value = 0;psx93XX_t this = dev_get_drvdata(dev);LOG_INFO("Reading IRQSTAT_REG\n");read_register(this, SX9310_IRQSTAT_REG, &reg_value);return scnprintf(buf, PAGE_SIZE, "%d\n", reg_value);}static ssize_t manual_offset_calibration_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count){psx93XX_t this = dev_get_drvdata(dev);unsigned long val;if (kstrtoul(buf, 0, &val))return -EINVAL;if (val) {LOG_INFO("Performing manual_offset_calibration()\n");manual_offset_calibration(this);}return count;}static DEVICE_ATTR(calibrate, 0644, manual_offset_calibration_show,manual_offset_calibration_store);static struct attribute *sx9310_attributes[] = {&dev_attr_calibrate.attr,NULL,};static struct attribute_group sx9310_attr_group = {.attrs = sx9310_attributes,};ret = sysfs_create_group(&client->dev.kobj, &sx9310_attr_group);


原创粉丝点击