【Linux】Ext 文件系统:从机械磁盘到 CHS/LBA,搞懂扇区、块与分区

🔥个人主页:爱和冰阔乐
📚专栏传送门:《数据结构与算法》 、C++
🐶学习方向:C++方向学习爱好者
⭐人生格言:得知坦然 ,失之淡然

🏠博主简介
文章目录
前言
前面学习基础 I/O 时,我们主要研究的是“已经被打开的文件”:进程执行 open/fopen 后,内核怎样创建 struct file,再通过文件描述符 fd 找到这个打开文件对象。
但这篇开始,视角要往前挪一步:
文件还没有被打开时,它到底放在磁盘的哪里?操作系统又是怎么把成千上万个文件组织起来的?
一个文件可以先粗略看成:
核心认知: 文件 = 内容 + 属性
已经被打开的文件在内存里研究,未被打开的文件主要在磁盘上研究。用户想访问文件,必须能通过路径找到它;而“谁来组织文件、谁来查找文件、谁来把路径变成磁盘上的数据位置”,这就是文件系统要解决的问题。
这一篇先不急着讲 inode 和 Ext 的块组结构,而是先把磁盘本身讲清楚:磁盘为什么慢、扇区是什么、CHS 怎么定位、LBA 为什么能把磁盘抽象成一个一维数组,最后再引出文件系统为什么要使用“块”和“分区”。
一、先把文件分成两种状态
从宏观上看,文件可以分成两类:
| 文件状态 | 主要研究位置 | 之前/本文关注点 |
|---|---|---|
| 已经被打开的文件 | 内存 | 基础 I/O:fd、struct file、重定向、缓冲区 |
| 没有被打开的文件 | 磁盘 | 本文:磁盘结构、文件系统、inode、路径解析 |
之前基础 I/O 讨论的是:文件被进程打开后,进程如何通过 fd 找到内核中的打开文件对象。
而现在要讨论的是:文件还躺在磁盘上时,操作系统如何管理它们。
磁盘上的文件数量可能非常多,如果没有一套组织方式,用户根本找不到自己要的文件。我们平时看到的目录树、路径、分区、挂载,本质上都是文件系统为了管理磁盘文件做出来的抽象。
二、先理解硬件:磁盘为什么慢但容量大?
机械磁盘是计算机里比较典型的机械设备,它属于外设,特点很明显:
- 速度慢,远慢于 CPU 和内存;
- 容量大,价格便宜;
- 适合长期保存数据;
- 企业场景里常常会根据冷热数据选择不同磁盘。
比如很久以前的聊天记录、朋友圈、备份数据,通常不会放在非常昂贵的高速存储上,而是会放到容量大、成本低的存储设备里。最近访问的数据放在更快的位置,历史数据放在更便宜的位置,这就是常见的冷热数据分离。

磁盘拆开后,能看到几个重要结构:
- 盘片:真正存储数据的地方;
- 主轴/马达:带动盘片高速旋转;
- 磁头:负责读写数据;
- 磁头臂/传动臂:带动磁头在半径方向上移动。

服务器一般不需要像个人电脑一样直接接鼠标、键盘、显示器。程序员通常通过网络登录服务器,服务器更多依赖网卡对外提供服务。很多服务器放在一起,就组成了机柜;很多机柜放在一起,就是机房。
三、磁盘如何表示 0 和 1?
磁盘盘面看起来很光滑,但可以把它想象成由很多微小磁性颗粒组成。每个颗粒可以有不同的磁化方向,比如我们可以粗略规定:
可以这样理解:
- 某个磁化方向表示
1- 另一个磁化方向表示
0
所以,向磁盘写入数据,本质上就是改变这些磁性颗粒的状态。

不同硬件表示二进制的方式不同:
| 设备 | 表示 0/1 的方式 |
|---|---|
| 磁盘 | 磁性颗粒方向变化 |
| 内存 | 电容充放电、电平高低 |
| 网络 | 电信号/光信号/波形变化 |
所以计算机底层统一认识的是二进制,但不同设备承载二进制的方法不一样。
四、磁盘的物理结构:盘片、磁道、扇区、柱面
先看磁盘的整体结构。

