一、Linux 与硬件的搭配
Linux 中所有设备均被视为文件,其命名规则如下:
设备 | 文件名 |
---|---|
SCSI/SATA/USB 硬盘机 | /dev/sd[a-p] |
USB 闪存盘 | /dev/sd[a-p](与 SATA 相同) |
Virtl/O 界面 | /dev/vd[a-p](用于虚拟机内) |
软盘机 | /dev/fd[0-7] |
打印机 | /dev/lp[0-2](25针打印机)、/dev/usb/lp[0-15](USB 接口) |
鼠标 | /dev/input/mouse[0-15](通用)、/dev/psaux(PS/2 界面)、/dev/cdrom(当前 CDROM) |
CDROM/DVDROM | /dev/scd[0-1](通用)、/dev/sr[0-1](通用,CentOS 较常见)、/dev/cdrom(当前 CDROM) |
磁带机 | /dev/ht0(IDE 界面)、/dev/st0(SATA/SCSI 界面)、/dev/tape(当前磁带) |
IDE 硬盘机 | /dev/hd[a-d](旧式系统才有) |
二、磁盘分区
1. 主要开机记录区 MBR
目前主流的磁盘接口为 SATA 和 SAS ,以前的 IDE 界面的磁盘文件名已仿真成和 SATA 一样。由于虚拟化技术的应用,许多机器为虚拟机,因此所使用的磁盘为虚拟磁盘,正常的磁盘文件名为 /dev/sd[a-] ,而虚拟机为了加速则使用 /dev/vd[a-p] 的文件名。
由于 SATA/USB/SAS 等磁盘接口都是使用 SCSI 模块来驱动的,因此这些接口的磁盘设备文件名都是 /dev/sd[a-p] 的格式,所以没有固定的顺序,通常都是根据 Linux 核心侦测到磁盘的顺序处理。如果 SATA 磁盘被差在主板上,那么先命名 SATA 磁盘,等开机完成后再检测 USB 磁盘,对其进行命名。
早期的 Linux 系统为了相容于 Windows 的磁盘,采用 MBP(Master Boot Record,主要开机记录区)的方式来处理开机管理程序与分区表,通常放在第一个扇区(512 Bytes),有两个数据:
- 主要开机记录区:可以安装开机管理程序的地方,有 446 Bytes;
- 分区表(partition table):记录整颗硬盘分区的状态,有 64 Bytes;
由于分区表仅有 64 Bytes 容量,因此最多仅能有 4 组记录区,被称为主要(Primary)或延伸(Extended)分区,每组记录区记录了该区段的起始与结束的柱面号码(就是将所有柱面按照位置划分为 4 个区),假设该硬盘设备文件名为 /dev/sda ,硬盘总共有 400 个柱面,那么这四个区的命名为:/dev/sda[1-4] ,每个分区有 100 个柱面。如果操作系统为 Windows ,那么这四个分区代号为 C、D、E、F ,因此: - 分区知识针对分区表进行设置,并没有从物理结构上进行重构;
- 硬盘默认的分区表仅能写入 4 组分区信息;
- 这 4 个分区称为主要(Primary)或延伸(Extended)分区;
- 分区的最小单位通常为柱面(cylinder);
- 当系统要写入磁盘时,需要参考磁盘分区表,才能针对某个分区进行数据处理;
- 分区可以提高数据安全性,对一个分区的数据进行处理,不会影响到其他分区;
- 分区能够集中数据,使得系统读取范围更加集中,有助于数据读取的速度与性能。
虽然分区表只能记录 4 组数据的空间,但是可以利用其他扇区建立新的分区表,以实现更多分区:
也就是说延伸分区并不是只占一个区块,二十分布在每个分区最前面的几个扇区进行记录。P1 为主要分区,P2 为延伸分区,延伸分区的目的是使用额外的扇区来记录分区信息,因此延伸分区本身不能被格式化,可以通过延伸分区所指向的区块继续作分区的记录。上图右下方区块表示继续划分的 5 个分区,被称为逻辑分区(logical partition),其可以使用的煮面范围为延伸分区所设置的范围。此时逻辑分区的设备文件名为:/dev/sda[5-9] ,之所以从 5 开始是因为前面有分区表所标定的 4 个分区,即使无记录也不能占用。逻辑分区的数量依操作系统而不同,再 Linux 系统中 SATA 硬盘已经可以突破 63 个以上的分区限制。
由于柱面为分区的单位,且是连续的磁盘空间,因此在合并分区时容易出现问题:
上图可以将两个蓝色分区合并,因为此时两个分区同属延伸分区中的逻辑分区,只需要将两个分区删除,然后重新创建一个新的分区即可。
下图则不行,因为两个蓝色分区分属主分区与逻辑分区,若要合并需要将延伸分区破坏掉再重新分区,导致影响所有分区。
由于每个分区表仅有 16 Bytes ,因此 MBR 分区表存在限制:
- 操作系统无法抓取到 2.2T 以上的磁盘容量;
- MBR 仅有 1 个区块,若被破坏则会丢失信息;
- MBR 内的存放开机管理程序的区块仅 446 Bytes ,无法容纳较多的程序码。
2. 磁盘分区表 GPT
过去一个扇区大小为 512 Bytes ,目前则已经有 4K 的扇区,为了相容于所有的磁盘,因此在扇区的定义中,大多会使用所谓的**逻辑区块位址(Logical Block Address,LBA)**来处理。GPT 将磁盘所有区块以此 LBA(默认 512 Bytes)规划,第一个 LBA 成为 LBA 0 。
GPT 使用了 34 个 LBA 区块来记录分区信息,并且使用最后的 33 个 LBA 作为备份:
- LBA 0(MBR 相容区块):于 MBR 模式相似,该区块分为两部分,一个是与 446 Bytes 相似的区块,存储了第一阶段的开机管理程序,另一个是在原本的分区表的记录区内进放入一个特殊标志的分区,用来表示此磁盘为 GPT 格式,如果操作系统不懂得 GPT ,那么将不会识别该磁盘。
- LBA 1(GPT 表头记录):记录了分区表本身的位置与大小,同时记录了备份用的 GPT 分区的位置信息,同时放置了分区表的检验机制码(CRC32),如有错误,操作系统可以通过该记录区取得备份的 GPT 来恢复正常运行。
- LBA 2-33(实际记录分区信息处):每个 LBA 都可以记录 4 个分区记录,因此默认情况下总共可记录 128 个分区记录,因为每个 LBA 有 512 Bytes ,因此每笔记录用到 128 Bytes 的空间,除了每笔记录所需要的识别码与相关的记录外,GPT 在每笔记录中分别提供了 64 bits 来记录开始/结束的扇区号码,因此 GPT 分区表对于单一分区来说,最大容量限制在 2 64 × 512 B y t e s = 2 63 K B = 2 33 T B = 8 Z B 2^{64}\times512Bytes=2^{63}KB=2^{33}TB=8ZB 264×512Bytes=263KB=233TB=8ZB 。
由于 GPT 分区已经没有所谓的主、延伸、逻辑分区的概念,每个记录都可以单独存在,因此均可以视为主分区,并进行格式化。
并不是所有操作系统都可以读取 GPT ,也不是所有硬件都支持 GPT ,能否读写 GPT 格式与开机的检测程序有关,即 BIOS 与 UEFI 。
3. 开机检测程序
目前的主机系统在载入硬件驱动方面的程序,主要有早期的 BIOS 与新的 UEFI 两种机制。
Ⅰ. BIOS 搭配 MBR/GPT 的开机流程
CMOS 是记录各项硬件参数且嵌入在主板上面的储存器,BIOS 则是一个写入到主板上的一个固件(即写入到硬件上的一个软件程序),因此 BIOS 就是开机时系统会主动执行的第一个程序。
BIOS 会分析计算机里面有哪些储存设备,以硬盘为例,BIOS 会依据使用者的设置去取得能够开机的硬盘,并且到该硬盘里面去读取第一个扇区的 MBR 位置,而 MBR 会存放最基本的开机管理程序,因此它会接替 BIOS 进行后续工作。
开机管理程序的目的是载入(load)核心文件,由于开程序是操作系统在安装时所提供的,因此能够识别硬盘内的文件系统格式,可以读取核心文件,接下来就是核心文件的工作了。总的来说,开机流程到操作系统之间的动作如下:
- BIOS:开机主动执行的固件,识别第一个可开机的设备;
- MBR:第一个可开机设备的第一个扇区内的主要开机记录区块,内含开机管理程序;
- 开机管理程序(boot loader):一支可读取核心文件来执行的软件;
- 核心文件:开始操作系统的功能。
若采用 GPT 格式,由于 LBA 0 仅提供第一阶段的开机管理程序码,因此如果使用类似 grub 的开机管理程序,需要额外分出一个 BIOS boot 分区,该分区才能放置其他开机过程所需的程序码。
boot loader 的主要任务如下:
- 提供菜单:使用者可以选择不同的开机项目,这也是多重开机的重要功能;
- 载入核心文件:直接指向可开机的程序区段来开始操作系统;
- 转交其他 loader :将开机管理功能转交给其他 loader 负责。
其他 loader 指安装在每个分区的开机山区内的开机管理程序,也就是说开机并不是只能采用第一扇区中的程序:
上图表示 2 个新的开机管理程序分别安装在两个分区内,那么开机时首先会看到 MBR 的开机管理程序提供的两个菜单,菜单一(M1)可以直接载入 Windows 的核心文件来开机;菜单二(M2)则是将开机管理工作交给第二个分区的开机扇区(boot sector)。当选择菜单二时,整个开机管理工作就交给第二分区的开机管理程序,此时仅有一个开机菜单,指向 Linux 的核心文件,总结如下
- 每个分区都拥有自己的开机扇区;
- 图中的系统盘为第一及第二分区;
- 实际可开机的核心文件是放置到各分区内的;
- loader 只会认识自己的系统盘内的可开机核心文件,以及其他 loader ;
- loader 可直接指向或是间接将管理权转交给另一个管理程序;
- Windows 安装时会主动覆盖掉 MBR 以及自己所在分区的开机扇区,没有选择机会,而 Linux 更加灵活,可供用户自行设置安装扇区及设置菜单,因此通常应先安装 Windows 再安装 Linux ,否则就需要采用 Linux 救援模式来挽救 MBR 了。
Ⅱ. UEFI BIOS 搭配 GPT 开机的流程
由于 GPT 可以提供到 64 bit 的寻址,也能使用较大的区块来处理开机管理程序,但是 BIOS 仅有 16 位,且不支持 GPT ,需要 GPT 采用相容模式适应它,因此现阶段采用 UEFI(Unified Extensible Firmware Interface),其主要取代 BIOS 这个固件界面,因此也将其称为 UEFI BIOS ,它采用 C 语言,比起 BIOS 更容易开发,两者区别如下:
比较项目 | 传统 BIOS | UEFI |
---|---|---|
使用程序语言 | 组合语言 | C 语言 |
硬件资源控制 | 使用终端(IRQ)管理,不可变的内存存取,不可变的输入/输出存取 | 使用驱动程序与协定 |
处理器运行环境 | 16 位 | CPU 保护模式 |
扩充方式 | 通过 IRQ 链接 | 直接载入驱动程序 |
第三方厂商支持 | 较差 | 较佳且支持多平台 |
图形化能力 | 较差 | 较佳 |
内置简化操作系统前环境 | 不支持 | 支持 |
由于 UEFI 类似于一个低阶的操作系统,而在发展最初指定的一些控制,导致其效率稍慢,因此通常在载入操作系统后,URFI 会停止工作。虽然 UEFI 可以直接取得 GPT 分区表,但最好还是拥有 BIOS boot 的分区支持,同时为了与 Windows 相容,并且提供其他第三方厂商所使用的 UEFI 应用程序储存的空间,因此需要格式化一个 vfat 文件系统,大约提供 512 MB 到 1 G 左右的容量。由于 BIOS boot 以及 UEFI 支持的分区,基本上 /boot 目录已经是 /dev/sda3 之后的号码了。
4. Linux 安装模式下,磁盘分区的选择
Linux 采用目录树架构,但是文件数据实际上存储在磁盘分区中,那么如何结合目录树的架构与磁盘内的数据?
Ⅰ. 文件系统与目录树的关系
所谓的挂载就是利用一个目录当成进入点,将磁盘分区的数据放置在该目录下,也就是说进入该目录就可以读取该分区。这个动作成为挂载,进入点称为挂载点:
上图中 partition 1 是挂载到根目录,partition 2 是过再到 /home 目录。光盘也是同理,通常挂载到 /media/cdrom/ 目录。