Linux设备管理(四)(3)

这其中的symlink就组成了下面的符号链接,许许多多这样的符号链接就构成了整个sysfs的符号链接体系

sys $ll devices/platform/serial8250/ lrwxrwxrwx 1 root root 0 1220 16:17 driver -> ../../../bus/platform/drivers/serial8250/ -rw-r--r-- 1 root root 4096 1220 16:17 driver_override -rw-r--r-- 1 root root 4096 1220 16:17 uevent ... sysfs与ktype

在sysfs中,kobject的属性(kobject.ktype.attribute)可以以普通文件的形式导出,sysfs还提供了使用文件I/O直接修改内核属性的机制,这些属性一般都是ASCII格式的文本文件(ktype.attribute.name)或二进制文件(通常只用在sys/firmware中),为了提高效率,可以将具有同一类型的属性放置在一个文件中,这样就可以使用数组进行批量修改,不要在一个文件中使用混合类型,也不要使用多行数据,这些做法会大大降低代码的可读性,下面就是一个属性的定义,可以看到,属性中并没有包含读写属性的函数,但是从面向对象的思想看,内核提供了两个用于读写attribute结构的函数。

//include/linux/sysfs.h 29 struct attribute { 30 const char *name; 31 umode_t mode; 32 #ifdef CONFIG_DEBUG_LOCK_ALLOC 33 bool ignore_lockdep:1; 34 struct lock_class_key *key; 35 struct lock_class_key skey; 36 #endif 37 }; int sysfs_create_file(struct kobject * kobj, const struct attribute * attr); void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr);

由于一个ktype往往包含很多属性(default_attr是一个二级指针),当用户通过sysfs读写一个kobject的属性的时候,会自动回调ktype中的sysfs_ops->show()sysfops->remove(),所以一个典型的做法是,当我们创建了一个继承自kobject的子类child后,同时还会创建两个调用了sysfs_create_file()sys_remove_file()的读写函数,并将它们注册到struct sysfs_ops中。比如内核使用的struct device就将相应的方法和属性都封装在了一起。

//include/linux/device.h 512 /* interface for exporting device attributes */ 513 struct device_attribute { 514 struct attribute attr; 515 ssize_t (*show)(struct device *dev, struct device_attribute *attr, 516 char *buf); 517 ssize_t (*store)(struct device *dev, struct device_attribute *attr, 518 const char *buf, size_t count); 519 }; 560 extern int device_create_file(struct device *device,const struct device_attribute *entry); 562 extern void device_remove_file(struct device *dev,const struct device_attribute *attr);

此外,内核甚至还提供了辅助定义这个属性的宏

//include/linux/device.h 539 #define DEVICE_ATTR(_name, _mode, _show, _store) \ 540 struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) //include/linux/sysfs.h 75 #define __ATTR(_name, _mode, _show, _store) { \ 76 .attr = {.name = __stringify(_name), \ 77 .mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \ 78 .show = _show, \ 79 .store = _store, \ 80 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/4660794135ab141263397c309971b569.html