From Disk to Operating System

硬盘分类

接口类型全称协议类型传输速率范围连接方式主要特点典型应用场景
SATASerial ATAAHCI/NVMe1.5-6 Gbps7针数据+15针电源兼容性强,成本低,支持热插拔家用PC、普通服务器
mSATAMini-SATAAHCI1.5-6 Gbps52针接口SATA的迷你版本,无电源接口超极本、工业设备
SATAeSATA ExpressAHCI/NVMe8-16 Gbps2x SATA+PCIe兼容SATA和PCIe协议早期高性能存储过渡方案
M.2NGFF (Next Gen FF)SATA/NVMe6-32 GbpsM型/B型/M+B型键支持PCIe通道,体积小巧,可选SATA或NVMe协议笔记本、高端PC、工作站
U.2SFF-8639NVMe32-64 Gbps68针接口支持热插拔,兼容2.5寸硬盘形态企业级存储、数据中心
PCIePCI ExpressNVMe16-128 GbpsPCIe插槽直接连接CPU,超低延迟高性能计算、显卡扩展存储
SASSerial Attached SCSISCSI6-24 Gbps29针接口全双工,支持多路径访问,高可靠性企业级服务器、存储阵列
FCFibre ChannelSCSI/FCP16-128 Gbps光纤接口超长距离传输(最远10km),支持SAN架构大型数据中心、云存储
USBUniversal Serial BusUAS/BOT0.48-40 GbpsType-A/C等即插即用,广泛兼容外置存储、移动设备
Thunderbolt-NVMe over PCIe40-120 GbpsType-C接口支持菊花链拓扑,可传输视频和数据创意工作站、外置SSD
NVMe-oFNVMe over FabricsRDMA/FC/TCP25-200 Gbps多种网络介质支持远程访问NVMe设备分布式存储、超融合架构
IDE/PATAParallel ATAATA16-133 MBps40/80针排线已淘汰,并行传输2000年前的老旧电脑

上述表格总结的各类接口,还存在着各种类型的协议

  1. AHCI:面向机械硬盘设计,支持NCQ但存在延迟瓶颈
  2. NVMe:专为SSD优化,支持64K命令队列,延迟降低90%
  3. SCSI:企业级协议,支持标签化命令和错误恢复
  4. UAS:USB3.0后的新一代协议,替代BOT模式提升效率
  5. RDMA:绕过CPU直接内存访问,用于超低延迟场景

引导类型与磁盘分区表格式

BIOS 还是 UEFI 这只是发展过程中产生的两种启动模式,但是启动逻辑是始终如一的.

开机过程分为主板侧和磁盘侧两部分。主板上存在一块 ROM,像我们平时进入的 BIOS 设置界面(或 UEFI 固件设置界面)都是 ROM 上的程序提供的功能。除了提供这个设置功能外,它还负责将后续启动过程交给磁盘侧来继续完成,而磁盘侧的结构和流程就进一步细分成"传统 BIOS 模式 (Legacy) “和"现代 UEFI 模式"两种了。

虽然说磁盘侧的后续过程被细分为 BIOS 和 UEFI 两种,但是 BIOS 固件和 UEFI 固件实际是主板 ROM 上的两种类型,正是因为它们的特性不同,才导致了对磁盘上的结构以及数据要求的不同。

BIOS 固件只会无脑加载磁盘的 0 号扇区,后来为了适应 BIOS 固件的这种启动行为,在磁盘设计上提出了 MBR 分区表类型(Master Boot Record,主引导记录)。更具体来说在磁盘的 0 号扇区有 512 字节的数据,446 字节的主引导代码,64 字节的分区表以及 2 字节的结束有效标志,之后的磁盘区域就是存放的操作系统分区了。由 BIOS 固件到 MBR 上的引导代码,操作系统的启动过程也就从主板侧来到了磁盘侧,后续就是加载真正的操作系统内核了。

UEFI 固件则已经类似于一个操作系统。与 BIOS 固件对接 MBR 分区表格式对应,UEFI 固件所对应的分区表格式叫做 GPT (GUID Partition Table, 全局唯一标识符分区表)。这种分区表格式在数据组织上,在最开始的位置是一个 FAT32 格式的 ESP 系统分区 (EFI System Partition),其中存放的是下面这些引导文件。在 ESP 之后就是操作系统分区。整体过程就是从 UEFI 固件到 efi 引导文件,最后到操作系统分区中的系统内容。

  • /EFI/boot/bootx64.efi (Fallback 文件,适用于磁盘迁移时找不到对应引导文件时的选择)
  • /EFI/ubuntu/grubx64.efi (GRUB)
  • /EFI/Microsoft/Boot/bootmgfw.efi (Windows Boot Manager)

