磁盘与定位方法
1、磁盘的结构
磁盘的结构组成:
- 存储光盘
- 磁头(读/写头)------header
- 主轴
- 传动臂
- ...

我们不关心其它结构,只关注盘片。
磁盘往往有多个盘片。一个盘片的正反两面都可以存储数据。
盘片上有许多"磁道":

磁道就是如图所示的一个个"同心圆"。
磁道并不是连续的。磁道间隙与间隙中间的区域,称作扇区。
实际上,磁道是有宽度的,那么将盘片上的扇区放大,就像一把扇子:

2、扇区的定位方法
扇区(sector),是磁盘存储数据的基本单位,大小一般是512字节 。扇区是块设备。
既然扇区是存储的基本单位,那么我们如何定位一个扇区呢?
首先,我们要认识到:
- 磁头可以转动,以定位磁道;
- 磁盘可以由主轴带动而旋转,以定位扇区。
所以,根据上面所学,我们就可以提炼出一个定位扇区的大概思路:
- 首先确定扇区所在的盘面,也是磁头的位置;
- 再确定磁道的位置;
- 最后再磁道上确定扇区的位置。
但是,真实的扇区定位方法,和上面的思路不太一样。
2.1、CHS定址法
磁盘有一个细节:磁盘的所有磁头都是一起运动的,即"共进退"。
当其中一个磁头,定位到某一个位置的磁道时,我们将此时所有磁头的所有磁道,统称为柱面(cylinder)。

至此,我们给出扇区定位的真实思路:
- 首先定位柱面(cylinder)
- 其次定位磁头(header)
- 最后定位扇区(sector)
这就是定位扇区的CHS定址法。
2.2、LBA定址法
我们不期望计算机直接使用CHS定址法定位扇区。直接采用CHS,计算机操作系统就与磁盘设备"强耦合";未来磁盘的存储结构如果发生改变,那么操作系统的底层代码就得跟着改,维护成本就会非常高。
换个思路。
把磁道"剪"开,我们就能得到一串"连续"的扇区,就能用一维数组存储起来:

把柱面"剪"开,我们就展开了这个柱面上的所有磁道,最后形成的扇区分布,很像二维数组:

而一个磁盘上有若干柱面,相当于有若干二维数组:

整个磁盘的扇区分布情况,不就可以用一个"三维数组"来描述吗?
而C语言视角下,n维数组在底层存储逻辑上,都是一维数组。我们就把扇区定位的物理世界的问题,转化为了计算机视角下管理数组的问题。
像这样用数组来定位扇区的方法,叫做LBA定址法(Logical Block Addressing)。
CHS定址法转化为LBA定址法:
c
// 前面有多少个柱面
// 最后一个不完整柱面,有多少个磁道
// 最后一个不完整磁道,有多少个扇区
单个柱面的总扇区数 = 磁头数 * 单个磁道的扇区数
LBA号 = 柱面号 * 单个柱面的总扇区数 + 磁头号 * 单个磁道的扇区数 + (扇区号 - 1)
LBA定址法转化为CHS定址法:
| 项目 | 计算方法 |
|---|---|
| 柱面号C | LBA号 // 单个柱面的总扇区数 |
| 磁头号H | LBA号 % 单个柱面的总扇区数 // 单个磁道的扇区数 |
| 扇区号S | (LBA号 % 单个磁道的扇区数) - 1 |
小贴士
扇区号从"1"开始,而柱面号与磁头号从"0"开始。LBA号也是从"0"开始。
每一个磁道的扇区总数,是相同的。
磁头数、单个磁道的扇区数等信息,磁盘内部会自动维护。
//是"取整除号",即对结果舍去小数部分,而不是"四舍五入"。
3、两个问题
对磁盘扇区分布的数学建模过程,是谁做的?
操作系统。
有必要真的开辟一个一维数组,存储扇区的信息吗?
答案是不需要。我们完全可以定义一个变量存储LBA号,未来只需利用"LBA定址法转化为CHS定址法"的规则,解析出三个参数,就能定位到某一个指定的扇区位置。而不是浪费大量空间存储一个一维数组,存放扇区信息。