MBR的缺点
MBR的缺点主要在于他是个程序。引导程序和磁盘分区原本是不太相关的两个事情,但是MBR却用一种及其原始的方式把它们混合在了一起。此外,MBR程序本身也带来了不少麻烦。由于MBR运行在实模式,因此它的编写与引导过程的其它程序有诸多不同。而且由于MBR是直接写在引导扇区的,并不是以文件的形式存在,因此对MBR进行管理也十分麻烦。缺少程序校验也使黑客可以通过更改MBR,让病毒在操作系统引导前就完成载入。总而言之,MBR的设计真的太过时了。
UEFI
UEFI(Unified Extensible Firmware Interface,统一可扩展固件接口)就是为了替代BIOS与MBR而诞生的。UEFI的前身是Intel开发的EFI,在标准化后就改名为UEFI。
从名字就可以看出,UEFI是介于系统固件和操作系统中间的软件界面。因此,它的定位并不是和BIOS类似的操作系统,而仅仅是一系列固件接口程序。而这意味着UEFI并不会使用中断,也没有完整的内存分配机制。这使得UEFI专注于硬件交互和系统引导,也简化了硬件驱动开发的流程。
UEFI的一大特点就是灵活。比如UEFI的驱动程序是使用EBC(EFI Byte Code)编写的,运行时UEFI固件会在DXE(Driver Execution Environment,驱动程序运行环境)下实时解释执行,类似于Java字节码和JVM的关系。因此,UEFI下的驱动程序是与CPU架构无关的,兼容性相对更好。
GPT
UEFI的另一个功能就是引导。而由于操作系统程序存在于磁盘中,因此UEFI也需要分区表。GPT(GUID Partition Table,全局唯一标识分区表)就是UEFI标准中的分区表。不同于MBR,GPT只负责分区。
GPT以LBA编址(可以参考上一篇博文,是比CHS更现代的方式),与存储介质的形态无关,因此可以兼容各种设备。GPT总共占用磁盘开头的34个LBA,包含了保护MBR、GPT头和GPT数据。此外,GPT通常还会占用磁盘最后33个LBA,用来备份当前的分区表。开头的LBA(或前512字节)是保护MBR,它具有MBR标志位但是并不保存实际分区数据,只是用于防止针对MBR设计的程序对GPT结构进行破坏。
GPT最明显的一个特点就是使用GUID来标志磁盘分区和分区类型。比如对于MBR分区表,GPT将它的分区类型标志为024DEE41-33E7-11D3-9D69-0008C781F39F
;而EFI系统分区将被标志为C12A7328-F81F-11D2-BA4B-00A0C93EC93B
。对于不同的系统不同分区类型,都可以使用各自的分区类型标志,因此GPT的分区信息较MBR更加丰富。
在Linux下,使用gdisk
指令即可对GPT分区表的磁盘进行操作。
$ sudo gdisk /dev/nvme0n1
GPT fdisk (gdisk) version 1.0.5
The protective MBR's 0xEE partition is oversized! Auto-repairing.
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Command (? for help): p
Disk /dev/nvme0n1: 500118192 sectors, 238.5 GiB
Model: INTEL SSDPEKKW256G8
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 4C0FC2FD-B8CF-11E9-A0C4-7470FD38587D
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 500118158
Partitions will be aligned on 2048-sector boundaries
Total free space is 6105 sectors (3.0 MiB)
Number Start (sector) End (sector) Size Code Name
1 2048 1230846 600.0 MiB EF00 EFI system partition
2 1230848 415408788 197.5 GiB 0700 Basic data partition
3 415410176 416720895 640.0 MiB 2700
4 416722944 500117503 39.8 GiB 8300 Linux data partition
可以看到,gdisk
识别出了不同的分区类型。
ESP与UEFI引导
GPT有一种特殊的分区类型:ESP(EFI system partition,EFI系统分区)。ESP专门用来存放引导相关的文件,因此会被特殊标记,并在启动时自动搜索引导程序。和MBR不同,ESP中的引导程序是以文件的形式存储的,因此ESP本身也是格式化的(通常是FAT32)。文件的形式给UEFI带来了远超MBR的引导能力,部分引导程序甚至可以通过配置文件来实现自定义。
在linux下,ESP通常会被挂载为/boot/efi
。ESP磁盘的EFI
文件夹下存放了各种启动引导程序(包括Bootloader和Boot Manager)。ESP可以同时存放多个引导程序。UEFI标准规定,引导程序必须放置在ESP磁盘的/EFI/id/
下,并且以.efi
为后缀名,比如Manjaro默认的引导位于/EFI/Manjaro/grubx64.efi
。启动时系统会扫描相关引导程序,并按预先设定的顺序进行引导。使用efibootmgr
指令可以查看当前的引导顺序
$ efibootmgr
BootCurrent: 0004
Timeout: 2 seconds
BootOrder: 0004,0000,0005,0006,0007,0001,0002,0003
Boot0000* Windows Boot Manager
Boot0001* UEFI:CD/DVD Drive
Boot0002* UEFI:Removable Device
Boot0003* UEFI:Network Device
Boot0004* rEFInd Boot Manager
Boot0005* Manjaro
Boot0006* UEFI: PXE IP4 Realtek PCIe GBE Family Controller
Boot0007* UEFI: PXE IP6 Realtek PCIe GBE Family Controller
使用-o
选项可以对启动顺序进行调节。具体操作可以查看man
。
除了从ESP进行引导(不仅限于磁盘,还有USB设备等等),UEFI标准还提供了UEFI Shell以便在shell环境下执行、调试UEFI程序。
引导程序
引导程序其实分为Bootloader和Boot Manager。Bootloader仅仅是用于引导系统的程序,而Boot Manager是Bootloader的管理程序,可以实现如多系统选择引导等等功能。不过如今,Bootloader大多集成了Boot Manager的功能。比如Windows阵营的Windows Boot Manager,Linux阵营中的Grub2。它们都可以承担多系统引导的工作。而专门化的Boot Manager比如rEFInd,目前更多承担的是可定制化启动和美化的工作。不过在UEFI中,它们都统一以EFI
文件夹下的.efi
文件的形式存在。以Grub2为例,你可以通过如下指令生成Grub2的引导程序
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=Manjaro
通过EFI,原本的启动引导过程得到了极大的简化。原本的MBR下,一个可能的引导过程为
- BIOS启动,寻找引导设备
- 运行MBR
- MBR查找磁盘上活动分区
- 运行活动分区内的引导程序PBR
- 由PBR载入、引导磁盘上的操作系统
而简化后的UEFI在引导过程中,只需要寻找并执行ESP内的引导程序即可。
Reference
- Unified Extensible Firmware Interface – Wikipedia(https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface)
- 全局唯一标识分区表 – 维基百科(https://zh.wikipedia.org/wiki/GUID磁碟分割表)
- Linux 引导过程内幕(https://www.ibm.com/developerworks/cn/linux/l-linuxboot/)