BIOS 与 UEFI 引导流程
前言
现代计算机的整个启动过程可以概括为:
-
计算机通电;
-
CPU 读取保存在主板上 ROM 芯片里的 BIOS 或 UEFI 程序(BootLoader);
-
该程序加载指定启动介质(包括从网络启动,但一般为本地硬盘),并从该介质启动操作系统。
主板固件(BIOS 与 UEFI)
固件(Firmware)是固化在特定芯片里的软件程序,是硬件设备最底层的软件。
可以把 UEFI 和 BIOS 都理解成一种固件,其主要功能是为计算机提供最底层的、最直接的硬件设置和控制(包括启动操作系统),而 UEFI 是传统 BIOS 升级替代品,功能更强,并兼容传统 BIOS。
BIOS
由于计算机启动是一个很矛盾的过程,即必须先运行程序,然后计算机才能启动,但是计算机不启动就无法运行程序!因此,需要想办法把一小段程序装进内存,然后计算机才能正常运行,这段程序称为 BIOS(基本输入输出系统),保存在计算机主板上的一个芯片里(称为BIOS ROM),如下图。
通常 BIOS 会被认为是随着 IBM PC 的出现而产生的,实际上 BIOS 要早于 IBM PC,早在1975年,BIOS 的概念就在 CP/M 系统上出现。后来随着计算机硬件的发展,除了上面提到的主板 BIOS(也叫系统 BIOS)以外,其他硬件也有了 BIOS 程序,如显卡 BIOS,硬盘 BIOS 等,但我们一般提到的 BIOS 固件专门指主板 ROM 芯片里的 BIOS 程序(即系统 BIOS)。
BIOS功能
-
检测硬件,又叫 POST,就是检测硬件是否还正常的工作;
-
初始化硬件,设置其基本状态,使得整个计算机达到所谓的"可用状态"(Ready State);
-
启动 OS Loader 加载操作系统;
BIOS 固定地加载存储器最前面扇区(LBA0)里的引导程序(即 BootLoader),然后,由 BootLoader 启动操作系统。
-
在操作系统启动起来以后,一部分继续驻留内存,向操作系统以及其他软件提供基本的系统级的服务,如磁盘读写(INT13 中断服务)等;
-
修复硬件缺陷,如 Intel CPU 的 SMM 功能。
BIOS启动过程
-
通电:CPU 初始化,并执行 BIOS 程序;
-
自检:BIOS 程序启动开始 POST 自检,进行更完整的硬件(检查 CPU、RAM、键盘、鼠标等)检测;
此阶段无法屏幕显示,只能通过主板扬声器报警。
-
其他初始化:初始化显卡和其他设备并显示到屏幕;
-
加载 MBR:BIOS 提供中断服务,读取 CMOS 设置,读取第一个启动磁盘的 MBR 到内存让 CPU 执行(此后 BIOS 就撒手不管了),然后由 MBR 引导代码启动操作系统。
BIOS 的缺点
BIOS 的缺点:
-
不支持2.2TB硬盘作为启动盘
-
安全与扩展性差等
UEFI
由于BIOS各种缺点,英特尔公司从 2000 年开始,发明了可扩展固件接口(Extensible Firmware Interface),用以规范 BIOS 的开发。而支持 EFI 规范的 BIOS 也被称为EFI BIOS。
之后为了推广EFI,业界多家著名公司共同成立了统一可扩展固件接口论坛(UEFI Forum),英特尔公司将 EFI 1.1 规范贡献给业界,用以制订新的国际标准 UEFI 规范。
UEFI 是一种规范,不同厂商根据该规范对 UEFI 的实现并烧录到芯片里,该实现程序就称为 UEFI 固件。
UEFI 启动过程
EFI 启动过程如下:
-
SEC(安全性)阶段:通电,内存未初始化,CPU 只能使用 Cache 来验证 CPU、芯片组和主机驱动;
-
PEI(EFI前初始化)阶段:初始化一小部分低地址内存空间,CPU 开始使用此内存初始化CPU、芯片组 和主板,随后EFI驱动载入内存;
-
DXE(驱动执行环境)阶段:此阶段内存、CPU(指CPU插槽上的物理CPU,非CPU核心)、PCI、USB、 SATA 和 Shell 都会被初始化;
-
BDS(开机设备选择)阶段:此阶段用户可选择从检测到启动设备中选择启动设备;
-
TSL(临时系统载入)阶段:此阶段将由启动设备上的系统接手正式进入操作系统, 若 BDS 阶段选择 UEFI Shell则会进入 UEFI 的简单命令行界面,可在此界面做简单维护和诊断。
启用 UEFI 的条件
-
电脑主板支持 UEFI;
2010年后的主板基本都支持。
-
操作系统支持 UEFI;
64位Windows基本都支持
-
磁盘具有 GUID 分区表(GPT)。
-
磁盘分区表中必须有 FAT 分区。
特殊标志的 FAT 分区(即 ESP 分区,也叫 EFI 系统分区),该分区要作为第一个磁盘分区(进入系统会自动隐藏)。
-
可启动的 efi 文件,一般为
\EFI\BOOT\BOOTx64.EFI
注,不同平台文件名可能不同。
从上面的启用条件发现,虽然要求支持 UEFI 的固件必须支持读取 GPT 磁盘类型中的 FAT(12/16/32) 文件系统格式,并可读取该 FAT 中的文件和执行 *.efi
的可执行文件,但是 UEFI 规范并没有提到固件不能识别其他文件系统类型(如苹果 Mac 的 HFS+)并从中加载启动装载程序(苹果 Mac 在这方面有与众不同的个性)。
硬盘分区结构(MBR 与 GPT)
目前硬盘有 MBR 与 GPT 两种分区方式,其中,Legacy BIOS 使用 MBR 分区表,UEFI 使用 GPT 分区表。
MBR 分区
主引导记录(Master Boot Record,MBR) 磁盘分区是一种使用广泛的分区结构,它也被称为 DOS 分区结构,但它并不仅仅应用于 Windows 系统平台,也应用于 Linux,基于 X86 的 UNIX 等系统平台。
最早在 1983 年在 IBM PC DOS 2.0 中提出(微软最早与 IBM 合作的操作系统,但更早期的 Unix 系统没有这个概念,更多需要阅读操作系统发展简史)。它是存在于驱动器开始部分的一个特殊的启动扇区,磁盘的第一个扇区,个扇区包含了已安装的操作系统的 BootLoader 和驱动器的分区信息。
注:MBR与MBR 分区结构的区别:前者(狭义)专指主引导记录(磁盘第一扇区),后者(广义)是整个硬盘的组成结构(包括主引导记录扇区与其他扇区)。
主引导记录的位于磁盘的第一个逻辑扇区(512 Byte),即 LBA0 的位置:
一个逻辑扇区仅有 512 Byte,MBR 引导代码占 446 Byte,MBR 分区表占 64 Byte,最后的 magic number (以 0x55AA 结尾的标识符)占2 Byte。因为每个分区只有 16 Byte 大小的分区表记录,所以,寻址最大只能到 2.2TB,并且由于分区表总共只占 64 Byte,所以 MBR 分区表最多 4 个分区,如上图的绿色部分。
分区结构
广义的 MBR 包含整个扇区(引导程序、分区表及分隔标识,即下图红色部分),狭义的 MBR 仅指引导程序(bootloader),这里统一按广义 MBR 的定义进行讨论:
-
主引导代码(BootLoader):占446字节,由操作系统或特殊工具写入。
-
硬盘分区表 DPT:占 64 字节,用 16 字节表示一个分区信息,因此,MBR 只能容纳 4 个分区。
后来随着磁盘空间越来越大,又发明了扩展分区和逻辑分区(为区分把原来的普通分区改称为主分区了)。
-
结束标志:占 MBR 扇区最后2个字节,一直为"0x55 0xAA"(也称魔术字,Magic Number),表示该磁盘可启动。
PBR
分区引导记录(Partition Boot Record,PBR),又被称为 VBR,位于一个分区的第一个扇区。PBR 是由硬盘的 MBR 加载的程序段。PBR 被加载入内存后即开始执行,其主要功能是完成操作系统的自举并将控制权交给操作系统。尽管每个分区都有 PBR,但只有活动分区的 PBR 才会被 MBR 加载执行。
GPT 分区
全局唯一标识码分区表(Globally Unique Identifier Partition Table,GPT),简称 GPT 或 GUID 分区表,它是 UEFI 标准中一种较新的磁盘分区表结构的标准。
GPT 分区相对于 MBR 更为先进,因为 GPT 分区表头可自定义分区数量(而 MBR 最大4个),并且GPT 分区支持 2TB 以上的磁盘空间,在 Windows 系统中微软限定 GPT 最大 128 个分区。GPT 分区结构只能被支持 UEFI 的计算机识别(BIOS无法识别)。
分区结构
GPT 分区由 GPT 头、GPT 主体、GPT 备份组成。它起始于磁盘 LBA1 的位置,相对的 LBA0 仍然为 MBR,但是这个 MBR 是被保护的,没有引导代码,仅仅有一个被标识为未知的分区,当支持 GPT 分区表的操作系统检索到这个 MBR 后就会自动忽略并跳到 LBA1 读取 GPT 分区表。
GPT的分区结构,如下图所示:
-
保护 MBR
在 GPT 分区表的最开头,出于兼容性考虑,仍然存储了一份传统的 MBR(LBA0),这个 MBR 叫做保护性 MBR(Protective MBR),它由分区表和结束标志组成,没有引导代码。而且分区表内只有一个分区表项(标识为 EE),MBR 工具无法识别和操作(从而起到保护作用),GPT 工具则不使用它。
-
GPT 头
起始于磁盘的 LBA1,通常也只占用这个单一扇区,其作用是:定义分区表的位置和大小。GPT 头还包含头和分区表的校验和,这样就可以及时发现错误。
-
GPT 分区表
GPT 分区表区域包含分区表项,这个区域由 GPT 头定义,一般占用磁盘 LBA2~LBA33 扇区,分区表中的每个分区项由起始地址、结束地址、类型值、名字、属性标志、GUID 值组成。
-
用户数据区
就是用户使用的分区,也是用户进行数据存储的区域,分区区域的起始地址和结束地址由 GPT 头定义。
-
分区表备份
分区区域结束后就是分区表备份,其地址在 GPT 头备份扇区中有描述,分区表备份是对分区表 32 个扇区的完整备份。如果分区表被破坏,系统会自动读取分区表备份,也能够保证正常识别分区。
-
GPT头备份
GPT 头有一个备份,放在 GPT 磁盘的最后一个扇区,但这个 GPT 头备份并非完全 GPT 头备份,某些参数有些不一样。复制的时候根据实际情况更改一下即可。
扇区与 LBA 的区别
在 GPT 分区中,每一个数据读写单元成为 LBA(逻辑块地址),一个“逻辑块”相当于传统 MBR 分区中的一个“扇区”,之所以会有区别,是因为GPT除了要支持传统硬盘,还需要支持以 NAND FLASH 为材料的 SSD 硬盘。
不像磁盘那样有磁片,而磁片又划分磁道和扇区来保存数据,因此,闪存材料需要采用模拟扇区来保持统一性。这些硬盘的一个读写单元是 2KB 或 4KB,所以,GPT 分区中干脆用 LBA 来表示一个基础读写块,当 GPT 分区用在传统硬盘上时,通常,LBA 就等于扇区号,有些物理硬盘支持 2KB 或 4KB 对齐,此时,LBA 所表示的一个逻辑块就是 2K B的空间,为了方便,我们后面仍然将逻辑块称为扇区。
操作系统的引导过程
传统 BIOS 与 UEFI 主板引导操作系统过程如下:
-
BIOS:设备加电 -> BIOS 初始化/自检 -> boot loader 引导(扇区代码) -> OS 操作系统;
-
UEFI:设备加电 -> UEFI 平台 -> efi 应用(硬盘文件) -> OS 操作系统。
BIOS 引导操作系统
引导装载程序(boot loader)
引导装载程序(boot loader)是计算机开机自检完成后装载操作系统或者其他系统软件的计算机程序。自检完成后运行引导装载程序,然后再加载并运行软件,引导装载程序可以从硬盘装载到主内存中。
在 MBR 磁盘分区中,引导程序位于主引导记录(MBR)。
但是随着计算机操作系统越来越复杂,位于主引导记录的空间已经放不下引导操作系统的代码,于是就有了第二阶段的引导程序,而 MBR 中代码的功能也从直接引导操作系统变为了引导第二阶段的引导程序。
因此引导程序通常分为两部分:第一阶段引导程序位于主引导记录,用以引导位于某个分区上的第二阶段引导程序,如:NTLDR、BOOTMGR 和 GNU GRUB 等。
对于 UEFI 系统,由 EFI 应用程序(即 EFI 系统分区中的
*.efi
文件)取代了 MBR 和第二阶段引导程序,UEFI 固件会加载引导程序的*.efi
文件,再由引导程序加载操作系统。
注意,理论上传统 BIOS 仅支持 MBR 硬盘启动,在操作系统支持下,GPT 类型的磁盘仅可做数据盘。
引导流程
具体启动过程:
-
按下电源,主板通电,CPU 重置;
-
固化在主板 ROM 芯片里的 BIOS 程序就会被 CPU 加载到内存运行;
-
BIOS 程序自检(POST)完毕以后加载 COMS 芯片里保存的参数;
-
通过 COMS 的参数,BIOS 程序加载指定(启动顺序)磁盘的第一个扇区(即主引导记录 MBR)到内存里运行;
-
引导代码(BootLoader)引导操作系统;
-
当引导文件运行后,操作系统内核就被加载运行,完成从 BIOS 程序(准确的说是 MBR)中接手的引导流程。
bootloader 引导操作系统的流程
不同的 boot loader 引导操作系统流程略有不同,如下所示:
bootloader 引导 Windows
微软的 boot loader 做法是加载分区表(DPT)中标记为活动标志的分区引导记录(PBR),PBR 里的引导代码加载操作系统的引导文件到内存运行。
例如,Windows 的 bootmgr,Windows 的 PBR 可以识别 FAT32 和 NTFS 两种分区,找到分区根目录的 bootmgr 文件,并加载、执行 bootmgr。bootmgr 没有 MBR 和 PBR 的大小限制,可以做更多的事,它会加载并分析BCD启动项存储,而且 bootmgr 可以跨越磁盘读取文件。所以无论我们有几个磁盘,在多少块磁盘上装了 Windows,一个电脑只需要一个 bootmgr 就行了。
bootmgr 会去加载某磁盘某 NTFS 分区的 \Windows\System32\WinLoad.exe
,然后,由 WinLoad.exe 启动 Windows。
上图中,启动分区和系统分区是位于同一个磁盘的同一分区,因为 bootmgr 和 BCD 文件是位于的系统分区的文件,WinLoad.exe 是位于启动分区的文件。启动分区和系统分区也有可能位于同一分区也是可以在不同磁盘的不同分区或者是同一磁盘的不同分区。
如上图所示,系统分区和启动分区可能不是位于同一磁盘同一分区。
bootloader 引导 Linux
Linux 的 boot loader(如:Gurb)则会分阶段加载,直接查找所有分区,加载第一个引导文件 grldr;
GRUB
GNU GRUB(GRand Unified Bootloader,GRUB)是一个非常强大的引导加载程序,它可以加载各种免费操作系统,以及
对于使用 BIOS 的系统,第一阶段引导装载程序会指导系统载入 GRUB 到内存里,而对于装备了 UEFI 的系统来说,则直接从 EFI 系统分区里读取。
GNU GRUB(GRand Unified Bootloader,GRUB)是一个来自 GNU 项目的多操作系统启动管理器,它允许用户可以在计算机内同时安装有多个操作系统,比如不同版本的Windows和Linux,并在计算机启动时选择希望运行的操作系统。同时,它可以链式加载专有操作系统。
GRUB 的实质是一个 mini os,它拥有 shell,支持 script,支持特定文件系统。GRUB 一直在发展,现在的发行版都用 GRUB2 了,但是基本的启动引导原理是差不多的。
BIOS installation
MBR 分区
PC BIOS 平台传统上使用的分区表格式称为主引导记录 (MBR) 格式,这种格式最多允许四个主分区和附加逻辑分区。使用这种分区表格式,有两种方法安装 GRUB:
-
将
core.img
嵌入到 MBR 和第一个分区之间的区域, -
将
core.img
安装在文件系统中,并且组成它的块列表可以存储在该分区的第一个扇区中。
GPT 分区
一些较新的系统可以使用 GUID 分区表 (GPT) 格式,虽然它被指定为可扩展固件接口 (EFI) 的一部分,但如果系统软件支持它,它也可以在 BIOS 平台上使用。
例如,GRUB 和 GNU/Linux 可以在此配置中使用。
使用这种格式,可以为 GRUB 保留整个分区,称为 BIOS 引导分区,然后,GRUB 可以嵌入到该分区中,而不会有被其他软件覆盖的风险,也不会包含在可能移动其块的文件系统中。
注意,在 GPT 系统上创建 BIOS 引导分区时,应确保其大小至少为 31 KiB。
GRUB 的两种启动方式
GRUB 有两种不同的引导方法:
-
第一种,直接加载操作系统;
-
第二种,链式加载另一个引导加载程序,然后该引导加载程序将实际加载操作系统。
一般来说,前者是更理想的选择,因为我们无需安装或维护其他引导加载程序,并且 GRUB 具有足够的灵活性,可以从任意磁盘或分区加载操作系统;但是,有时需要后者,因为 GRUB 本身并不支持所有现有的操作系统。
如上图所示,GRUB 启动加载器有两个启动项,Linux 启动项是直接加载操作系统的,而 Windows 启动项使用链式加载方式加载 VBR 中的 Windows 启动加载器(BOOTMGR 或者 NTLDR)。同时还需要注意,图中的系统分区和启动分区应该是位于同一分区的,因为启动加载器和操作系统都在一个分区。
BIOS 引导过程总结
传统的 BIOS 比较低级,只读取指定磁盘最前面第一个扇区(MBR)里的代码,MBR 里面的引导代码(BootLoader)如何启动操作系统 BIOS 是一无所知的。
微软的 BootLoader 只是一条跳转语句,跳转到标记为活动分区的 PBR(分区引导记录,类似于主引导记录,位于分区最前面的扇区)执行。
由于 BIOS 并没有具体规定用户的第一个分区(我们平时说的C盘)从哪个位置(相对于 MBR)开始,因此,可以利用 MBR 后面的扇区空间保存更多的引导代码(实现更多的功能),比如, GRUB4DOS 占用 16 个扇区,因此,改变 BootLoader 代码就可以实现多系统的引导,这样的软件也比较多,这里不一一列举了。
因此,MBR 里的引导代码也称为引导的第一阶段,其他扇区的引导代码称为第二阶段,以实现更多功能,比如识别文件系统等。
UEFI 引导操作系统
UEFI基本启动流程(如下图):首先 EFI 初始化,EFI 平台加载,设备驱动与 EFI 应用程序加载,boot manager 启动,OS loader 启动,OS 启动。
UEFI 的启动流程如下:
-
开机后,固化在 ROM 里的 UEFI BIOS 就会被加载到内存运行;
-
UEFI BIOS 将引导 EFI 系统进行运行;
-
在 EFI 系统启动后,GUID 分区表就会被识别,之后 EFI 系统就会通过
*.efi
文件启动 Boot Loader 程序加载操作系统内核; -
在 EFI 系统启动后,GUID 分区表就会被识别,之后 EFI 系统读取全局 NVRAM 变量,启动 Boot Loader 程序(根据启动顺序加载 efi 可执行文件),efi 会加载操作系统内核。
对于分区表格式为 MBR 分区表的磁盘,EFI 系统会先启动 CSM 兼容模式后按传统 BIOS 的步骤加载操作系统的内核,如下图所示:
在 UEFI 安装完操作系统后,Windows 至少使用两个分区,一个分区叫做 ESP(EFI SYSTEM PARTITION) 分区,用于存放启动文件;另一个分区则是 BIOS 下正常的系统分区,不同的是,BIOS 下引导文件是winload.exe,UEFI 下引导文件式 winload.efi,两者都是pecoff格式的,但UEFI用的是各种固件接口,而BIOS使用的是中断。
有时还会有一个 MSR 分区,不过这个分区并不重要,实验可以删除。
默认情况下,UEFI 固件加载的启动文件路径是 EFI\BOOT\bootx64.efi
(或者 bootia32.efi
),而 Windows 会强制写入的启动项则会加载 EFI\MICROSOFT\BOOT\bootmgfw.efi
,虽然这两个文件其实是一模一样的文件,但这样在 BDS 阶段,固件就会自动引导 Windows 启动管理器,从而在多系统的情况下 Windows 能优先启动,Linux 系统引导文件一般是 grubx64.efi
。
UEFI 引导总结
UEFI 之所以比 BIOS 强大,是因为 UEFI 本身已经相当于一个微型操作系统,其带来的便利之处在于:
-
UEFI已具备文件系统的支持,它能够直接读取 FAT 分区中的文件。
-
可开发出直接在 UEFI 下运行的应用程序,这类程序文件通常以 efi 结尾。既然 UEFI 可以直接识别 FAT 分区中的文件,又有可直接在其中运行的应用程序。那么完全可以将 Windows安 装程序做成 efi 类型应用程序,然后把它放到任意 fat 分区中直接运行即可,如此一来安装 Windows 操作系统这件过去看上去稍微有点复杂的事情突然就变非常简单了,就像在 Windows 下打开 QQ 一样简单。
而这些都是 BIOS 做不到的,因为 BIOS 下启动操作系统之前,必须从硬盘上指定扇区读取系统启动代码(包含在主引导记录中),然后从活动分区(只限微软)中引导启动操作系统。对扇区的操作远比不上对分区中文件的操作更直观更简单,所以,在 BIOS 下引导安装 Windows 操作系统,我们不得不使用一些工具对设备进行配置以达到启动要求。而在 UEFI 下,这些统统都不需要,不再需要主引导记录,不再需要活动分区,不需要任何工具,只要复制安装文件到一个 FAT32(主)分区 或 U 盘中,然后从这个分区 或 U 盘启动,安装 Windows 就是这么简单。
BIOS 和 UEFI 的启动过程区别:
-
BIOS 把 MBR (包含 bootloader 引导代码)读出来交给 CPU 执行,引导代码进一步(各家不同)去加载操作系统引导文件,引导文件启动操作系统内核。
-
UEFI 是查找硬盘 FAT 分区里的
EFI\BOOT\bootx64.efi
(或者bootia32.efi
) 文件,启动这个 efi 可执行程序(也叫 UEFI 应用),efi 应用(各家不同)去加载操作系统引导文件,引导文件启动操作系统内核。苹果 macOS 较为特殊,引导与恢复等功能都集成在主板 ROM 里,EFI 分区(即 FAT 分区)只用来升级系统。
引导总结
一般来说,有如下两种引导 + 磁盘分区表组合方式:
-
Legacy BIOS + MBR;
-
UEFI BIOS + GPT。
Legacy BIOS 无法识别 GPT 分区表格式,所以也就没有 LegacyBIOS + GPT 组合方式。
UEFI BIOS 可同时识别 MBR 分区和 GPT 分区,所以,在 UEFI 下,MBR 和 GPT 磁盘都可用于启动操作系统。不过由于微软限制,UEFI 下使用 Windows 安装程序安装操作系统是只能将系统安装在 GPT 磁盘中。
因此,一般先安装 Windows,后安装 Linux,因为 GRUB 能检测到 Window 的引导并自动配置好引导;反过来 Windows 比较霸道会覆盖掉 Linux 的引导,可以通过重装 GRUB 并生成配置 grub.cfg 或者修改BCD 添加 Linux 引导实现多重引导。
GRUB 可以通过 grub-mkconfig 或手动修改 grub.cfg 文件添加 Windows 的引导。
注:UEFI 引导 MBR 要开启 CSM 模式。
参考: