前面分别分析了devtmpfs、sockfs,本次开始分析sysfs文件系统,该文件系统与设备驱动模型是结合使用的。因此在介绍该文件系统的同时,也需要说明linux的设备驱动程序模型。
本次sysfs文件系统分析主要涉及如下几个主题:
一、sysfs文件系统注册以及挂载
- 文件系统的注册;
- 文件系统的挂载
二、sysfs文件系统相关的结构体说明
- 相关结构体说明
三、sysfs的文件操作解析
- 文件操作相关的结构体及其关联说明
- open接口说明
- read接口说明
- write接口说明
四、linux设备驱动模型说明
- 概念说明(device、driver、bus、class等)
- 设备驱动对应结构体的属性说明
- bus的创建
- device的创建
- driver的创建
五、bus总线的介绍(以platform总线为例)
一、sysfs文件系统注册及挂载
1.文件系统的定义
sysfs是一个内存文件系统,该文件系统主要在用户态展示系统硬件相关的设备、驱动、总线等层级关系。该文件系统将系统上的总线、设备、驱动等,按照不同的分类方式进行展示,应用层可对相应的文件属性值进行读写操作。目前sysfs按照device、bus、class、kernel、drivers、power等进行分类(具体分类如下图所示),其中devices中包含系统中所有的设备、drivers中包含所有已注册的驱动、bus中包括所有总线相关的信息、class中系统的设备类型(包括tty、net、rtc、gpio等)
以上是针对sysfs的简要说明,下面我们看下sysfs的文件系统的定义,sysfs的超级块处理接口
static struct file_system_type sysfs_fs_type = {
.name = "sysfs",
.mount = sysfs_mount,
.kill_sb = sysfs_kill_sb,
.fs_flags = FS_USERNS_MOUNT,
};
2.文件系统的注册及挂载
在sysfs_init接口中实现文件系统的注册以及挂载,该接口的实现比较简单,如下流程所示(该流程图忽略了错误处理的内容),主要就是文件系统的注册以及文件系统的kern_mount(此时并没有真正挂载,但是已完成超级块、根root、根dentry、vfsmount的创建,待文件系统起来时,执行mount -t sysfs none /sys,在系统调用sys_mount时,通过调用do_add_mount实现将sysfs挂载至sys目录下。另外在sys_mount接口中,创建或者查找超级块是通过调用sb = sget(fs_type, sysfs_test_super, sysfs_set_super, flags, info);语句实现的,若对sysfs进行多次mount时,只创建一次超级块,因调用sysfs_test_super时对文件系统的私有变量判断相同,则无需再次创建超级块)。
针对文件系统注册接口register_filesystem,我们在之前的文章中已经介绍过(具体请参考《LINUX VFS分析之文件系统注册与挂载相关的分析》《LINUX VFS分析之VFS相关的概念及数据结构》、《LINUX VFS分析之进程描述符与文件系统相关参数的关联》)。下面我们针对sysfs文件系统的挂载进行一下分析,其处理流程图如下所示,针对kern_mount接口调用相关的内容,已在文件系统相关的分析文章中介绍过,有兴趣的请查看上面的链接文章。
此处主要介绍sys_mount接口,该接口调用sget创建超级块,并调用sysfs_fill_super对sysfs的超级块进行设置,主要是设置超级块的操作接口指针、根dentry的操作接口等内容(sysfs_fill_super接口的定义如下流程图所示)。
sysfs_ops为sysfs的超级块处理接口,包括获取文件系统状态的接口,删除inode的接口,通过如下定义我们发现,其并没有提供inode节点的创建接口。
static const struct super_operations sysfs_ops = {
.statfs = simple_statfs,
.drop_inode = generic_delete_inode,
.evict_inode = sysfs_evict_inode,
};
以上主要介绍了sysfs文件系统的注册以及挂载操作,在我们熟悉了LINUX VFS相关的内容后,sysfs文件系统的挂载分析,相对来说还是比较简单,下一章主要介绍sysfs文件系统相关的结构体以及结构体之间的关联