关于启动引导的那些事儿(下) : UEFI与GPT

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下,一个可能的引导过程为

  1. BIOS启动,寻找引导设备
  2. 运行MBR
  3. MBR查找磁盘上活动分区
  4. 运行活动分区内的引导程序PBR
  5. 由PBR载入、引导磁盘上的操作系统

而简化后的UEFI在引导过程中,只需要寻找并执行ESP内的引导程序即可。

Reference

  1. Unified Extensible Firmware Interface – Wikipedia(https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface
  2. 全局唯一标识分区表 – 维基百科(https://zh.wikipedia.org/wiki/GUID%E7%A3%81%E7%A2%9F%E5%88%86%E5%89%B2%E8%A1%A8
  3. Linux 引导过程内幕(https://www.ibm.com/developerworks/cn/linux/l-linuxboot/
分享到

KAAAsS

喜欢二次元的程序员,喜欢发发教程,或者偶尔开坑。(←然而并不打算填)

相关日志

  1. 没有图片
  2. 没有图片

评论

还没有评论。

在此评论中不能使用 HTML 标签。