1.硬件
常见的硬件有磁盘、服务器、机柜、机房机械磁盘但
是计算机中唯一的一个机械设备磁盘
外设的特点就是 外设慢容量大,价格便宜
1.1.磁盘的物理结构
磁盘的物理图:

磁盘的存储图
扇区:是磁盘存储数据的基本单位,512字节,块设备


磁盘的逻辑图:

1.2.CHS和LBA

扇区是从磁盘读出和写入信息的最小单位,通常大小为512 字节。
1.磁头(head)数:每个盘片一般有上下两面,分别对应1个磁头,共2个磁头
2.磁道(track)数:磁道是从盘片外圈往内圈编号0磁道,1磁道...,靠近主轴的同心圆用于停靠磁头,不存储数据
3.柱面(cylinder)数:磁道构成柱面,数量上等同于磁道个数
4.扇区(sector)数:每个磁道都被切分成很多扇形区域,每道的扇区数量相同
5.圆盘(platter)数:就是盘片的数量
6.磁盘容量=磁头数 x 磁道(柱面)数 x 每道扇区数 x 每扇区字节数
有了上面的理解,知道磁盘的最小单位为一个扇区(512字节)
如何定位一个扇区呢,分下面三个步骤:
这个操作简称CHS
1.可以先定位磁头(header)
2.确定磁头要访问哪一个柱面(磁道)(cylinder)
3.定位一个扇区(sector)
1.磁道:
某一个盘面某一个磁道的展开:

一维数组
2.柱面:

柱面上的每个磁道,扇区个数是一样的
就是二维数组
3..整盘:
整个磁盘不就是多张二维的扇区数组表(三维数组)
所以,寻址一个扇区:先找到哪一个柱面(Cylinder),在确定柱面内哪一个磁道(其实就是磁头位置,Head),在确定扇区(Sector),所以就有了CHS。
所以,每一个扇区都有一个下标,我们叫做LBA(Logical Block Address)地址,其实就是线性地址

CHS和LBA直接的转换:
OS只需要使用LBA就可以了 LBA地址转成CHS地址,CHS如何转换成为LBA地址。都是磁盘自己来做
1.CHS转成LBA:
磁头数*每磁道扇区数=单个柱面的扇区总数
LBA=柱面号C*单个柱面的扇区总数+磁头号H*每磁道扇区数+扇区号S-1
即:LBA=柱面号C*(磁头数*每磁道扇区数)+磁头号H*每磁道扇区数+扇区号S-1扇区号通常是从1开始的,而在LBA中,地址是从0开始的
柱面和磁道都是从0开始编号的
总柱面,磁道个数,扇区总数等信息,在磁盘内部会自动维护,上层开机的时候,会获取到这些参数。
2.LBA转成CHS:
柱面号C=LBA//(磁头数*每磁道扇区数)【就是单个柱面的扇区总数】。
磁头号H=(LBA%(磁头数*每磁道扇区数)) //每磁道扇区数
扇区号S=(LBA%每磁道扇区数)+1
"/":表示除取整
所以:从此往后,在磁盘使用者看来,根本就不关心CHS地址,而是直接使用LBA地址,磁盘内部自己转换。所以:
从现在开始,磁盘就是一个 元素为扇区 的一维数组,数组的下标就是每一个扇区的LBA地址。OS使用磁盘,就可以用一个数字访问磁盘扇区了。
2.文件系统
2.1.块
操作系统读取硬盘数据的时候,其实是不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。硬盘的每个分区是被划分为一个个的"块"。一个"块"的大小是由格式化的时候确定的,并且不可以更改,最常见的是4KB,即连续八个扇区组成一个"块"。"块"是文件存取的最小单位。

1.磁盘就是一个三维数组,我们把它看待成为一-维数组",数组下标就是LBA,每个元素都是扇午
2.每个扇区都有LBA,那么8个扇区一个块,每一个块的地址我们也能算出来。
3.知道LBA:块号=LBA/8
4.知道块号:LAB=块号*8+n.(n是块内第几个扇区)

2.2.分区
其实磁盘是可以被分成多个分区(partition)的,以Windows观点来看,你可能会有一块磁盘并且将它分区成C,D,E盘。那个C,D,E就是分区 。分区从实质上说就是对硬盘的一种格式化。但是Linux的设备都是以文件形式存在,那是怎么分区的呢?

2.3.inode
都知道
文件=内容+属性
所以文件的内容和属性在磁盘中也是分开存储的

所以文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息(属性信息),比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"

注意事项:
1.Linux下文件的存储是属性和内容分离存储的
2.Linux下,保存文件属性的集合叫做inode,一个文件,一个inode,inode内有一个唯一的标识符,叫做inode号
3.文件名属性并未纳入到inode数据结构内部
4.inode的大小一般是128字节或者256
3.ext2文件系统
我们想要在硬盘上储⽂件,必须先把硬盘格 式化为某种格式的⽂件系统,才能存储⽂件。⽂件系统的⽬的就是组织和管理硬盘中的⽂件。在Linux 系统中,最常⻅的是 ext2 系列的⽂件系统。
ext2文件系统将整个分区划分成若干个同样大小的块组(Block Group),只要能管理一个分区就能管理所有分区,也就能管理所有磁盘文件。

3.1.Block Group内部结构

3.1.1.超级块(super Block)

