2019-05-27
BIOS和UEFI

MBR

MBR(Master Boot Record)是BIOS下的硬盘分区格式,占据硬盘的第一个sector, 通常是512Bytes。

它支持4个主分区(Primary partition),或者3个主分区和1个扩展分区(Extended Partition), 扩展分区可以被分割成若干逻辑分区(Logical Partition).

MBR包含一个分区表和自启动代码:

地址 字节数 说明
1 - 446(1BE) 446 自启动代码
447 - 510((1FE) 64 4个主分区条目,每个分区条目占16Bytes
511 - 512 2 自启动代码签名

因为给启动代码的空间只有446字节,一般的启动程式还会占用MBR和第一分区里的空白区域,而MBR里的启动程序仅作为加载剩余部分用.

MBR里每个分区条目占据16字节:

地址 字节数 说明
1 1 自启动flag, 0x80: bootable, 0x0: Non-bootable
2 - 4 3 开始扇区号的CHS地址
5 1 分区类型
6 - 8 3 结束扇区号的CHS地址
9 - 12 4 开始扇区在LBA地址中的起始扇区号
13 - 16 4 该分区的扇区数

分区表条目里有两种寻址方式:CHS寻址和LBA寻址。CHS寻址基本不用了,因为现代的存储硬盘要么不是CHS结构要么自带有将CHS寻址转换为LBA寻址的驱动。

因为分区的起始地址和分区的大小都是用4个字节来存放,而一个扇区为512字节,所以一个分区的最大容量是2T (512 x 2^32) ,而整个磁盘最多能分区4T的容量。

BIOS引导流程

BIOS本身的引导逻辑很简单: 按照一定顺序(这个顺序用户可以在BIOS界面里设置)试加载有bootable标志的硬盘,加载执行该硬盘MBR里的自启动程序.

BIOS引导的弊端:

  1. 分区表和引导程序放在一起, 你需要特殊的工具去查看和修改MBR.

  2. MBR给引导程序的空间太小(仅446字节), 因此大多数的引导程序要分成若干阶段加载。

  3. MBR只支持最多2T的分区。

  4. 大部分的引导功能都交给了引导程序,这使得像多重引导和网络引导等没有规范。

GPT

GPT是UEFI下的硬盘分区格式, 为了兼容MBR,它的第一个扇区是一个MBR结构,只有一个类型号EEh为的分区.

GPT为整个磁盘和每个分区都分配了一个GUID, 分区表有备份和CRC32校验, 只保留了LBA寻址模式, 并且不再包含启动代码.

GPT分区的格式:

Offset Length Contents
0 (0x00) 16 bytes Partition type GUID (mixed endian[6])
16 (0x10) 16 bytes Unique partition GUID (mixed endian)
32 (0x20) 8 bytes First LBA (little endian)
40 (0x28) 8 bytes Last LBA (inclusive, usually odd)
48 (0x30) 8 bytes Attribute flags (e.g. bit 60 denotes read-only)
56 (0x38) 72 bytes Partition name (36 UTF-16LE code units)

UEFI引导流程

UEFI是为GPT设计的, 但也可以通过CSM(Compatibility Support Module)模式引导MBR硬盘. 只是以CSM引导的操作系统没有权限修改UEFI的引导列表.

与BIOS在硬盘的第一个扇区里读取引导程序不同,UEFI可以识别FAT文件系统,要求硬盘有一个特殊的FAT分区来存放引导程式,这个分区被称为ESP(EFI system partition)。引导程式放到文件系统里,这样远比放在第一个扇区这样的阴暗角落便于维护。

UEFI里自带boot manager, 它将引导条目存放在固件的NVRM里,操作系统可以在增删条目(对比BIOS,它仅包含有bootable标志的硬盘,不可以增删), 比如Linux的efibootmgr

运行efibootmgr示例:

# efibootmgr -v
BootCurrent: 0002
Timeout: 3 seconds
BootOrder: 0003,0002,0000,0004
Boot0000* CD/DVD Drive  BIOS(3,0,00)
Boot0001* Hard Drive    HD(2,0,00)
Boot0002* Fedora        HD(1,800,61800,6d98f360-cb3e-4727-8fed-5ce0c040365d)File(\EFI\fedora\grubx64.efi)
Boot0003* opensuse      HD(1,800,61800,6d98f360-cb3e-4727-8fed-5ce0c040365d)File(\EFI\opensuse\grubx64.efi)
Boot0004* Hard Drive    BIOS(2,0,00)P0: ST1500DM003-9YN16G        .

BootCurrent表示现在的操作系统是通过哪个条目引导的, Boot0000和Boot0004是uefi通过MBR自动生成的条目。

Boot0002是一个常规的UEFI条目,HD里是分区信息,File里是引导程序在这个分区里的路径.

用grub安装引导程序和增加一个引导条目:

# grub-install --target=x86_64-efi --efi-directory=[esp mount point] --bootloader-id=[boot entry name]

lazyrobot.me