Linux文件系统学习(一)之相关概念⭐⭐⭐
“一切皆是文件”是 Unix/Linux 的基本哲学之一。不仅普通的文件,目录、字符设备、块设备、套接字等在 Unix/Linux 中都是以文件被对待;它们虽然类型不同,但是对其提供的却是同一套操作界面。另外所谓的块设备:是指支持随机访问的存储设备;与此相对应的是字符设备,它只支持顺序访问。另外Linux将文件的相关信息和文件本身这两个概念加以区分,这两者在磁盘上都需要存储,前者经常又被称为inode节点,后者才是实际的文件内容,但必须通过前者才能找到该文件实际存放的磁盘位置,及操作方法。
VFS使得可以通过使用同一套文件 I/O 系统调用即可对 Linux 中的任意文件进行操作而无需考虑其所在的具体文件系统格式;更进一步,对文件的操作可以跨文件系统而执行。如我们可以使用 cp 命令从 vfat 文件系统格式的硬盘拷贝数据到 ext3 文件系统格式的硬盘;而这样的操作涉及到两个不同的文件系统。不同的文件系统块大小可能不一样(在超级块中定义),一般大多数文件系统使用512B。VFS即虚拟文件系统是Linux文件系统中的一个抽象软件层;因为它的支持,众多不同的实际文件系统才能在Linux中共存,跨文件系统操作才能实现。VFS借助它四个主要的数据结构即超级块、索引节点、目录项和文件对象以及一些辅助的数据结构,向Linux中不管是普通的文件还是目录、设备、套接字等都提供同样的操作界面,如打开、读写、关闭等。只有当把控制权传给实际的文件系统时,实际的文件系统才会做出区分,对不同的文件类型执行不同的操作。由此可见,正是有了VFS的存在,跨文件系统操作才能执行,Unix/Linux中的“一切皆是文件”的口号才能够得以实现。(不同文件系统的统一io接口)
如:
■什么是VFS
VFS是软件, 一个什么样的软件呢? 是一个用来管理多个实际文件系统的软件
比如linux系统下有两个实际的文件系统, 一个fat32类型磁盘A , 一个ext3类型磁盘B, 如果我要将A上的一个文件1.txt拷贝到B中去,我只需要在中端敲击命令 cp path1/1.txt path2
就可以了, 而底层会如何做的?
1.根据path1找到对应的1.txt文件标识(inode 1)
2.调用inode 1对应的拷贝函数(此拷贝函数对应的是fat32类型的),将磁盘中的1.txt内容读入高速缓存中
3.根据path2找到对应目的地的inode 2
4.调用inode 2对应的拷贝函数(此拷贝函数对应的是ext3类型的),将高速缓存中1.txt内容拷贝到path2指定的目的地
这1-4的过程就是VFS其中的一部分
图VFS在内核中与其他的内核模块的协同关系
文件系统的三个操作过程:
注册: 向内核报到声明自己能被内核支持。一般在编译内核的时侯注册;也可以加载模块的方式手动注册。注册过程实际上是将表示各实际文件系统的数据结构struct file_system_type 实例化。
创建: 以某种方式格式化磁盘的过程就是在其之上建立一个文件系统的过程。创建文现系统时,会在磁盘的特定位置写入关于该文件系统的控制信息,即向磁盘写超级块。
安装: 也就是我们熟悉的mount操作,将文件系统加入到Linux的根文件系统的目录树结构上;这样文件系统才能被访问,通过目录来查找。
--
①file_operations与vfs
file_operations结构体中每个函数指针所指向的操作函数都是需要传进一个inode表项结构体的;
struct inode 包括很重要的两个成员:
dev_t i_rdev 设备文件的设备号
struct cdev *i_cdev 代表字符设备的数据结构,struct inode结构是用来在内核内部表示文件的。同一个文件可以被打开好多
次,所以可以对应很多struct file,但是只对应一个struct inode.
open方法根据inode中的设备号在已注册的字符设备驱动中查找cdev,这个cdev里的fops才是驱动提供的。它会赋给file结构体中相应成员(file_operations结构体)
(覆盖了之前的一次赋值),其open方法不为空则调用之
②device----driver
add platform_device之后,需要注意的一个地方是这里,add是通过系统初始化里边调用platform_add_devices把所有放置在板级platform_device数组中的所有platform_device逐次调用platform_device_register添加到系统中去,platform_device_register中会调用platform_device_add(注意:这个同platform_add_devices有本质区别的),全部add到系统之后,便可以通过platform的操作接口来获取platform_device中的resource资源,比如地址、中断号等,以进行request_memregion、ioremap(将resource分配的物理地址映射到kernel的虚拟空间来)和request_irq操作。platform的操作接口包括:
@||| 69 platform_get_irq
@||| 70 platform_get_irq_byname
@||| 71 platform_get_resource
@||| 72 platform_get_resource_byname
add操作是在系统初始化时完成,因此在后续挂在platform虚拟总线上的设备在驱动模块insmod到系统时,驱动代码里边就可以通过上面函数来获取对应platform_device的resource,比如在module_init中我们会调用plarform_driver_register,这个会引用到platform_driver中的probe函数,而probe函数中则可以进行cdev的初始化及cdev_add的操作,在进行这些操作之前,可以通过get_resource来获取寄存器物理基地址,然后ioremap到kernel的虚拟空间来,这样驱动就可以正式操纵改设备的寄存器了。
至于platform_driver的注册过程,及何时调用probe函数,下面引用一下kernel中的调用关系就清晰明了了:
驱动注册的时候 platform_driver_register()->driver_register()->bus_add_driver()->driver_attach()->bus_for_each_dev() 对每个挂在虚拟的platform bus的设备作 __driver_attach()->driver_probe_device()->drv->bus->match()==platform_match()-& gt;比较strncmp(pdev->name, drv->name, BUS_ID_SIZE),如果相符就调用platform_drv_probe()->driver->probe(),如果probe成 功则绑定该设备到该驱动
③driver---probe
1.drv->bus->match()首先调用驱动或设备所属bus总线提供的match函数,初步检测在bus总线级别是否能匹配
2.dev->bus->probe()如果不存在,那么调用drv->probe(),更周详的检测驱动和设备的匹配程度.
对于usb系统match函数由usb系统自有的usb_bus_type结构体提供,usb的bus系统不提供probe()函数,必须由用户
的驱动程式提供
kobj_map函数中哈希表的实现原理和前面注册分配设备号中的几乎完全一样,通过要加入系统的设备的主设备号major(major=MAJOR(dev))来获得probes数组的索引值i(i = major % 255),然后把一个类型为struct probe的节点对象加入到probes[i]所管理的链表中,如图2-6所示。其中struct probe所在的矩形块中的深色部分是我们重点关注的内容,记录了当前正在加入系统的字符设备对象的有关信息。其中,dev是它的设备号,range是从次设备号开始连续的设备数量,data是一void *变量,指向当前正要加入系统的设备对象指针p。图2-6展示了两个满足主设备号major % 255 = 2的字符设备通过调用cdev_add之后,cdev_map所展现出来的数据结构状态。
----
Linux文件系统学习(一)之相关概念⭐⭐⭐的更多相关文章
- linux文件系统学习
linux系统支持很多种文件系统. 1. 如何确认当前系统挂载了哪些文件系统? 使用mount命令可以查看当前系统上已经挂载了哪些文件系统, sh-# mount rootfs on / type r ...
- [Linux] linux文件系统学习
linux系统支持很多种文件系统. 1. 如何确认当前系统挂载了哪些文件系统? 使用mount命令可以查看当前系统上已经挂载了哪些文件系统, lqt@lqt-ThinkPad-T420:~$ moun ...
- Linux文件系统学习笔记-1
在Linux中, 一切皆文件,不论是目录,设备,套接字等都可以看成文件,而且每一个文件对应一个inode号,这是一一对应的关系. [root@oracle ~]# ls -il 总用量 2624 ...
- 学习笔记:CentOS7学习之十四:linux文件系统
目录 1. 机械硬盘结构 1.1 机械硬盘结构 1.2 簇和block 2.文件系统结构 2.1 文件名 2.2 inode的内容 2.3 inode的大小 2.4 目录文件 2.5 block块大小 ...
- Linux 学习手记(2):Linux文件系统的基本结构
Linux 文件系统概况 Linux文件系统为一个倒置的树状结构,所有文件或文件夹均包含在一个根目录“/”中.如图所示(每个目录的作用可以参考:Linux目录结构说明): Linux系统严格区分大小写 ...
- 理解与学习linux 文件系统的目录结构
1. linux文件系统的结构 linux文件系统是以一种树形结构存在,Linux的文件系统的入口就是/,所有的目录.文件.设备都在/之下,/就是Linux文件系统的组织者,也是最上级的领导者. 2. ...
- Linux 学习总结(五)-linux 文件系统及相关命令
一 linux文件系统概要 linux系统结构有别用于windos,他是树状结构的文件系统,在linux下我们称一切皆文件,我们将一个目录,可以成称为目录文件.linux只有一个单独的顶级目录结构.所 ...
- Linux学习之二十-Linux文件系统
Linux文件系统 文件系统的定义 文件系统是操作系统的必备软件,文件系统是对一个存储设备上的数据(block)和元数据(inode)进行组织的一种机制.文件系统可以帮助用户管理磁盘空间,进行文件的快 ...
- 【Linux学习】Linux文件系统6—文件目录权限设置
Linux文件系统6-文件目录权限设置 1. chmod操作权限设置 chomd是用来改变文件或目录权限的命令,但只有文件的属主和超级权限用户root才有这种权限.通过chmod来改变文件 ...
随机推荐
- CodeForces 24D Broken robot (概率DP)
D. Broken robot time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- 学习IPFS
注:以下所有操作均在CentOS 6.8 x86_64位系统下完成. IPFS(InterPlanetary File System)是一个点对点的分布式超媒体分发协议,被认为是最有可能取代HTTP的 ...
- echarts学习心得1---模块化单文件引入和标签式单文件引入
一.模块化单文件引入 1. 为ECharts准备一个具备大小(宽高)的Dom(当然可以是动态生成的) <div id="main" style="height:40 ...
- Elasticsearch提示low disk watermark [85%] exceeded on [UTyrLH40Q9uIzHzX-yMFXg][Sonofelice][/Users/baidu/Documents/work/soft/data/nodes/0] free: 15.2gb[13.4%], replicas will not be assigned to this node
mac本地启动es之后发现运行一段时间一分钟就能打印好几条info日志: [--13T10::,][INFO ][o.e.c.r.a.DiskThresholdMonitor] [Sonofelice ...
- 持续集成之戏说Check-in Dance(转)
add by zhj: 先说一下持续集成的定义,这是ThoughtWorks首席科学家Martin Fowler在<持续集成>第二版中给出的,“持续集成是一种软件开发实践.在持续集成中,团 ...
- 爬虫之Xpath详解
XPath介绍 XPath 是一门在 XML 文档中查找信息的语言.XPath 可用来在 XML 文档中对元素和属性进行遍历. XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 ...
- Python标准库 之 turtle(海龟绘图)
turtle库介绍 首先,turtle库是一个点线面的简单图像库(也被人们成为海龟绘图),在Python2.6之后被引入进来,能够完成一些比较简单的几何图像可视化.它就像一个小乌龟,在一个横轴为x.纵 ...
- SQL学习笔记。
数据库视图: 视图是虚表,是从一个或几个基本表(或视图)中导出的表,在系统的数据字典中仅存放了视图的定义,不存放视图对应的数据. 视图是原始数据库数据的一种变换,是查看表中数据的另外一种方式.可以将视 ...
- Python学习笔记(一)数据类型
一.整型和浮点型 Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样 age=10 num=-35 score=98.8 二.布尔类型 布尔值和布尔代数的表示 ...
- C语言中的extern
extern: 这个关键字真的比较恶心,在定义变量的时候,extern居然可以被省略(定义时,默认均省略): 在声明变量的时候,extern必须加在变量前. 所以有时候你搞不清楚是声明还是定义.:变量 ...