存放文件系统本身的结构信息,描述整个分区的文件系统信息。
记录的信息主要有:
1.bolck和inode的总量,
2.未使用的block和inode的数量,
3.一个block和inode的大小,
4.最近一次挂载的时间,
5.最近一次写入数据的时间,
6.最近一次检验磁盘的时间等其他文件系统的相关信息。
Super Block的信息被破坏,可以说整个文件系统结构就被破坏了
超级块在每个块组的开头都有一份拷贝(第一个块组必须有,后面的块组可以没有)。为了保证文件系统在磁盘部分扇区出现物理问题的情况下还能正常工作,就必须保证文件系统的super block信息在这种情况下也能正常访问。所以一个文件系统的super block会在多个block group中进行备份,这些super block区域的数据保持一致。
3.1.2.块组描述符(GDT)

块组描述符表,描述块组属性信息,整个分区分成多个块组就对应有多少个块组描述符。每个块组描述符存储一个块组 的描述信息,
1.如在这个块组中从哪里开始是inode Table,
2.从哪里开始是DataBlocks,
3.空闲的inode和数据块还有多少个等等。
块组描述符在每个块组的开头都有一份拷贝
3.1.3.块位图和inode位图
Block Bitmap中记录着Data Block中哪个数据块已经被占⽤,哪个数据块没有被占⽤
每个bit表⽰⼀个inode是否空闲可⽤
3.1.4. i节点表(Inode Table)
存放文件属性 如 文件大小,所有者,
最近修改时间等当前分组所有Inode属性的集合
inode编号以分区为单位,整体划分,不可跨分区
3.1.5 .Data Block
数据区:存放文件内容,也就是一个一个的Block。根据不同的文件类型有以下几种情况:
1.对于普通文件,文件的数据存储在数据块中。
2.对于目录,该目录下的所有文件名和目录名存储在所在目录的数据块中,除了文件名外,[s-l命令看到的其它信息保存在该文件的inode中。
3.Block 号按照分区划分,不可跨分区
3.2.inode和datablock映射
inode内部有个逻辑结构就是用来进行inode和block映射的这样文件=内容+属性,就都能找到了。
下面就是如果文件的大小太大了,就需要分级存储了

创建一个新文件主要有以下4个操作:
1.存储属性
内核先找到一个空闲的i节点(这里是263466)。内核把文件信息记录到其中。
2.存储数据
该文件需要存储在三个磁盘块,内核找到了三个空闲块:300.500,800。将内核缓冲区的第一块数据复制到300,下一块复制到500,以此类推。
3.记录分配情况
文件内容按顺序300,500.800存放。内核在inode上的磁盘分布区记录了上述块列表。
4.添加文件名到目录
3.3.文件于目录
目录也是文件,但是磁盘上没有目录的概念,只有文件属性+文件内容的概念
目录的属性不用多说,内容保存的是:文件名和Inode号的映射关系
3.4.路径的解析和缓存
路径解析:
假设此时要访问下面这个文件,都要从根目录开始,依次打开每一个目录,根据目录名,依次访问每个目录下指定的目录,直到访问到test.c。这个过程叫做Linux路径解析

路径缓存:
访问任何⽂件,如果都要从/⽬录开始进⾏路径解析,那么这种速度还是太慢了,所以Linux会缓存路径结构
Linux中,在内核中维护树状路径结构的内核结构体叫做: struct dentry

注意:
1.每个⽂件其实都要有对应的dentry结构,包括普通⽂件。这样所有被打开的⽂件,就可以在内存中 形成整个树形结构
2.更重要的是,这个树形结构,整体构成了Linux的路径缓存结构,打开访问任何⽂件,都在先在这 棵树下根据路径进⾏查找,找到就返回属性inode和内容,没找到就从磁盘加载路径,添加dentry 结构,缓存新路径

3.5.挂载分区
挂架分区的主要流程:
1.设备打开与初始化
- 内核通过块设备层打开分区设备
- 分配 ext2 文件系统专用的超级块结构(ext2_sb_info)
2.读取并验证超级块
- 从设备 0 号块组的超级块位置(通常是分区的 1024 字节处)读取超级块数据
- 验证超级块魔数(0xEF53)以确认是 ext2 文件系统
- 检查文件系统状态(是否干净卸载、是否需要修复)
超级块关键字段验证:

3.块组描述符表读取
- 读取块组描述符表(位于超级块之后)
- 每个块组描述符记录对应块组的位图和 inode 表位置
- 验证块组描述符的一致性
4.内存数据结构建立
- 在内存中构建 ext2 文件系统的元数据结构:
- 超级块缓存(struct ext2_sb_info)
- inode 缓存(struct ext2_inode_info)
- 块位图和 inode 位图缓存
- 建立 VFS 层与 ext2 特定结构的映射关系
5.根 inode 获取
- 读取根目录的 inode(通常是 2 号 inode)
- 验证根 inode 的类型(必须是目录类型)
- 将根 inode 与挂载点目录关联
6.挂载完成与错误处理
- 向 VFS 注册 ext2 文件系统的操作函数集
- 返回挂载句柄,完成文件系统树的关联
- 若过程中发现错误(如超级块损坏),返回错误码并终止挂载
4.软硬连接
1.硬连接:
我们看到,真正找到磁盘上⽂件的并不是⽂件名,⽽是inode。其实在linux中可以让多个⽂件名对应 同⼀个inode。


2.软连接:
硬链接是通过inode引⽤另外⼀个⽂件,软链接是通过名字引⽤另外⼀个⽂件,但实际上,新的⽂件和 被引⽤的⽂件的inode不同,应⽤常⻅上可以想象成⼀个快捷⽅式。

