BIOS 与 UEFI引导流程

1 基础知识

1.1 引导程序(boot loader)

1.1.1 概念 [1]

引导装载程序(英语:boot loader)是计算机开机自检完成后装载操作系统或者其他系统软件的计算机程序。自检完成后运行引导装载程序,然后再加载并运行软件。引导装载程序可以从硬盘装载到主内存中。

在MBR磁盘分区中引导程序位于主引导记录(MBR)。但是随着计算机操作系统越来越复杂,位于主引导记录的空间已经放不下引导操作系统的代码,于是就有了第二阶段的引导程序,而MBR中代码的功能也从直接引导操作系统变为了引导第二阶段的引导程序。因此引导程序通常分为两部分:第一阶段引导程序位于主引导记录(MBR),用以引导位于某个分区上的第二阶段引导程序,如NTLDR、BOOTMGR和GNU GRUB等。

对于UEFI系统,由EFI应用程序(即EFI系统分区中的.efi文件)取代MBR和第二阶段引导程序,UEFI固件会加载引导程序的.efi文件,再由引导程序加载操作系统。

1.1.2 BOOTMGR安装

在MBR磁盘分区安装Windows时,Windows会覆盖MBR分区和其所在的分区。你没有办法保留之前MBR中对Linux引导程序的指向。

1.1.3 GRUB安装

在MBR磁盘分区有两种安装GRUB的方法:两种方法的启动镜像(即boot.img,用于加载后续内容)都是放在MBR中的,GRUB的核心镜像(即core.img,GRUB的核心部分)可以将其嵌入MBR和第一个分区之间的区域(英文叫做“boot track”、 “MBR gap”或者“embedding area”,通常至少为31 KiB),也可以将其安装在存放分区的第一个扇区中(VBR)[2],[3],[4]

GRUB在MBR和UEFI的安装

在BIOS/GPT启动时,GRUB会被安装在BIOS BOOT分区,参见[5]

1.2 磁盘分区 [6]

1.2.1 主分区

实际上在早期的硬盘分区中并没有主分区、扩展分区和逻辑分区的概念,每个分区的类型都是主分区。由于硬盘仅仅为分区表保留了64个字节的存储空间,而每个分区的参数占据16个字节,故主引导扇区中总计只能存储4个分区的数据。也就是说,一块物理硬盘只能划分为4个逻辑磁盘。在具体的应用中,4个逻辑磁盘往往不能满足实际需求。为了建立更多的逻辑磁盘供操作系统使用,引入了扩展分区和逻辑分区,并把原来的分区类型称为主分区。

1.2.2 拓展分区

上面说了,4个分区显然不能满足需求,但是物理硬件限制只能有4个分区怎么办呢?所以操作系统开始出马了,把其中一个主分区命名为扩展分区,记住只是命名哦,原则上扩展分区和主分区是一样的,只不过功能不同。下面说完逻辑分区,你就懂我在说什么了。

1.2.3 逻辑分区

4个分区肯定不够,我想要20个分区,怎么办呢?把其中一个主分区变成扩展分区,然后在这个扩展分区上进行切割,变成一个个D盘,E盘,F盘什么的,但是这些盘综合起来就是一个扩展分区,这些盘是相互链接的,并不像主分区那样,4个之间相互独立互不干扰。逻辑分区用链表进行链接,如果E盘中的分区信息丢掉,操作系统就找不到F盘了。

MBR拓展分区

1.2.4 启动分区

存放操作系统文件的的分区,比如你装了2个系统:Windows 7 + Linux那么你就2个启动分区。装的是Windows的话就看Windows目录(System32目录)存放在那个区,哪个区就是你的启动分区,默认装C盘,你也可以装F盘等。装的是Linux的话就看/分区装在哪,哪就是启动分区。

1.2.5 系统分区

存放第二阶段引导程序(如NTLDR、BOOTMGR和GNU GRUB等)的分区,Windows通常装在C盘,Linux通常装载/boot分区

1.2.6 活动分区

活动分区是主分区,活动分区是系统分区,每次PC启动时,一块硬盘只能有一个活动分区,如果要启动Windows就将Windows的系统分区设为活动分区,计算机就会去那里装载引导程序(NTLDR、BOOTMGR和GRUB等)并执行,如果要启动Linux就将Linux的系统分区设为活动分区。

注:系统分区就是保存各种引导文件的分区(也叫引导分区),启动分区则是指保存Windows目录的分区。系统分区和启动分区可以在同一个分区,也可以不在同一个分区。

1.3 VBR(PBR)

VBR(也称作PBR)是IBM个人计算机引入的一种启动扇区。它可以在分区数据存储设备(例如硬盘)或未分区设备(例如软盘)上找到,并且包含用于引导存储在计算机其他部分中的程序(通常但不一定是操作系统,例如GRUB、BOOTMGR等)的机器代码。在非分区存储设备上,它是设备的第一个扇区。在分区的设备上,它是设备上单个分区的第一个扇区,整个设备的第一个扇区是包含分区表的主启动记录(MBR)[7],[8]