4.1 磁道和扇区
磁盘盘面不是一个整体,逻辑上会被划分成一圈一圈的同心圆,每一个同心圆叫做磁道。
磁道也不是一个连续整体,它还会被切成一小段一小段的扇形区域,这些小区域叫做扇区。


扇区是磁盘读写数据的基本单位。本文沿用传统模型,把一个扇区按 512 字节理解。现代硬盘还可能使用 4KB 原生扇区(4Kn),或者对上层兼容成 512 字节逻辑扇区(512e),但不影响后面理解 CHS、LBA 和文件系统块的主线。
这里要注意:
重点: 磁盘不是按单个字节读写,而是按扇区这样的块状单位读写。
如果外设每次只处理一个字节,效率会非常低,所以磁盘天然属于块设备。
4.2 多个盘面和多个磁头
真实磁盘通常不止一个盘面。一个盘片有上下两个面,每个面都可能对应一个磁头。

盘片在旋转,磁头臂带着磁头在半径方向上移动。多个磁头通常是共进退的,也就是说,它们会一起移动到相同半径的位置。

当多个盘面上相同半径位置的磁道组合在一起时,就形成了柱面。
可以这样理解:
- **一个盘面上的某个同心圆:**磁道
- **多个盘面上相同半径的磁道组合:**柱面
这个“柱面”是理解 CHS 寻址非常重要的概念。
五、如果要读写一个扇区,磁盘要做什么?
假设现在要把 512 字节写入某个扇区,磁盘大致要经历这几个动作:
- 磁头臂移动,让磁头到达目标柱面;
- 盘片继续旋转,等待目标扇区转到磁头下面;
- 根据目标盘面选择对应磁头;
- 磁头完成读或写。
这也解释了机械磁盘为什么慢:
它不是纯电子设备,还涉及机械移动和等待旋转。
磁头移动到目标磁道的时间叫寻道时间,等待目标扇区转到磁头下方的时间叫旋转延迟。机械动作越多,访问就越慢。
六、CHS 寻址:用柱面、磁头、扇区定位数据
在真实物理磁盘中,可以用三个参数定位一个扇区:
| 参数 | 英文 | 含义 |
|---|---|---|
| C | Cylinder | 柱面 |
| H | Head | 磁头 |
| S | Sector | 扇区 |
这就是 CHS 寻址。
定位过程可以理解成:
- 先确定访问哪个柱面;
- 再确定柱面中的哪个磁头/盘面;
- 最后确定该磁道上的第几个扇区。


磁盘容量也可以用这些参数算出来:
磁盘容量计算公式:
磁盘容量 = 磁头数 × 磁道(柱面)数 × 每道扇区数 × 每扇区字节数
常见概念整理如下:
| 名称 | 含义 |
|---|---|
| 扇区 sector | 磁盘读写的最小物理单位,通常 512 字节 |
| 磁道 track | 盘面上一圈同心圆 |
| 柱面 cylinder | 多个盘面上相同半径的磁道组合 |
| 磁头 head | 每个盘面通常对应一个读写磁头 |
| 盘片 platter | 磁盘中的圆形存储介质 |
早期 CHS 寻址比较直接,但它有容量限制。传统 CHS 中常见参数位数是:磁头地址 8 bit、柱面地址 10 bit、扇区地址 6 bit,一个扇区 512 字节。按这种方式计算,最大容量大约是:
传统 CHS 模型下的理论容量:
256 × 1024 × 63 × 512B ≈ 8064MB
如果按 1MB = 1000000B 来算,大约是 8.4GB。
这个容量对早期磁盘够用,但对现代磁盘显然不够,所以后来更常用的是 LBA。
关于现代磁盘的说明: CHS 更适合用来理解机械磁盘的盘片、磁头、柱面和扇区。现代操作系统主要使用 LBA,硬盘或 SSD 控制器再把逻辑地址映射到真实存储位置。这个映射不一定还是简单的“LBA 直接换算成传统 CHS”,尤其 SSD 根本没有磁头和柱面。
七、磁盘的逻辑结构:把磁盘看成一个一维数组
CHS 是从物理结构角度理解磁盘,但操作系统并不希望天天关心柱面、磁头、扇区这些物理细节。
可以换个想法:磁带卷起来是圆的,但如果把它拉直,就是一条线性结构。

