
于此止?:个人主页
本文选自专栏: 《Linux篇》
❄️个人专栏传送门: 《QT百日筑基篇》 《算法篇》
《C++与STL剖析篇》 《数据结构篇》 《Python基础篇》《嵌入式砺剑录》
⭐️纵有狂风拔地起,我亦乘风破万里⭐️

文件系统的存储——理解硬件
前言:本片文章主要拆解我们对应的硬件知识,我们下篇是文件系统这篇文章有助于我们理解我们的下篇文章,所以我们就来看看我们磁盘的底层构造吧。
目录
文件系统的存储——理解硬件
一、从宏观角度看待我们的硬件域
1.磁盘、服务器、机柜、机房
磁盘
服务器
机柜
机房
二、磁盘的结构(深度拆解磁盘)
磁盘的存储结构(微观,俯视图)
主视图
扇区
理解柱面和盘面
CHS寻址
三、从软件抽象我们的磁盘
1、理解过程
2、LBA地址
3、真实的过程
四、CHS和LBA地址的转化
CHS转化LBA:
LBA 转成 CHS:
一、从宏观角度看待我们的硬件域
我们的文件分为下面的两种
1.打开的文件——储存在内存中
2.没有打开的文件——储存在磁盘中
1.磁盘、服务器、机柜、机房
像我们现在的笔记本电脑大多装的都是我们对应的固态硬盘。但是向我们的台式机还是使用我们对应的磁盘的。所以我们来详细的看一下我们的磁盘吧。
磁盘以下的特点。
- 机械磁盘是计算机中唯一的一个机械设备
- 磁盘 — 外设
- 慢
- 容量大,价格便宜
我们看一下我们磁盘的样子吧
磁盘
这是我们带包装的磁盘。一般是企业级的磁盘,当然企业级的磁盘价格会更贵一点,但是效率会更高一点。

我们将我们的磁盘的包装进行拆开,能看到我们内部的磁盘的样子。

我们磁盘主要是进行存储的,也就是IO

服务器
我们可以将我们的一个个磁盘放入我们对应的服务器当中。这就是我们对应的服务器,服务器一般没有什么外设,一般的外设只有网卡。

我们可以将前面的一个个柜子抽出来,将我们对应的磁盘放进去。

机柜
我们在上面的光盘操作完之后我们将一个个服务器放入我们的机柜中

我们的机柜的背面有各种各样的连线

机房
我们将我们的一个个机柜放入我们的房间中形成对应的机房.

当然除啦这种的磁盘外,我相信大家还认识我们的光盘,光盘和磁盘的区别是我们的磁盘能进行我们的读写,但是我们的光盘是只读的。

二、磁盘的结构(深度拆解磁盘)
这就是我们对应的一个磁盘。

磁盘的存储结构(微观,俯视图)
我们的磁盘在我们的俯视图是一个个同心圆,当然我们这一个个圆弧就是我们一个个磁道。
右侧是我们对应的一个个磁道的简化图我们这一个圆弧有我们一个个扇区来进行构成。我们这里的扇区一般是512Byte。当然这只是我们俯视图所看到的,我们不一定一个磁盘只有一个这样的盘片。

主视图
我们有很多很多的盘片,这里我们有几个盘片数也是代表我们有几个对应的磁头数。我们这几个磁头都有一个有趣的特点,这个特点是他们在运行的时候我们所有的盘面也都进行运行,运行后他指向的是我们对应的位置在一个高度中(我们称之为共进退)


扇区
我们的磁盘在运行的过程中要将我们对应的一个个内容写到我们对应的扇区中,这时候我们就要运动我们对应的磁头,找到我们对应的扇区进行我们对应的写入。
我们的磁头在我们的转动臂下共进退。
我们的扇区呈现我们的扇子状因此我们将其命名为扇区。



理解柱面和盘面
我们查看我们的立体结构

CHS寻址
我们在执行我们写入的时候,要怎么进行写入呢?
1.首先在我们那么多的柱面(cylinder)(上面图中的盘面)找寻一个我们对应的柱面进行写入。
2.找到我们的柱面后我们让我们的该柱面的磁头(head)去定位我们写的地方。
3.我们将我们对应的磁头指向我们要进行写入的扇区(sector)。
所有我们想定位一个空间进行写入我们的顺序是cylinder head sector我们称之为CHS寻址法。
当然这里的CHS是我们的简称,我们CHS是我们硬件上的称呼我们的软件,不称之为CHS。
我们的文件=内容+属性。都是我们的数据,无非就是占几个扇区的问题,既然我们能定位一个扇区那我们当然也能定位多个扇区了。
我们查询我们Linux机器中的磁盘数据
命令fdisk
fdisk -l