MBR

  • MBR:主引导记录位置在磁盘的第一个逻辑扇区,即LBA0的位置。一个逻辑扇区仅有512B(字节) ,MBR引导代码占446B,MBR分区表占64B,最后的magic number占2B(即上述以0x55 0xAA结尾的标识符)。因为每个分区只有16B大小的分区表记录,所以寻址最大只能到2.2TB,并且由于分区表总共只占64B,所以MBR分区表最多4个分区。上图的绿色部分。
  • PBR:即Partition Boot Record,对应主引导记录,每个分区都存在引导记录,位置在每个磁盘分区的开始部分,占用扇区不定。这个扇区一般保存着操作系统引导程序的所在位置。上图的红色部分。
  • File System:操作系统对磁盘的所有操作都需要经过文件系统,删除文件指的是在文件系统里删除文件的索引条目,创建文件就是在在文件系统里添加索引条目并将具体数据写入磁盘。常见的文件系统格式有:FAT、ext4、NTFS。文件系统位置一般在PBR之后。上图黄色部分。

1.4 链式加载

ChainLoading的意思是用当前的启动加载器去载入另一个启动加载器,所以叫做链式加载[9]

要被加载的另一个启动加载器可能嵌入在一个有分区表的磁盘的头部 (MBR),或在一个未分区磁盘或者一个分区的头部 (VBR),也可能在使用 UEFI 的情形下是一个 EFI 可执行文件 [9]

例如,GRUB可以通过链式加载的方法加载放在VBR中的BOOTMGR的引导程序进而运行BOOTMGR,也可以在UEFI模式下链式加载Windows和Linux的启动加载器。