磁盘也是类似的。虽然物理上是一圈圈磁道,但逻辑上可以把所有扇区排成一条线。

这样每一个扇区就有了一个线性编号,这个编号叫:
LBA,Logical Block Address,逻辑块地址。


从操作系统角度看,磁盘就像一个很大的数组:
磁盘可以按顺序抽象为:
sector[0]sector[1]sector[2]...
数组下标就是 LBA。
这样做最大的好处是:
LBA 的价值: 操作系统只需要使用一个数字,就可以描述一个扇区位置。
至于这个 LBA 最后如何转换成真实磁盘上的柱面、磁头、扇区,交给磁盘控制器和固件去做。
八、真实视角:磁道、柱面和整盘都可以被线性化
这里再从真实结构上顺一遍。
一个细节:磁头臂上的磁头是共进退的。

柱面不是单个盘面上的一圈,而是多个盘面上相同半径的磁道组合。

某一个盘面上的某个磁道展开后,可以看成一维数组。

整个柱面展开后,可以看成二维结构。


整个磁盘可以看成多个二维结构组合起来,类似三维数组。

但无论是二维还是三维,在 C/C++ 中最终都可以按连续地址线性化管理。

所以从文件系统使用者角度看:
磁盘最终就是一个元素为扇区的一维数组,数组下标就是 LBA。
九、CHS 与 LBA 的转换公式
虽然操作系统一般直接使用 LBA,但理解 CHS 和 LBA 的转换有助于把磁盘结构彻底串起来。
假设:
每个柱面的扇区总数 = 磁头数 × 每磁道扇区数
9.1 CHS 转 LBA
公式:
CHS 转 LBA 公式:
LBA = C ×(磁头数 × 每磁道扇区数)+ H × 每磁道扇区数 + S - 1
其中:
C是柱面号;H是磁头号;S是扇区号;- 扇区号通常从 1 开始;
- LBA 从 0 开始,所以最后要
-1。
9.1.1 CHS 转 LBA 计算示例
假设一块教学模型磁盘有 4 个磁头,每条磁道有 16 个扇区,现在要计算:
| 参数 | 数值 |
|---|---|
柱面号 C |
2 |
磁头号 H |
1 |
扇区号 S |
5 |
代入公式:
代入计算:
LBA = 2 × (4 × 16) + 1 × 16 + 5 - 1= 128 + 16 + 4= 148
所以 (C=2, H=1, S=5) 对应的 LBA 是 148。
9.2 LBA 转 CHS
公式:
LBA 转 CHS 公式:
C = LBA //(磁头数 × 每磁道扇区数)H =(LBA %(磁头数 × 每磁道扇区数))// 每磁道扇区数S =(LBA % 每磁道扇区数)+ 1
这里 // 表示整除。
9.2.1 用 LBA=148 反推 CHS
仍然使用 4 个磁头、每磁道 16 个扇区:
反推过程:
C = 148 // (4 × 16) = 2H = (148 % 64) // 16 = 1S = (148 % 16) + 1 = 5
最终又得到 (C=2, H=1, S=5),与前面的结果对应。

到这里可以得到一个重要结论:
对现代操作系统来说,主要使用的是 LBA。设备控制器和固件负责把逻辑地址映射到实际存储位置;CHS 在本文中主要承担物理结构教学模型的作用。
十、引入文件系统:为什么要有块 block?
从这里开始,就进入软件部分了。
磁盘的物理最小读写单位是扇区,常见大小是 512 字节。但操作系统访问文件时,一般不会一个扇区一个扇区地读,这样效率太低。
所以文件系统会引入“块”这个概念。
核心概念: block 是文件系统层面对磁盘数据管理的基本单位。
常见块大小是 4KB,也就是连续 8 个 512 字节扇区组成一个块。

