【Linux 0.11】第十二章 文件系统

341 阅读10分钟
  • 有遗留,还是不懂。

exfat:windows、mac、linux、

赵炯;《Linux 内核完全注释 0.11 修正版 V3.0》

www.cnblogs.com/zongzi10010…

文件系统是地图,是抽象,对块设备的抽象,让我们能够通过文件名来访问扇区。

文件系统是一些代码,是一套软件,这套软件的功能就是对存储设备的扇区进行管理,将这些扇区的访问变成了对目录和文件名的访问。我们在上层按照特定的目录和文件名去访问一个文件时,文件系统会将这个目录+文件名转换成对扇区号的访问。

  • 虚拟文件系统存储在RAM里的,没有实际的设备(ROM)与之对应;虚拟文件系统接口是 Linux 定义的一个文件系统地统一接口,这样各种类型地文件系统都采用一样地接口给用户。
  • 实际文件系统有实际的存储设备(ROM)与之对应,又可分为远程文件系统和本地文件系统;
  • 根文件系统处于文件系统的最上层,其很重要的作用是用来挂载其他文件系统。根文件系统可以是虚拟文件系统也可以是实际文件系统,只要条件支持;/dev/xxx:根文件系统。
  • 文件系统格式
    • ramdisk/initramfs:基于 ram 的文件系统,将一部分固定大小的内存当作块设备来使用,并非是一个实际的文件系统,而是一种将实际的文件系统装入内存的机制,将经常访问而又无需修改的文件通过ramdisk放在内存中,可以明显地提高系统性能。

挂载文件系统方式:

  1. ramdisk

将真正的文件系统保存为 ramdisk,保存到内存的 ramdisk。

制作 ramdisk 文件系统压缩包,保存至内存中,当系统启动时,通过 uboot 的 bootargs 环境变量来传递启动参数 bootargs=initrd=0x31000000,0x200000 root=/dev/ram rw init=/linuxrc console=ttySAC0 mem=64 指定从 ramdisk 启动。亦可修改内核配置,Default kernel command string initrd=0x31000000,0x200000 root=/dev/ram rw init=/linuxrc console=ttySAC0 mem=64

  1. Flash 中的 FS

根文件系统和其它文件系统的mount方式不一样,内核通过直接解析设备的名称来获得设备的主从设备号,然后就可以访问对应的设别驱动了。bootloader 或内核中设定的启动参数 root=/dev/xxx只是一个代号,实际的根文件系统中不一定存在这个设备文件。

  1. initramfs

真正文件系统已编译入内核,仅仅解压到 rootfs 即可。

initramfs将根目录直接编译到linux内核镜像中 ,这种方法不同于前面两种方法需要在uboot启动参数中指定ramdisk加载到内存的地址或者文件系统在flash中的分区,由于已经将根目录编译到linux的.init.ramfs段中了,所以启动的时候直接将linux内核镜像的.init.ramfs段的内容解压到系统的rootfs中。

  1. inird

真正文件系统的阉割版,需要映射到真正的文件系统。

用 initrd 来挂载根文件系统,具体实现也是用 ramdisk 技术,bootloader 在装载 linux 之前,可以把一个较小的根文件系统的映像装在在内存的某个指定位置(占用内存而非ramdisk),initrd的具体实现过程是这样的:bootloader把根文件系统映象装载到内存指定位置,把相关参数传递给内核,内核启动时把initrd中的内容复制到ramdisk中(ram0),把initrd占用的内存释放掉,在ram0上mount根文件系统。从这个过程可以看出,内核需要同时对ramdisk和initrd的支持(这种需要都编入内核,不能作为模块)。

ramdisk 只是在 ram 上实现的块设备,类似与硬盘操作,可以在系统运行的任何时候使用,而不仅仅是用于启动。

内核加载的时候,RAM其实已经可用了,那就基于RAM建立一个临时文件系统吧,这个临时的文件系统自己挂载到自己身上,然后我们指定这个文件系统为根文件系统,这样就有了起步的文件系统啦,借助这个临时的文件系统把磁盘驱动模块、网络驱动模块加载上,这样就可以挂载实际的文件系统啦,有了实际的文件系统之后再把这个实际的文件系统指定为根文件系统,这就好啦,然后其他的各式各样的文件系统就可以陆陆续续的挂载在这个根文件系统下了。

.MINIX 文件系统

MINIX 文件系统由以下六个部分构成,整个磁盘被划分为以 1KB 为单位的磁盘块,磁盘块与逻辑块的大小一致,均为 1KB。

  • 引导块。是计算机加电启动时由 ROM BIOS 自动读入的执行代码和数据。对于不用于引导的==盘片==,这一盘块中可以不含代码,但是任何盘片必须含有引导块空间,以保持 MINIX 文件系统格式的统一。即文件系统只是在块设备上空出一个存放引导块的空间。如果你把内核映像放在文件系统中,那么就可以在文件系统所在设备的第一个块存放实际的引导程序,并由它来取得和加载文件系统中的内核映像文件。

请添加图片描述 对于硬盘块设备,通常会有多个分区,并且在每个分区中都可以存放一个不同的文件系统。 主引导扇区是硬盘的第一个扇区,其中存放着硬盘引导程序和分区表信息,分区表中的信息指明了硬盘上每个分区的类型、在硬盘中起始位置参数和结束位置参数以及占用的扇区总数。 请添加图片描述

  • 超级块。用于存放所有文件系统结构的信息,并说明各部分的大小。