Invoking a VBR via a boot manager is known as chain loading. Some dual-boot systems, such as NTLDR (the boot loader for all releases of Microsoft's Windows NT-derived operating systems up to and including Windows XP and Windows Server 2003), take copies of the bootstrap code that individual operating systems install into a single partition's VBR and store them in disc files, loading the relevant VBR content from file after the boot loader has asked the user which operating system to bootstrap. In Windows Vista, Windows Server 2008 and newer versions, NTLDR was replaced; the boot-loader functionality is instead provided by two new components: WINLOAD.EXE and the Windows Boot Manager [7].

1.5 GRUB的两种启动方式

GRUB有两种不同的引导方法。 两者之一是直接加载操作系统,另一个是链式加载另一个引导加载程序,然后该引导加载程序将实际加载操作系统。 一般来说,前者是更理想的选择,因为您无需安装或维护其他引导加载程序,并且GRUB具有足够的灵活性,可以从任意磁盘/分区加载操作系统。 但是,有时需要后者,因为GRUB本身并不支持所有现有的操作系统 [2]

GRUB的两种启动方式

如上图中,GRUB启动加载器有两个启动项,Linux启动项是直接加载操作系统的,而Windows启动项使用链式加载方式加载VBR中的Windows启动加载器(BOOTMGR或者NTLDR)。同时还需要注意,图中的系统分区和启动分区应该是位于同一分区的,因为启动加载器和操作系统都在一个分区。

1.6 组合方式

一般来说,有如下两种引导+磁盘分区表组合方式:LegacyBIOS+MBR和UEFI BIOS+GPT

Legacy BIOS无法识别GPT分区表格式,所以也就没有LegacyBIOS+GPT组合方式;
UEFI BIOS可同时识别MBR分区和GPT分区,所以UEFI下,MBR和GPT磁盘都可用于启动操作系统。不过由于微软限制,UEFI下使用Windows安装程序安装操作系统是只能将系统安装在GPT磁盘中。

注:UEFI引导MBR要开启CSM模式百度百科

2 BIOS引导流程[3],[10]

开机后,固化在ROM里的BIOS就会被加载到内存运行,BIOS自检完毕以后加载COMS的参数,通过COMS的参数,BIOS程序加载启动磁盘的MBR到内存里运行,运行MBR的引导代码,这段代码会查找活动分区DPT(BIOS不认识活动分区,但这段代码认识活动分区)的位置,加载并执行活动分区的PBR(另一段引导程序),与MBR类似,PBR在运行后加载操作系统的引导程序到内存运行,例如Windows的BOOTMGR或Linux的GRUB。当引导程序运行后,操作系统内核就被加载运行,完成从BIOS程序中接手的引导流程,整体流程如下图:

BIOS加载流程

Windows的PBR认识FAT32和NTFS两种分区,找到分区根目录的bootmgr文件,加载、执行bootmgr

bootmgr没了MBR和PBR的大小限制,可以做更多的事。它会加载并分析BCD启动项存储。而且bootmgr可以跨越磁盘读取文件了。所以无论你有几个磁盘,你在多少块磁盘上装了Windows,一个电脑只需要一个bootmgr就行了。bootmgr会去加载某磁盘某NTFS分区的\Windows\System32\WinLoad.exe,后面启动Windows的事就由WinLoad.exe来完成了。

Windows 7 操作系统启动流程

上图中,启动分区和系统分区是位于同一个磁盘的同一分区,因为bootmgrBCD文件是位于的系统分区的文件,WinLoad.exe是位于启动分区的文件。启动分区和系统分区也有可能位于同一分区也是可以在不同磁盘的不同分区或者是同一磁盘的不同分区。

Windows 启动流程

上图中的虚线就很好的说明了系统分区和启动分区可能不是位于同一磁盘同一分区,因为两个分区之前用虚线隔开了。

3 UEFI引导流程[10],[11]

UEFI的启动要经过多个阶段[12],[13],[14],本文主要对DXE这一阶段进行介绍。

系统想要使用一个设备就必须要有对应的驱动。UEFI作为一个模糊了固件和操作系统界限的东西,作为一个设计之初就考虑到了扩展性的东西,它也是有驱动程序的。启动过程中的DXE阶段,全称叫Driver eXecution Environment,就是加载驱动用的。

UEFI启动后,进入了DXE阶段,就开始加载设备驱动,然后UEFI就会有设备列表了。

对于其中的磁盘,UEFI会加载对应的驱动解析其中的分区表(GPT和MBR)。然后UEFI就会有所有分区的列表了。然后UEFI就会用内置的文件系统驱动,解析每个分区。然后UEFI就会认识分区里的文件。

在启动操作系统的阶段,根据设置的启动项顺序,转到相应设备(仅限GPT设备,如果启动传统MBR设备,则需要打开CSM支持)的引导项,引导并进入操作系统。

启动项分为两种:

  • 文件启动项:大约记录的是某个磁盘的某个分区的某个路径下的某个文件。对于文件启动项,固件会直接加载这个EFI文件,并执行。类似于DOS下你敲了个win.com就执行了Windows 3.2/95/98的启动。文件不存在则失败。
  • 设备启动项:大约记录的就是“某个U盘”、“某个硬盘”。(此处只讨论U盘、硬盘)对于设备启动项,UEFI标准规定了默认的路径\EFI\Boot\bootX64.efi。UEFI会加载磁盘上的这个文件。文件不存在则失败。

作为UEFI标准里,钦定的文件系统,FAT32.efi是每个主板都会带的。所有UEFI的主板都认识FAT32分区。这就是UEFI的Windows安装盘为啥非得是FAT32的。

至于这个EFI文件会干嘛,主板是不管的。
但是随着Windows 8.x,以及UEFI标准2.x,推出了一个叫做SecureBoot的功能。开了SecureBoot之后,主板会验证即将加载的efi文件的签名,如果开发者不是受信任的开发者,就会拒绝加载。

根据前文说的,UEFI启动项分为文件启动项和设备启动项。

通常情况:主板UEFI初始化,然后找到了默认启动项Windows Boot Manager。里面写了bootmgfw.efi的位置。固件加载bootmgfw.efibootmgfw.efi根据BCD启动项存储,找到装Windows的磁盘的具体分区,加载其中的WinLoad.efi。由WinLoad.efi完成剩下的启动工作。

Windows UEFI启动流程

其中的虚线,跟上面的一样,意思是,Windows启动盘和EFI启动盘,可以是一个硬盘,也可以是不同的硬盘。所以对于UEFI来说,启动盘是bootmgfw.efi所在的那个盘。

4 为Boot loader添加系统引导[15]

一般先安装 Windows,后装 Linux,因为GRUB能检测到Window是的引导并自动配置好引导,反过来Windows比较霸道会覆盖掉Linux的引导,可以通过重装GRUB并生成配置grub.cfg或者修改BCD添加Linux引导实现多重引导。

GRUB可以通过grub-mkconfig或手动修改grub.cfg文件添加Windows的引导。(推荐)

Bootmgr同样可以通过EasyBCD或者BOOTICE等软件修改BCD文件,添加GRUB引导,详见[16]。(UEFI没添加成功,不太推荐)

参考文献

  1. 引导程序 - Wiki
  2. GNU GRUB Manual 2.04
  3. 聊聊 BIOS、UEFI、MBR、GPT、GRUB…… - 个人博客
  4. linux的/boot和grub和MBR和boot sector是什么关系? - js li的回答
  5. BIOS UEFI MBR GPT GRUB - 个人博客
  6. 从系统盘符选错到认识硬盘的各种分区 - 博客园
  7. Volume boot record - Wiki
  8. Partition Boot Record (PBR)
  9. GRUB (简体中文) - ArchWiki
  10. 科普贴:BIOS和UEFI的启动项 - 知乎专栏
  11. 电脑基础知识普及:BIOS、EFI与UEFI详解! - 知乎专栏
  12. UEFI启动流程 - 博客园
  13. (转)UEFI系统的启动过程 - CSDN
  14. 两图看懂BIOS和UEFI启动过程 - 每日头条
  15. 多操作系统安装与引导原理(Windows、Deepin) - github.io
  16. 如何将Linux添加到新的Windows 8启动管理器中?
 
posted @ 2020-07-10 16:47  pipci  阅读(6013)  评论(0编辑  收藏  举报