我们能利用的一些信息。
loop 叫做回环设备(loop‑device),是 Linux 内核提供的虚拟块设备。
普通磁盘 /dev/vda 对应真实硬盘; loop0‑loop7 并不对应真实硬件磁盘,它把一个普通文件,虚拟成一块磁盘设备。 你可以把一个 .iso、.img 文件,“伪装” 成磁盘,然后对它做分区、格式化、挂载。
| /dev/loop0 | 63.78 | 66,875,392 | 130,616 | 512B | 回环设备 |
| /dev/loop1 | 63.78 | 66,879,488 | 130,624 | 512B | 回环设备 |
| /dev/loop2 | 73.98 | 77,574,144 | 151,512 | 512B | 回环设备 |
| /dev/loop3 | 50.10 | 52,535,296 | 102,608 | 512B | 回环设备 |
| /dev/loop4 | 115.13 | 120,717,312 | 235,776 | 512B | 回环设备 |
| /dev/loop5 | 73.99 | 77,586,432 | 151,536 | 512B | 回环设备 |
| /dev/loop6 | 50.10 | 52,535,296 | 102,608 | 512B | 回环设备 |
| /dev/loop7 | 115.26 | 120,856,576 | 236,048 | 512B | 回环设备 |
| /dev/vda | 40,960 (40GiB) | 42,949,672,960 | 83,886,080 | 512B | 虚拟磁盘 (系统盘) |
| /dev/vda1 | 2048 | 4095 | 2,048 | 1 MiB | BIOS boot | GPT 分区表下的 BIOS 引导分区,存放 GRUB 引导代码 |
| /dev/vda2 | 4096 | 83,886,046 | 83,881,951 | 40 GiB | Linux filesystem | 主分区,挂载根目录 /,存放系统和用户数据 |
关键字段解读
| Units | 扇区单位换算 | 1 扇区 = 512 字节 |
| Sector size (logical/physical) | 逻辑 / 物理扇区大小 | 均为 512B,传统磁盘标准 |
| I/O size (minimum/optimal) | 最小 / 最优 IO 大小 | 均为 512B,单次读写最小单位 |
| Disklabel type | 分区表类型 | gpt,新一代分区表,支持大于 2TB 磁盘 |
| Disk identifier | 磁盘唯一标识符 | GPT 磁盘的 UUID,用于系统唯一识别磁盘 |
- 扇区是从磁盘读出和写入信息的最小单位,通常大小为 512 字节。
- 磁头(head)数:每个盘片一般有上下两面,分别对应 1 个磁头,共 2 个磁头
- 磁道(track)数:磁道是从盘片外圈往内圈编号 0 磁道,1 磁道…,靠近主轴的同心圆用于停靠磁头,不存储数据
- 柱面(cylinder)数:磁道构成柱面,数量上等同于磁道个数
- 扇区(sector)数:每个磁道都被切分成很多扇形区域,每道的扇区数量相同
- 圆盘(platter)数:就是盘片的数量
- 磁盘容量 = 磁头数 × 磁道 (柱面) 数 × 每道扇区数 × 每扇区字节数
- 细节:传动臂上的磁头是共进退的 (这点比较重要,后面会说明)
对早期的磁盘非常有效,知道用哪个磁头,读取哪个柱面上的第几扇区就可以读到数据了。
但是 CHS 模式支持的硬盘容量有限,因为系统用 8bit 来存储磁头地址,用 10bit 来存储柱面地址,用 6bit 来存储扇区地址,而一个扇区共有 512Byte,这样使用 CHS 寻址一块硬盘最大容量
为256 * 1024 * 63 * 512B = 8064 MB(1MB = 1048576B)(若按1MB=1000000B来算就是 8.4GB)
三、从软件抽象我们的磁盘
1、理解过程
我们相信我们一定见过下面的这个东西, 这是我们的磁带,我们可以将里面的绳子从口中抽离出来,我们里面装的是一个个同心圆,我们拉出来就是一个个长长的绳子。

将我们的磁盘拉长就变成了下面的图片。变成了一个对应的线性结构,我们在Linux下一切皆文件,我们这样就将我们的磁盘抽象成了一个线性的结构。