请添加图片描述

  • 逻辑块位图。其用于描述盘上每个数据盘块的使用情况。除位 0 外,每个位标志数据区的一个逻辑块。当一个数据盘块被占用时,逻辑块位图中相应的比特位置位。从超级块的结构中我们可以发现,逻辑块位图最多可以使用 8 个逻辑块,总共能够表示的数据块个数是:8x8x1024,即 MINIX 文件系统 1.0 所能支持的最大块设备容量为 64MB。
  • i 节点位图用于说明 i 节点是否被使用。每个比特位代表一个 i 节点,对于 1K 大小的盘块来说,一个盘块可以表示 8192 个 i 节点的使用情况,与逻辑块位图的情况类似,由于当所有 i 节点都被使用时查找空闲 i 节点的函数会返回 0 值,因此 i 节点位图第 1 个字节的最低比特位(位0)和对应的 i 节点 0 都空闲不用,可以在创建文件系统时预先将 i 节点 0 对应比特位图中的比特位置位。因此第一个 i 节点位图块中只能表示 8191 个 i 节点的状况。
  • 盘上的 i 节点部分存放着文件系统中文件或目录名的索引节点。每个文件或目录都有一个 i 节点每个 i 节点结构中存放着对应文件的相关信息 —— 文件属主id、文件属组id、文件长度、访问修改时间以及文件数据块在盘上的位置等。

2+2+4+4+1+1+2x9 = 32B

请添加图片描述

2B: 请添加图片描述 文件中的数据是放在磁盘块的数据区中,而一个文件名则通过对应的 i 节点与这些数据磁盘块相联系,盘块的号码存放在 i 节点的逻辑块数组 i_zone[] 中。i_zone[0] - i_zone[6] 存放 7 个直接块,i_zone[7] 是一次间接块,i_zone[8] 是二次间接盘块(能够寻址 512x512 个盘块)。

一般以一个扇区(512B)的长度作为块设备的数据块长度,而 MINIX 文件系统将连续两个扇区数据作为一个数据块来处理,称为一个磁盘块。(预读取相关?) 在这里插入图片描述 在文件系统的一个目录中,其中所有文件名信息对应的目录项存储在该目录文件名文件的数据块中。例如,目录名 root/ 下的所有文件名的目录项保存在 root/ 目录名文件的数据块中,而文件系统根目录下的所有文件名信息则保存在指定 i 节点的数据块中。

每个目录项只包括一个长度为 14 字节的文件名字符串和该文件名对应的 2 字节的 i 节点号。 一个逻辑盘块可以存放 1024/16=64 个目录项。有关文件的其它信息被保存在该 i 节点指定的 i 节点结构中 —— 文件访问属性、宿主、长度、访问保存时间、所在磁盘块等。

i 节点中一项就是一个文件/目录,一个 i 节点数据块里面包含有 1024 / 32 = 32 个项目,一个目录中的每一项需要有两个 i 节点数据块来指向磁盘区域。如果仅包含有一个 i 节点位图,那么意味着最多可以有 8191 个 i 节点数据块,意味着可以有 8191 x 32 = 262112 个文件/目录。 在这里插入图片描述 对于 /usr/bin/vi 的 i 节点号查找:

文件系统首先从具有固定 i 节点号(1)的根目录开始操作,即从 i 节点号 1 的数据块中查找到名称为 usr 的目录项,从而得到文件 /usr 的 i 节点号,根据该 i 节点号文件系统可以顺利地取得目录 /usr,并在其中可以查到文件名 bin 的目录项。这样也就知道了 /usr/bin 的 i 节点号,因而我们可以知道目录 /usr/bin 的目录所在位置,并在该目录中找到 vi 文件的目录项。最终我们获得了文件路径名 /usr/bin/vi 的 i 节点号,从而可以从磁盘上得到该 i 节点号的 i 节点结构信息。

通过指定的文件名,我们可以找到对应的目录项。根据目录项的 i 节点号就可以找到 i 节点表中相应的 i 节点结构。 i 节点结构中包含着该文件数据的块号信息,最终可以得到文件名对应的数据信息。每个 i 节点结构中都有一个链接计数字段 i_nlinks 记录着指向该 i 节点的目录项数 —— 文件的硬链接计数值(实时备份)。在执行删除操作文件时,只有当 i 节点链接计数值等于 0 时内核才会真正删除磁盘上该文件的数据。

由于目录项中 i 节点号仅能用于当前文件系统中,因此不能使用一个文件系统的目录项来指向一个文件系统的 i 节点,硬链接不能跨越文件系统。

符号链接类型的文件名目录项并不直接指向对应的 i 节点,符号链接目录项会在对应文件的数据块中存放某一文件的路径名字符串。当访问符号链接目录项时,内核就会读取该文件中的内容,然后根据其中的路径名字符串来访问指定的文件。因此符号链接可以不局限在一个文件系统中,我们可以在一个文件系统中建立一个指向另一个文件系统中文件名的符号链接。

请添加图片描述

在这里插入图片描述 每一行对应一个目录项,每行开始两个字节是 i 节点号,随后的 14 字节是文件名或目录名字符串。