zl程序教程

您现在的位置是:首页 >  硬件

当前栏目

浅析系统调用(opem,read,write),VFS,驱动三者的关系

驱动系统 调用 关系 浅析 Read Write 三者
2023-09-11 14:18:26 时间


前言

这里为什么说是浅析呢?因为我也是在遇到了一些问题后,尝试自己去寻找答案,并没有特意的去学习VFS这一块的内容!所以有说的不恰当的地方,还望大家多多包含与指针

遇到的问题

  1. 我们在学习驱动的时候,常规的理解就是,我们的应用程序(APP)去调用系统调用函数open,read,write等函数,然后通过系统调用函数去映射我们的驱动函数,相信这里大家肯定是可以理解的,
    我拿之前的博客中的代码来举例子第一个驱动程序

在这里插入图片描述通过file_operations结构体来关联系统调用函数与驱动函数,那么问题来了,它是怎么实现关联的呢?

  1. 在我们查看我们的驱动代码可以知道,我们实现的open函数,其功能是将我们的设备结点文件与我们的设备结构体进行绑定。然后然会0,但是我们在应用程序中所获得的fd的值,显然肯定是一个大于2的数。那么fd又是谁给我们的呢?怎么处理的呢?
    在这里插入图片描述
  2. 为什么提到当我们的驱动程序没有实现open函数的时候,仍然能够获得一个正确的文件描述符而不是直接报出错误呢?
    对于这个问题,大家一个自己尝试验证一下,就简单的写一个驱动程序,不实现该驱动程序的open函数,并向内核进行注册该驱动,然后创建该驱动程序的设备结点,写一个应用程序进行验证即可。

VFS源码分析与问题解决

VFS的基本概念

Linux能够支持各种不同的文件系统是通过VFS实现的,由于不同的物理文件系统具有不同的组织结构和不同的处理方式,为了能够处理各种不同的物理文件系统,操作系统必须把它们所具有的特性进行抽象,并建立一个面向各种物理文件系统的转换机制,通过这个转换机制,把各种不同物理文件系统转换为一个具有统一共性的虚拟文件系统。(可以理解为VFS产生的原因)

VFS是一个软件层,用来处理与Unix标准文件系统相关的所有系统调用,是用户应用程序与文件系统实现之间的抽象层。它实际上向Linux内核和系统中运行的进程提供了一个处理各种物理文件系统的公共接口,通过这个接口使得不同的物理文件系统在内核看起来都是相同的。(可以理解为一切皆文件的根据)

VFS通用文件模型将文件以及其操作对象分为以下几种对象类型:超级块对象(superblock object)存放文件系统相关信息;索引节点对象(inode object)存放具体文件的一般信息;文件对象(file object)存放已打开的文件和进程之间交互的信息;目录项对象(dentry object)存放目录项与文件的链表信息。

好,清楚了基本概念,咱们就直接去看源码是不是这么一回事,看看我抄的这个博客说的有没有问题!

VFS源码分析

超级块对象(superblock object)

超级块是各种具体文件系统在安装时建立的,并在这些文件系统卸载时自动删除,它只存在于内存中
我这里使用的源码是厂商提供给我的开发板的Linux5.4源码,应该不会差太多,大家直接在Source Insight中搜索fs.h就行。
找到我们的超级块对象结构体
在这里插入图片描述
有兴趣的同学可以自己阅读,这里就不解释了。后面有注释
其本质是一个双向的链表
在这里插入图片描述在这里插入图片描述

索引结点对象

源码还是在include/linux/fs.h
文件系统处理文件所需要的所有信息都放在称为索引节点的数据结构中。
在这里插入图片描述
后面都有注释,有兴趣的可以自行阅读。

目录项对象

该对象的声明位于include/linux/dcache.h

在这里插入图片描述

文件对象

定义在 include/linux/fs.h
在这里插入图片描述

分析1:应用程序是如何连接到驱动程序的open函数的

1. 应用程序调用VFS的系统调用ope函数
源码位于fs/open.c,我的没找到,可能是我的版本问题,不再写在这个文件中
在这里插入图片描述核心代码
在这里插入图片描述