这里我们抽象成了一个线性的结构,那我们应该怎么进行访问这些数据呢? ok这里我们看到他的样子形似数组,我们数组是怎么进行访问的?采用数组下表的方式进行访问的。所以这里我们是不是也能使用数组下表进行访问呢?
答案:是的,所以以后我们对于扇区的访问就是我们对于该数组下表的访问。

2、LBA地址
这样我们每一个扇区就有了一个线性的地址(起始这里就是我们的数组下标),这种地址我们称之为LBA地址。
3、真实的过程
一个细节:转动臂的磁头是共进退的

柱面是一个逻辑上的概念,其实就是每一面上,相同半径的磁道逻辑上构成的柱面。
所以,磁盘物理上分了很多面,但是在我看来逻辑上磁盘整体是由柱面卷起来的。

磁道:

我们一个柱面的一个磁道我们将其展开就得到下面的一张图片

我们看到了这个磁道展开是一个一维数组。
那我们将整个柱面进行展开呢?


我们看到这是一个二维数组
那我们将我们的磁盘进行展开呢??
我们磁盘有很多的柱面,我们的磁盘展开会形成多张二维数组,那么我们将储存二维数组的数组称之为三维数组。

在我们软件层,什么一维数组,二维数组,三维数组,在我看来都是一维数组。

所以,每⼀个扇区都有⼀个下标,我们叫做 LBA(Logical Block Address) 地址,其实就是线性 地址。所以怎么计算得到这个LBA地址呢?

LBA,1000,CHS 必须要! LBA 地址转成 CHS 地址,CHS 如何转换成为 LBA 地址。
OS 只需要使用 LBA 就可以了!! LBA 地址转成 CHS 地址,CHS 如何转换成为 LBA 地址。谁做啊??磁盘自己来做!固件 (硬件电路,伺服系统)
四、CHS和LBA地址的转化
CHS转化LBA:
- 磁头数 * 每磁道扇区数 = 单个柱面的扇区总数
解析:我们在一个柱面上包含一个个盘面上的一圈磁道,我们的柱面数==我们的磁头数,所以我们的磁头数x我们的每磁道的扇区数就是我们单个柱面的扇区总数。
- LBA = 柱面号 C*单个柱面的扇区总数 + 磁头号 H每磁道扇区数 + 扇区号 S – 1
- 即:LBA = 柱面号 C*(磁头数每磁道扇区数) + 磁头号 H*每磁道扇区数 + 扇区号 S – 1
解析:我们是在哪一个柱面,我们是在C号柱面,我们要计算某一位置要将前面的所有的扇区都计算出来我们的扇区是从0开始进行编号的,cx我们一个柱面的扇区总数+ 我们某一磁道的前面的磁道扇区总数+我们特定的一个扇区。我们的数组从0开始所以要-1.
- 扇区号通常是从 1 开始的,而在 LBA 中,地址是从 0 开始的
- 柱面和磁道都是从 0 开始编号的
- 总柱面,磁道个数,扇区总数等信息,在磁盘内部会自动维护,上层开机的时候,会获取到这些参数。
LBA 转成 CHS:
- 柱面号 C = LBA // (磁头数 * 每磁道扇区数)【就是单个柱面的扇区总数】
解析:我们的LBA是我们具体的一个数组下表,我们的磁头数x每磁道扇区的总数=单个柱面的总数,我们想看这个数组下表对应的是哪一个柱面,所以我们用我们的数组下表除以一个面的扇区总数取整就能得到我们是在哪个柱面上。
- 磁头号 H = (LBA % (磁头数 * 每磁道扇区数)) // 每磁道扇区数、
解析:我们想知道我们对应的数据是哪个磁道的,我们将我们的LBA地址和我们单个主面的扇区总数进行取模,我们的余数就是我们的磁头号。
我们的除是柱面号,取模是我们的磁头号。
- 扇区号 S = (LBA % 每磁道扇区数) + 1
解析:我们的LBA地址和磁道扇区数取模,就能得到我们数组的下表,因为数组下标是从0开始的所以我们要+1是对应的扇区位置。
- "//": 表示除取整
所以:从此以后,在磁盘使用者看来,根本就不关心 CHS 地址,而是直接使用 LBA 地址,磁盘内部自己转换。所以:
从现在开始,磁盘就是一个元素为扇区 的一维数组,数组的下标就是每一个扇区的 LBA 地址。OS 使用磁盘,就可以用一个数字访问磁盘扇区了。



