参考文章:http://www.wowotech.net/linux_kenrel/dm_sysfs.html
目录
1. 前言
sysfs是一个基于RAM的文件系统,它和kobject一起,可以将Kernel的数据结构导出到用户空间,以文件目录结构的形式,提供对这些数据结构(以及数据结构的属性)的访问支持。
Linux设备模型(二) 基本数据结构 Kobject 已经讲过sysfs和Kobject相关数据结构的关系了,本文不再赘述,本文主要讨论属性和sysfs与普通文件系统的关系。
跟属性相关的关键数据结构有:
struct attribute
struct attribute_group
struct bin_attribute
struct sysfs_ops
2. sysfs 与 attribute
在sysfs中,为什么会有attribute的概念呢?其实它是对应kobject而言的,指的是kobject的“属性”。我们知道,sysfs中的目录描述了kobject,而kobject是特定数据类型变量(如struct device)的体现。因此kobject的属性,就是这些变量的属性。它可以是任何东西,名称、一个内部变量、一个字符串等等。而attribute,在sysfs文件系统中以文件的形式存在,即:kobject的所有属性,都在它对应的sysfs目录下以文件的形式呈现。这些文件一般是可读、写的,而kernel中定义了这些属性的模块,会根据用户空间的读写操作,记录和返回这些attribute的值。
总结:所谓的attibute,就是内核空间和用户空间进行信息交互的一种方法。例如某个driver定义了一个变量,却希望用户空间程序可以修改该变量,以控制driver的运行行为,那么就可以将该变量以sysfs attribute的形式开放出来。
2.1. attribute基础知识
Linux内核中,attribute分为普通attribute,attribute_group,bin_attribute。
源码版本:Kernel 3.10
源码路径:
include/linux/sysfs.h
fs/sysfs/file.c
// include/linux/sysfs.h, line 26
struct attribute {
const char *name;
umode_t mode;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
bool ignore_lockdep:1;
struct lock_class_key *key;
struct lock_class_key skey;
#endif
};
name,属性的名字,对应sysfs中文件的名字。
mode,应用于属性(文件)的保护位,与文件的权限相同。
ignore_lockdep、key、skey,内核用于debug Kernel Lock(一般用不到)。
// include/linux/sysfs.h, line 57
struct attribute_group {
const char *name;
umode_t (*is_visible)(struct kobject *,
struct attribute *, int);
struct attribute **attrs;
};
name,属性组的名字,不为空的话对应一个sysfs的文件夹。
attrs,属性组里的普通属性列表。
is_visible,返回组中属性的读写权限。
// include/linux/sysfs.h, line 100
struct bin_attribute {
struct attribute attr;
size_t size;
void *private;
ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *,
char *, loff_t, size_t);
ssize_t (*write)(struct file *,struct kobject *, struct bin_attribute *,
char *, loff_t, size_t);
int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,
struct vm_area_struct *vma);
};
attr,包含的普通属性。
size,二进制属性的最大长度,如果没有最大值可以设为0。
private,私有数据,与linux中大部分私有数据的用途一样,用于传递私有数据结构。
read、write、mmap,操作二进制属性的函数。
二进制属性不能作为默认属性被设置,只能显式地创建。
struct attribute 为普通的attribute,使用该attribute生成的sysfs文件,只能用字符串的形式读写(第4节中说明)。
struct attribute_group 为普通的attributes的集合,可以在不借助Kobject创建一个目录,并在该目录下创建多个属性文件。
struct bin_attribute 在struct attribute的基础上,增加了read、write等函数,因此它所生成的sysfs文件可以用任何方式读写。固件一般使用bin_attribute属性。
2.2. attibute文件的创建
普通attibute文件的创建是由fs/sysfs/file.c中sysfs_create_file()接口完成的。
attribute_group为普通attributes的集合,由fs/sysfs/group.c中sysfs_create_group()接口来完成创建。
bin_attribute文件的创建是由fs/sysfs/bin.c中sysfs_create_bin_file()接口完成的。
注:上述三个接口的实现没有什么特殊之处,大多是文件系统相关的操作,和设备模型没有太多的关系,这里先略过不提。
2.3. 普通attibute文件的read和write
看到2.1章节struct attribute的原型时,也许我们会犯嘀咕,该结构很简单啊,name表示文件名称,mode表示文件模式,其它的字段都是内核用于debug Kernel Lock的,那文件操作的接口在哪里呢?
不着急,我们去fs/sysfs目录下看看sysfs相关的代码逻辑。
所有的文件系统,都会定义一个struct file_operations变量,用于描述本文件系统的操作接口,sysfs也不例外:
// fs/sysfs/file.c, line 479
const struct file_operations sysfs_file_operations = {
.read = sysfs_read_file,
.write = sysfs_write_file,
.llseek = generic_file_llseek,
.open = sysfs_open_file,
.release = sysfs_release,
.poll = sysfs_po