这样文件系统管理文件内容,就从管理扇区变成管理块。
如果知道某个扇区的 LBA,那么:
已知 LBA:
块号 = LBA / 8
如果知道块号,也能反推块内扇区:
已知块号:
LBA = 块号 × 8 + n
其中 n 表示块内第几个扇区,按本文 4KB 块模型取值范围是 0~7。

为什么不直接让 OS 以 512 字节扇区为单位管理?主要有两个原因:
- 提高效率:一次读写 4KB 比频繁读写 512B 更划算;
- 解耦硬件:如果磁盘底层技术变化,文件系统不至于完全被物理扇区绑死。
10.1 块设备和字符设备有什么区别?
磁盘属于块设备。块设备通常按固定大小的数据块读写,并且支持随机访问,也就是可以通过地址直接定位到某一块数据。
键盘、串口这类设备更接近字符设备,数据通常按顺序形成字符流,上层一般不能像访问磁盘那样随意跳到“第几个字符”读取。
| 对比项 | 块设备 | 字符设备 |
|---|---|---|
| 常见设备 | 磁盘、SSD、U 盘 | 键盘、串口、部分终端设备 |
| 数据组织 | 按块组织 | 按字节流/字符流组织 |
| 随机访问 | 通常支持 | 通常不支持任意 seek |
| 典型特点 | 容量大,适合文件系统 | 连续输入输出 |
文件系统通常建立在块设备上,因为它需要根据块号快速定位文件内容和管理信息。
十一、引入分区:文件系统的载体是分区
一块磁盘通常可以分成多个分区。Windows 下常见的 C 盘、D 盘、E 盘,本质上就是不同分区。
Linux 下虽然“一切皆文件”,但是底层仍然有磁盘分区。文件系统通常建立在分区之上:
- 磁盘
- 分区
- 文件系统
- 文件和目录
- 文件系统
- 分区
也就是说:
核心结论: 文件系统的载体是分区。
一个磁盘上可以有多个分区,因此也就可以有多套文件系统。
早期磁盘分区时常用柱面作为边界,因为柱面是磁头共进退后的一个自然逻辑单位。可以把磁盘上的柱面平铺开,再划分不同分区。
这里用柱面划分分区,是为了配合前面的 CHS 模型理解。现代分区工具通常直接按照 LBA 起始位置和结束位置划分分区,不再要求分区边界严格对齐传统物理柱面。



不过分区本身仍然很大,直接管理起来不方便,所以 Ext 文件系统会继续把分区划分成多个块组,也就是后面要讲的 Block Group。
十二、上篇总结
这篇主要解决的是:文件系统正式登场前,磁盘到底是什么样的。
几个核心结论要记住:
- 未打开的文件主要存放在磁盘上,打开后的文件才进入内核内存结构中管理。
- 磁盘属于块设备,机械磁盘速度慢但容量大、价格便宜。
- 扇区是磁盘读写的基本物理单位,传统大小一般是 512 字节。
- 磁道是一圈同心圆,扇区是磁道上的一小段,柱面是多个盘面上相同半径磁道的组合。
- CHS 通过柱面、磁头、扇区定位数据,但容量表达和使用都不够方便。
- LBA 把磁盘抽象成一个一维数组,操作系统只需要使用线性下标访问扇区。
- 文件系统不会直接以扇区为主要管理单位,而是引入 block,常见大小是 4KB。
- 文件系统建立在分区上,分区继续划分成块组,后面 Ext 的 inode、位图、数据块都会围绕块组展开。
下一篇就继续往下看:Ext 文件系统如何通过 Super Block、GDT、Block Bitmap、Inode Bitmap、Inode Table 和 Data Blocks 管理文件。
资源分享
【Linux】文件描述符背后的底层逻辑:重定向、VFS 与用户态缓冲区
【Linux基础IO】printf 为什么会写进文件?一文搞懂重定向和 dup2 底层原理
【Linux】基础 I/O 详解:从 fopen 到 open,终于搞懂 fd 为什么从 3 开始
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)