值得提到的一点是在 UEFI 启动模式下的多系统启动,常规的方式在系统启动时通过 Fxxx 键进入 UEFI 设置界面,修改操作系统的启动优先顺序,但是这无疑是麻烦的,所以就出现了一种链式加载(Chainloading)的方式。具体来说,启动时会走 GRUB,由 GRUB 再选择是走 ubuntu 的 efi 还是 windows 的 efi。这相当让 GRUB 作为"引导引导程序”,它的实现方式是使用 os-prober程序为 GRUB 生成配置文件,从而可以添加一个启动时走 windows efi 的配置项。这样的好处是在希望切换系统时按照正常的启动流程即可,无需再次进入 UEFI 的设置界面。

项目EFI/UEFIGPT
本质启动固件(主板程序)磁盘分区表(磁盘结构)
执行位置主板固件中磁盘开头的分区结构
管理对象控制系统引导流程、寻找 EFI 文件控制磁盘分区的布局和类型
相互关系UEFI 需要 GPT 格式的磁盘才能使用 EFI 启动GPT 磁盘中必须有一个 EFI 分区供 UEFI 使用
可否分开使用GPT 可以用 BIOS 启动(需要 BIOS 支持)UEFI 也可兼容 MBR(有兼容启动选项)

由 archlinux 了解系统安装的本质

在 Windows 系统安装流程中,分为三个层次:

  1. 安装在启动盘中的 PE 系统
  2. 系统安装镜像(一般为 iso 文件)
  3. 实际安装到磁盘的系统

由于 Windows 在内以及包含一般 Linux 发行版在内的众多系统,往往就是双击或者说挂载 iso 之后,遵循着一系列的设置流程,系统就安装完成了,所以我一直不太理解这个 iso 系统镜像文件究竟是什么。

但是由于 archlinux 系统安装的所有过程都需要手动完成(安装流程参考Arch Linux 安装使用教程),因此在这个过程才了解到系统镜像中包含的文件结构实际就是最后安装完成后的系统所具备的文件结构,而装系统也就是在镜像中的文件基础上,经过一系列自定义,将这些文件区别化的迁移到磁盘中的一个过程。

实践

一种更便捷且安全的实践方式是使用 QEMU 完成一个系统的安装流程,以下给出简要的流程描述。

  1. 编译安装 QEMU

source code

configure 脚本如下

1
../configure --prefix=xxx --enable-kvm --target-list=x86_64-softmmu --enable-debug --enable-slirp

其中的添加 slirp 是因为在 qemu 启动时需要指定虚拟机使用的网络模式,其中的 user network backend 默认是不具备的,需要在编译时额外添加选项,该解决方案参考network backend ‘user’ is not compiled into this binary

  1. 创建虚拟磁盘
1
qemu-img create -f qcow2 ubuntu.qcow2 20G
  1. 启动 qemu

比较关键的一点是如何让 qemu 模拟 UEFI 启动,一般来说这是需要主板支持的,在虚拟机下则需要通过 ovmf 来进行支持,一方面是需要在宿主机安装 ovmf,另一方面是在 qemu 启动时添加额外的选项。

1
2
3
4
5
6
7
8
# bios 是设置 UEFI 启动模式,需要在宿主机安装 ovmf
#qemu-system-x86_64 \
#    -enable-kvm \
#    -m 2048 \
#    -nic user,model=virtio \
#    -drive file=arch.qcow2,media=disk,if=virtio \
#    -cdrom archlinux-x86_64.iso \
#    -bios /usr/share/OVMF/OVMF_CODE.fd
  1. 其他问题解决

在添加完引导程序准备启动程序时,可能会在开机时仍然找不到引导程序,这是因为某些主板的 UEFI 会硬编码引导路径,仅识别固定路径 EFI/BOOT/BOOTX64.EFI,忽略其他自定义路径(如 EFI/ARCH/grubx64.efi),所以需要额外将 GRUB 安装到 UEFI 规范中的后备引导路径,当然这一点在 archlinux 的安装流程中也有说明。

0%