计算机那些事(1)——硬盘
硬盘接口
常见的硬盘接口有:IDE 、SATA、SAS、USB、SCSI,其中 SATA 是目前的主流接口,IDE 则几乎不再使用。
设备文件
计算机的各种硬件设备在 Linux
中都有对应的设备文件,甚至不同的接口也对应着不同的设备文件,从而使用不同的驱动程序来操作硬件设备。对于硬盘,实体设备的文件名一般是
/dev/sd[a-]
;虚拟设备(虚拟机中的硬盘)的文件名一般是
/dev/vd[a-]
。
有时,系统中会有
/dev/sda
、/dev/sdb
...等设备文件,它们之间又是什么关系呢?实际上,/dev/sd[a-]
是 SATA/USB/SAS 等硬盘接口对应的设备文件,这类接口都使用 SCSI
模块作为驱动程序。a
、b
、c
...则是按系统检测到的顺序来排列的,与实际插槽顺序无关。
我们知道硬盘是可以被分区成多个分区(partition),如在 Windows
中可以将一块硬盘分区成 C:
、D:
、E:
盘。那么,不同的分区是否也有对应的设备文件呢?
硬盘结构
提到分区,我们需要先了解一下硬盘的结构。不同寻址方式的硬盘,其结构也不同。硬盘的寻址方式主要有两种:
- CHS 寻址方式:由柱面数(Cylinders)、磁头数(Headers)、扇区数(Sectors)组成 3D 参数,简称 CHS 寻址方式,硬盘容量相对较小。如传统的机械硬盘(Hard Disk Drive,HDD)。
- LBA 寻址方式:线性寻址,以逻辑区块为单位进行寻址,全称为 Logic Block Address(即扇区的逻辑块地址),硬盘容量相对较大。如固态硬盘(Solid State Disk,SSD)
CHS 寻址方式
如下图所为 CHS 寻址方式的硬盘结构,硬盘主要由盘片、机械手臂、磁头、主轴马达组成。盘片是数据存储的媒介,圆形,通过机械手臂读写数据,盘片需要转动才能够让机械手臂读写。因此,可以将盘片同心圆分割成一个个的小区块,这些区块组成一个圆形,可以让机械手臂的磁头进行读写。这个小区块就是硬盘的最小物理存储单位,即 扇区(sector)。位于同一个同心圆上的扇区组成的圆环,即 磁道(track)。硬盘中可能包含多个盘片,在所有盘片上的同一个磁道组成了所谓的 柱面(cylinder),柱面是文件系统的最小单位,也是分区的最小单位。
LBA 寻址方式
LBA 寻址方式的硬盘使用集成电路代替物理旋转磁盘,主要由主控与闪存芯片组成。数据的读写速度远远高于 CHS 寻址方式的硬盘。
硬盘分区
了解了硬盘结构,再来看硬盘分区。
关于硬盘分区,首先思考一个问题:为什么要分区?其实主要有两个原因:
- 数据的安全性。由于每个分区的数据是独立的,使得数据更加安全。
- 访存的高效性。对于 CHS 寻址方式的硬盘,由于分区将数据集中在某个柱面的区段,如第一个分区位于柱面号 1~100。当需要对该分区进行访存时,硬盘只会在 1~100 柱面范围内进行操作,从而提升了数据的访存性能。
既然硬盘能被分区,那么其分区信息是如何保存的呢?答案就是分区表。但是对于不同寻址方式的硬盘,其分区表的格式也不同,主要有两种:
- MBR 分区表:多用于 CHS 寻址方式的硬盘
- GUID 分区表:多用于 LBA 寻址方式的硬盘
分区表有存储在哪里呢?和绝大多数文件将自身的基本描述信息放在文件的开头类似,分区表作为硬盘的基本信息,同样保存在硬盘最前面的存储区域。
下面分别介绍 MBR 分区表和 GUID 分区表。
MBR 分区表
MBR 分区表保存在硬盘的 第一个扇区,由于第一个扇区主要记录了两个重要信息,也称为 主引导记录区(Master Boot Record,MBR)。这两个信息分别是:
- MBR 分区表:记录整个硬盘的分区信息,容量为 64 Bytes。
- 引导程序(Boot Loader):容量为 446 Bytes。
MBR 分区表
分区表占据了 MBR 64 Bytes 的空间,最多只能记录 4 组分区信息,每组分区信息记录了该分区的 起始与结束的柱面号,这 4 组分区信息称为 主要分区(primary partition) 或 延伸分区(extended partition)。
假设上述硬盘的设备文件名为 /dev/sda
,则这四个分区在
Linux
中的设备文件名如下所示,重点在于文件名后面会再接一个数字,这个数字与分区在硬盘中的位置有关。
- P1:
/dev/sda1
- P2:
/dev/sda2
- P3:
/dev/sda3
- P4:
/dev/sda4
由于分区表只有 64 Bytes,最多只能记录 4 组分区信息,那么是否意味着一个硬盘最多只能分割成 4 个分区呢?当然不是!虽然第一个扇区的分区表只能记录 4 组分区信息,但是利用其中的延伸分区信息进一步索引到一个新的分区表,从而记录更多分区信息。如下图所示:
上图所示,硬盘第一个扇区中的四个分区记录仅仅使用了两个,P1 为 主要分区,P2 为 延伸分区。延伸分区的目的是使用额外的扇区来记录分区信息。通过延伸分区所指向的那个区块继续记录分区信息。上图延伸分区索引的分区表继续分出了 5 个分区,这 5 个有延伸分区分出来的分区,称为 逻辑分区(logical partition)。
同理,上图中的分区在 Linux 中的设备文件名如下所示。其中的
/dev/sda3
和 /dev/sda4
则保留给主要分区和延伸分区了,所以逻辑分区的设备文件名从 5 开始。
- P1:
/dev/sda1
- P2:
/dev/sda2
- L1:
/dev/sda5
- L2:
/dev/sda6
- L3:
/dev/sda7
- L4:
/dev/sda8
- L5:
/dev/sda9
MBR 主要分区、延伸分区、逻辑分区的特性 - 主要分区与延伸分区最多可以有 4 个(硬盘的限制) - 延伸分区最多只有一个(操作系统的限制) - 逻辑分区是由延伸分区持续分割出来的分区 - 主要分区和逻辑分区可以被格式化;延伸分区不能被格式化 - 逻辑分区的数量上限由操作系统决定
引导程序(Boot Loader)
Boot loader 是操作系统安装在 MBR 中的一套软件,但 MRB 仅仅提供 446 Bytes 的空间给 boot loader,所以 boot loader 是极其精简的。其主要完成以下任务:
- 提供菜单:用户可以选择不同的开机项目
- 载入核心文件:直接指向可开机的程序区段来启动操作系统
- 转交其他 loader:将开机管理功能转交给其他 loader 负责,主要用于多系统引导。
对于第 3 项,表示计算机系统中可能具有两个以上的 boot loader。事实上,boot loader 不仅可以安装在 MBR 中,还可以安装在每个分区的 开机扇区(boot sector) 中。
假设 MBR 中安装的是可以识别 Windows/Linux 的 boot loader,那么整个流程如下图所示:
由上图可知,MBR 的 boot loader 提供两个菜单选项:选项 1(M1)可以直接载入 Windows 的核心文件进行开机;选项二(M2)可以将开机管理任务交给第二个分区的开机扇区(boot sector)。如果用户选择选项 2,第二分区的开机扇区中的 boot loader 将会载入 Linux 的核心文件进行开机。
关于多系统安装 Linux 安装时,可以将 boot loader 安装在 MBR 或其他分区的开机扇区,Linux 的 boot loader 可以手动设置菜单(即上图的 M1、M2),因此可在 Linux 的 boot loader 中加入 Windows 开机的选项 Windows 安装时,其安装程序会主动覆盖 MBR 以及自己所在分区的开机扇区,并且没有选择的机会,也没有让用户自己选择的菜单的功能 结论:安装多系统时应该先安装 Windows 系统
GUID 分区表
MBR 主要有以下限制:
- 操作系统无法寻址容量超过 2.2TB 的磁盘
- MBR 只有一个区块,若被破坏后,很难对数据进行恢复
- MBR 的引导程序所能使用空间只有 446 Byte,无法容纳更多的代码
GUID 则解决了 MBR 的这些问题。
下图所示为 GUID 的结构示意图。与 MBR 使用扇区作为寻址单位不同,GUID 使用 逻辑区块(Logical Block) 作为寻址单位,即采用 LBA(Logical Block Address)寻址方式。MRB 仅使用第一个扇区 512 Bytes 的空间记录分区信息,GUID 则使用 34 个 LBA 区块(每个区块容量默认为 512 Bytes)记录分区信息。MBR 仅有一个扇区保存分区信息,GUID 除了使用硬盘前 34 个 LBA,还是用最后 33 个 LBA 作为备份。
这里有个疑问:为何前面使用 34 个 LBA,后面使用 33 个 LBA。因为第一个 LBA(LBA0)是用来兼容 MBR 的。
LBA0(MBR 兼容区块)
LBA0 为了兼容 MBR,该区块也分为两个部分,分别用于存储 MBR 分区表和引导程序。因为LBA0 是针对 MBR 兼容模式,因此其分区表中仅仅存放一个特殊标志的分区表信息,用来标识此硬盘为 LBA 寻址方式。
LBA1(GUID 分区表表头)
LBA1 记录了分区表本身的位置和大小,同时记录了备份分区表的位置(即最后 33 个 LBA)。此外还存放了分区表的校验码(CRC32),表示硬盘的完整性。
LBA2~33(分区表表项)
从 LBA2 开始,每个 LBA 都可以记录 4
组分区信息。默认情况下,总共可以有 4 * 32 = 128 组分区信息。因为每个 LBA
有 512 Bytes,所以每组分区信息可使用 128 Bytes 的空间。这 128 Bytes
的分区信息中,分别提供了 64 Bits 用于记录分区对应的
起始/结束 区块号。因此,GUID 能够支持的硬盘的最大容量为
2^64 * 512Byte = 233 TB
参考
- 硬盘寻址方式
- SSD固态硬盘的结构和基本工作原理概述
- 《鸟哥的 Linux 私房菜——基础学习篇》
- 《Linux 系统架构和应用技巧》
- 《Linux 系统架构与目录解析》