在操作系统里面, 最重要的组成部分之一要数文件系统了, 几乎时时刻刻都在与之打交道, 本文就来聊聊文件系统.设备特殊文件
设备特殊文件对应于系统中的某个设备。在内核内部,每种设备类型都有相应的设备驱动程序,该程序负责处理该设备的所有I/O请求。设备驱动程序是一段内核代码单元,它实现了一组(通常)对应于对相关硬件进行输入和输出操作的操作。设备驱动程序提供的API是固定的,包括对应于系统调用 open()、close()、read()、write()、mmap() 和 ioctl() 的操作。每个设备驱动程序都提供一致的接口,隐藏了各个设备操作上的差异,这一事实使得I/O的通用性得以实现. 有些设备是真实的,例如鼠标、磁盘和磁带机。其他的则是虚拟的,这意味着没有相应的硬件;相反,内核(通过设备驱动程序)提供了一个抽象设备,其API与真实设备相同。 Linux操作系统支持设备, 最为有趣之处在于定义了一个API, 设备如果需要适配该系统, 只需要实现定义的这些接口即可, 这样就可以满足对设备的定义, 而操作系统也不同关系其是什么设备以及如何实现的, 只需要按照接口调用方法就行了, 这也满足了Linux操作系统的简洁的设计概念. 设备文件像其他文件一样出现在文件系统中,通常位于 /dev 目录下。root用户可以使用 mknod 命令创建设备文件,root权限的程序也可以使用 mknod() 系统调用来执行相同的任务。设备可分为两种类型:1. 字符设备: 以逐字符的方式处理数据。终端和键盘是字符设备的例子。2. 块设备: 一次处理一块数据。块的大小取决于设备类型,但通常是512字节的倍数。块设备的例子包括磁盘和磁带机。设备ID
每个设备文件都有一个主设备号和一个次设备号。主设备号标识设备的大致类别,内核用它来查找此类设备的适当驱动程序。次设备号则在某个类别中唯一地标识一个特定设备。ls -l 命令会显示设备文件的主次设备号。查看有哪些设备df -hFilesystem Size Used Avail Capacity iused ifree %iused Mounted on/dev/disk1s4s1 233Gi 11Gi 116Gi 9% 356050 1213664840 0% /devfs 187Ki 187Ki 0Bi 100% 648 0 100% /dev/dev/disk1s2 233Gi 3.2Gi 116Gi 3% 1016 1213664840 0% /System/Volumes/Preboot/dev/disk1s6 233Gi 20Ki 116Gi 1% 0 1213664840 0% /System/Volumes/VM/dev/disk1s5 233Gi 66Mi 116Gi 1% 796 1213664840 0% /System/Volumes/Update/dev/disk1s1 233Gi 102Gi 116Gi 47% 1196603 1213664840 0% /System/Volumes/Datamap auto_home 0Bi 0Bi 0Bi 100% 0 0 100% /System/Volumes/Data/home/dev/disk1s4 233Gi 11Gi 116Gi 9% 356884 1213664840 0% /System/Volumes/Update/mnt1查看设备的IDls -l /dev/disk1s2brw-r----- 1 root operator 0x1000005 3 15 09:07 /dev/disk1s2其中设备ID是 0x1000005,它表示该块设备的主设备号和次设备号(主设备号 256,次设备号 5)。
磁盘与分区
普通文件和目录通常驻留在硬盘设备上, 因此磁盘如何进行读写和访问, 就涉及到分区的概念了. 硬盘驱动器是一种机械设备,包含一个或多个以高速旋转的盘片(转速可达每分钟数千转)。磁盘表面以磁编码方式存储的信息,通过沿磁盘径向移动的读/写头进行读取或修改。从物理上看,磁盘表面的信息位于一组称为磁道的同心圆上。磁道本身又被划分为若干扇区,每个扇区由一系列物理块组成。物理块的大小通常为512字节(或其倍数),是驱动器可读写的最小信息单位。尽管现代磁盘速度很快,但读写磁盘信息仍需耗费相当时间。磁头必须先移动到目标磁道(寻道时间),然后驱动器需等待目标扇区旋转到磁头下方(旋转延迟),最后才能传输所需的数据块(传输时间)。执行此类操作所需的总时间通常在毫秒级别。相比之下,现代CPU在此时间内可执行数百万条指令。 每个磁盘被划分为一个或多个(不重叠的)分区。内核将每个分区视为一个独立的设备,这些设备位于/dev目录下。 这里对比一下系统中各类组件的速度, 寄存器 > CPU(L1, L2缓存) > 内存 > 磁盘.文件系统
有了磁盘之后, 还需要定义文件是按照怎样的方式存储在磁盘中的, 这就是文件系统的设计了. 文件系统是普通文件和目录的有组织的集合, 文件系统是使用 mkfs 命令创建的. 多年来,Linux 上使用最广泛的文件系统是 ext2(第二扩展文件系统),它是早期 Linux 文件系统 ext 的后继者。文件系统中分配空间的基本单位是逻辑块,它是文件系统所在磁盘设备上若干个连续物理块的组合。例如,ext2 的逻辑块大小可以是 1024、2048 或 4096 字节. 引导块:这始终是文件系统的第一个块。引导块不被文件系统使用;相反,它包含用于引导操作系统的信息。尽管操作系统只需要一个引导块,但所有文件系统都有一个引导块(其中大部分未被使用)。例如操作系统在进入系统的时候, 会加载引导分区, 用的就是这里的数据. 超级块:这是一个紧跟在引导块之后的单独块,包含有关文件系统的参数信息. i-node表:文件系统中的每个文件或目录在i-node表中都有一个唯一的条目。i-node表对于理解文件是非常有用的, 后续将继续介绍该表中的内容. 数据块:文件系统中的绝大部分空间用于构成驻留在文件系统中的文件和目录的数据块。