无论是什么计算机或操作系统,标准(“IBM 兼容”)台式 PC 和笔记本电脑都使用以下两种方式之一开机和启动:传统的 BIOS-MBR 方法和较新的 UEFI-GPT 方法。本文总结了传统 BIOS PC 加载操作系统的过程,涵盖了 BIOS、MBR 和引导扇区的基础知识和细节。
文章目录
1 BIOS/MBR 启动过程概述
在下图中,显示了所有标准计算机和操作系统的启动顺序:
引导过程被分解为几个主要组件,每个组件都是一个完全独立的子系统,具有许多不同的选项和变化。每个组件的实现可能因硬件和操作系统而异,但它们遵循的规则和工作过程始终相同。
2 启动过程的四大组成部分
2.1 BIOS
BIOS的代码被固定到PC主板(motherboard),通常存储在所谓的EEPROM中(一种储存的介质),和硬件很相关。BIOS 是与硬件整体连接的最低软件级别,并且是引导加载程序和操作系统内核,可以与硬件通信并控制硬件的接口。通过对 BIOS 的标准化调用(计算机术语中的“中断”),操作系统可以触发 BIOS 读取和写入磁盘并与其他硬件组件交流。
当PC 首次通电时,会发生很多事情。按下电源按钮并触发一个开关,该开关激活电源并将电流从 PSU 引导至主板,并主要通过它给PC 的所有各种组件通电。当每个单独的组件接收到赋予生命的电力时,它就会通电并初始化为初始状态。RAM 和 PSU 是较简单的组件,会作为一系列逻辑电路(AND/NAND 和 OR/NOR 门)的功能。而更复杂的部分(例如显卡)则有自己的微控制器。
2.1.1 POST 过程
一旦 PC 通电,BIOS 就会作为 POST(开机自检(Power-On Self Test))过程的一部分开始工作。它将 PC 的所有不同部分连接在一起,并根据需要在它们之间建立接口,将视频显示设置为接受基本 VGA 并将其显示在屏幕上,初始化存储库并让 CPU 访问所有硬件。它扫描连接硬件的 IO 总线,并识别和映射对已连接到 PC 的硬盘的访问。较新主板上的 BIOS 足够智能,甚至可以识别和识别 USB 设备,例如外部驱动器和 USB 鼠标。
在 POST 过程中,在可能的情况下进行快速测试,经常会发现由不兼容的硬件、断开的设备或故障组件引起的错误。 BIOS 负责各种错误消息,例如“键盘错误或不存在键盘”或有关不匹配/无法识别的内存的警告。此时,BIOS 的大部分工作已完成,几乎可以进入引导过程的下一阶段。
剩下的唯一事情就是运行所谓的“附加 ROM”:某些连接到主板的硬件可能需要用户干预才能完成其初始化,而 BIOS 实际上将整个 PC 的控制权交给了编码到硬件中的软件例程(例如显卡或 RAID 控制器)。它们承担计算机及其显示器的控制权,在 PC 真正完成通电之前进行设置 RAID 阵列或配置显示设置等操作。当它们完成执行时,它们会将计算机的控制权交还给 BIOS,然后 PC 进入基本可用状态并准备开始。
2.1.2 BIOS 启动切换
在配置了 PC 的基本输入和输出设备后,BIOS 现在进入最后阶段。这个阶段用于用户进行单独的配置。可以类比我们开机时,通常会看到一个选项,可以快速按一个键进入 BIOS 设置,可以从中配置硬件设置并控制 PC 的启动方式。如果什么都不选择,BIOS 将开始使用默认设置实际“启动” PC 。
前面我们提到 BIOS 工作的一个重要部分是检测连接的硬盘。因为 BIOS 将从第一个硬盘加载一个非常小的程序到内存,并告诉 CPU 执行它。此时,BIOS将计算机的控制权交给这个硬盘,完成了BIOS自身的使命。这个硬盘驱动器就被称为“启动设备”、“启动盘”或“驱动器 0”,通常可以在 BIOS 设置中选择或设置。
2.2 启动设备/启动盘/驱动器 0
无论 BIOS 配置为从本地硬盘启动还是从可移动 USB 设备启动,切换顺序都是相同的。一旦 BIOS POST(2.1.1) 和 AddOn ROM 程序(2.1.2)完成,BIOS 就会从所选引导设备的硬盘驱动器加载前 512 个字节——这 512 个字节就是通常所说的 MBR—主引导记录。
2.3 主引导记录 (MBR/The Master Boot Record)
MBR 是BIOS-MBR启动方式中,第一个也是最重要的组件。每个硬盘都有一个 MBR,它包含几个重要的信息。
2.3.1 分区表(The Partition Table)
首先也是最重要的,MBR 包含一个叫做分区表的东西,它储存硬盘上的分区索引。(类似我们电脑中的C盘和D盘,两个不同的分区,但可能在同一个硬盘上),也可以称为目录表。对于MBR来说,只能有四个分区,GPT却可以有最多128个。没有MBR,(例如在软盘上),整个磁盘只能包含一个分区,这意味着不能在同一硬盘驱动器上拥有不同文件系统,也就是说无法在该磁盘上同时安装 Linux 和 Windows。如果一个
硬盘分为C,D和E盘,可以在C安装Windows,E上安装Linux。
2.3.2 引导代码(Bootstrap Code)
其次,MBR 还包含一段非常重要的代码,称为“引导代码”。 这 512 字节中的前 440可以包含几乎任何内容——BIOS 将加载它并按原样执行其内容,启动引导加载程序。440 字节非常小。440 字节只是一个古老的 1.44 MiB 软盘容量的 0.3%——几乎不足以容纳任何形式的有用代码——而且太小了,无法做一些像从磁盘调用操作系统内核的任务。
考虑到 MBR 的引导程序代码部分是多么的小,它真正可以服务的唯一有用的目的是从磁盘中查找另一个文件并加载它,以执行实际的引导过程。因此,这个引导代码通常被称为“第一阶段引导加载程序”。“第一阶段引导加载程序”会指向“第二阶段引导加载程序”,根据操作系统不同,“第二阶段引导加载程序”的确切位置不同。
但在 Windows 上,“第一阶段引导加载程序”将在 MBR 的分区表中搜索标记为“活动”的分区,这个活动分区的开头在其起始扇区(也称为“引导扇区”)中包含引导代码的下一部分。在正确创建的 MBR 磁盘上,一次只能将一个分区标记为活动分区。
因此,MBR 中引导程序代码段的工作非常简单:从分区表中查找活动分区,并将该代码加载到内存中,作为引导链中的下一个环节由 CPU 执行。
由于操作系统不同,它实际上可能会查找硬编码分区而不是活动分区(例如始终加载第三个分区的引导扇区),并且分区引导扇区内的引导代码偏移量可能会改变(例如它可能不是分区的前 2 KiB,而是从当前月相的第二倍数开始的第二个 KiB 或 6 KiB)——但基本概念保持不变。
然而,出于遗留兼容性的原因,MBR 几乎总是加载活动分区的第一个扇区,这意味着另一个扇区也只有 512 字节。
2.3.3 引导签名
在 IBM 兼容的 PC(基本上就是所有的电脑)上,512 字节 MBR 的最后两个字节称为 引导签名,BIOS 使用它们来确定所选的引导驱动器(就是MBR所在的这个启动设备/启动盘/驱动器 0)是否实际可引导。在包含有效引导代码的磁盘上,MBR 的最后两个字节应始终为 0x55, 0xAA。
如果 MBR 的最后两个字节分别不等于 0x55 和 0xAA,则 BIOS 将假定磁盘 不是bootable 并且不是有效的引导选项 - 在这种情况下,它将回退到引导顺序列表中的下一个设备(如 BIOS 设置中的配置)。例如,如果 BIOS 中的第一个引导设备设置为 U 盘,第二个是本地硬盘,如果插入了没有正确引导签名的 U 盘,BIOS 将跳过它并继续尝试从本地磁盘加载。如果引导设备列表中没有磁盘具有正确的 0x55 0xAA 引导签名,则 BIOS 将显示错误,例如经常遇到的错误的“无引导设备可用”或“重新引导并选择正确的引导设备”。
2.4 分区引导扇区(The Partition Boot Sector)
如上所述,MBR 中的引导程序代码通常会从活动分区的开头加载一个字节序列。分区的确切布局取决于创建或格式化分区的文件系统,但通常看起来像这样:
同样,根据操作系统和文件系统,分区的确切布局肯定会有所不同。但这与您通常会看到的情况非常接近:
- 单个 JMP(跳转)指令,它是与goto命令等效 的汇编代码。
- 文件系统标头,它将包含特定于文件系统本身的重要信息。
- 另一个引导代码段,包含引导加载程序过程的下一阶段。
- 扇区结束标记,与我们之前在 MBR 中看到的 0x55 0xAA 引导签名非常相似。
这通常都打包到分区的第一个扇区中,该扇区通常也只有 512 字节长,而且不能容纳太多数据或指令。在用于较新操作系统的现代文件系统上,引导代码可以利用增强的 BIOS 功能来读取和执行超过 512 个字节的内容,但在所有情况下,基本步骤保持不变: - MBR 将活动分区的前 512 字节加载到内存中,并指示 CPU 执行它们。
分区引导扇区的前(三个)字节包含一条 JMP 指令,告诉 CPU 跳过 xx 个字节,并从那里执行引导加载程序的下一阶段。 - CPU 遵循 JMP 指令并寻找包含在分区引导扇区中的引导代码的开头,并开始执行。
分区中的引导代码不是道路的尽头,它只是前进的另一步。由于在分区引导扇区中为引导代码分配的空间很少,它包含的代码通常以另一个 JMP 命令结束,该命令指示 CPU 跳转到 分区中的 下一个扇区,该扇区通常为分区的其余部分留出代码。根据文件系统的不同,这可以是几个扇区的长度,或者需要多长才能适应引导加载程序的这个阶段。
2.4.1 第二阶段引导加载程序
引导加载程序的第二阶段,存储在引导程序部分的分区引导扇区中,并且可以选择继续超越它,执行引导加载程序过程的下一步:它查找存储在分区本身上的文件(作为常规文件) ,并告诉 CPU 执行其内容以开始引导过程的最后部分。
与之前的 MBR 和分区引导扇区的引导段不同,引导过程的下一步不是存储在分区内的专用偏移量处(即引导代码不能只是告诉 CPU 到 JMP 到位置 0xABC 并执行引导文件)——它是一个普通文件,存储在磁盘文件系统中的其他普通文件中。
这个明显更复杂的引导程序代码实际上必须读取分区上文件系统的目录,7来自旧版本文件系统的第二阶段引导加载程序通常对它们需要加载的引导加载程序文件施加复杂的限制,例如要求它们出现在分区的前几个 KB 中,或者无法在分区上加载非连续分配的文件。该文件是引导加载程序拼图的最后一部分,通常对其大小或内容没有限制,这意味着它可以像从磁盘加载操作系统内核并传递所需的那样大和复杂将 PC 控制到 OS。
2.5 引导加载程序(bootloader)
磁盘上的实际引导加载程序文件构成引导加载过程的最后部分。当人们谈论引导加载程序和引导文件时,他们通常指的是引导过程的最后一个关键步骤。
- 引导加载程序序列
- 一旦 PC 的控制权从 BIOS 移交给 MBR 中的引导程序代码,
- 从 MBR 移交给分区引导扇区中的引导程序代码,
- 并从那里移交给活动分区上的可执行引导文件,实际逻辑涉及确定要加载哪个操作系统、从哪里加载它、传递给它的参数/选项以及完成可能可用的与用户的任何交互,启动操作系统的实际过程就开始了。
2.5.1 引导配置文件
虽然可执行引导加载程序文件理论上可以包含与要从磁盘加载的操作系统有关的硬编码信息,但这根本不是很有用。因此,几乎所有引导加载程序都将实际的、可执行的引导加载程序与包含要加载的操作系统信息的配置文件或数据库分开。下面提到的所有主要引导加载程序都支持加载多个操作系统,这一过程称为“双引导”或“多重引导”。
2.5.2 流行的引导加载程序
如前所述,有许多不同的引导加载程序。每个操作系统都有自己的引导加载程序,专门设计用于读取其文件系统并定位需要加载以便操作系统运行的内核。以下是一些常见操作系统的一些更流行的引导加载程序及其基本配置文件:
NTLDR 引导程序 GRUB
每个流行的操作系统都有自己的默认引导加载程序。Windows NT、2000 和 XP 以及 Windows Server 2000 和 Windows Server 2003 使用 NTLDR 引导加载程序。Windows Vista 引入了 BOOTMGR 引导加载程序,目前由 Windows Vista、7、8 和 10 以及 Windows Server 2008 和 2012 使用。虽然多年来 Linux 已经存在许多不同的引导加载程序,但两个主要的引导加载程序是 Lilo 和GRUB,但现在大多数 Linux 发行版都结合了全能的 GRUB2 引导加载程序。
NTLDR
NTLDR 是旧的 Windows 引导加载程序,最初用于 Windows NT(因此“NTLDR”中的“NT”,“NT Loader”的缩写),目前用于 Windows NT、Windows 2000、Windows XP 和 Windows Server 2003。
NTLDR 将其引导配置存储在一个名为 BOOT.INI 的基于文本的简单文件中,该文件存储在活动分区的根目录中(通常为 C:\Boot.ini)。一旦第二阶段引导加载程序加载并执行 NTLDR,它就会执行一个名为 NTDETECT.COM 的帮助程序,该程序可识别硬件并生成有关系统的信息索引。有关 NTLDR、BOOT.INI 和 NTDETECT.COM 的更多信息,请参见我们知识库中的链接文章。
BOOTMGR
BOOTMGR 是 Microsoft Windows 使用的较新版本的引导加载程序,它首先在 Windows Vista 的测试版(然后是 Windows Codename Longhorn)中引入。它目前用于 Windows Vista、Windows 7、Windows 8、Windows 8.1 和 Windows 10,以及 Windows Server 2008 和 Windows Server 2012。
BOOTMGR 标志着与 NTLDR 的显着背离。它是一个独立的引导加载程序,具有更多选项,专门设计用于与现代操作系统中的新功能兼容,并在设计时考虑了 EFI 和 GPT(尽管只有某些版本的 BOOTMGR 支持从 GPT 磁盘或 UEFI 中加载 Windows /EFI 配置)。与 NTLDR 不同,BOOTMGR 将其配置存储在一个名为 BCD 的文件中——Boot Configuration Database 的缩写。与 BOOT.INI 不同,BCD 文件是一个二进制数据库,无法手动打开和编辑。8相反,必须使用专门设计的命令行工具(如 bcdedit.exe)和更用户友好的 GUI 实用程序(如EasyBCD) 来读取和修改操作系统列表。
格鲁布
GRUB 是 1990 年代和 2000 年代初期主要用于 Linux 的引导加载程序,其设计不仅可以加载 Linux,还可以加载为其内核实现开放式多重引导规范的任何操作系统。包含空白格式的操作系统列表的 GRUB 配置文件通常称为 menu.lst 或 grub.lst,可在 /boot/ 或 /boot/grub/ 目录下找到。由于可以通过使用不同选项重新编译 GRUB 来更改这些值,因此不同的 Linux 发行版在不同的目录中以不同的名称放置此文件。
GRUB 2
虽然 GRUB 最终战胜了 Lilo 和 eLilo,但在 2002 年左右被 GRUB 2 取代,旧的 GRUB 正式更名为“Legacy GRUB”。令人困惑的是,GRUB 2 现在正式称为 GRUB,而旧的 GRUB 已正式降级为“Legacy GRUB”,但幸运的是,您会在网上找到大多数将 GRUB 引导加载程序的新版本称为 GRUB 2 的资源。
GRUB 2 是一个功能强大的模块化引导加载程序,更类似于操作系统而不是引导加载程序。它可以加载数十种不同的操作系统,并支持自定义插件(“模块”)以引入更多功能并支持复杂的启动程序。
GRUB 2 的实际引导加载程序文件不是名为 GRUB2 的文件,而是通常名为core.img的文件。与 Legacy GRUB 不同,GRUB 2 配置文件更像是一个脚本,而不是传统的配置文件。grub.cfg 文件通常位于引导分区上的 /boot/grub/grub.cfg,与 shell 脚本相似,并支持函数等高级概念。GRUB 2 的核心功能由模块补充,这些模块通常位于 /boot/grub/ 目录的子目录中。
3 引导过程
如前所述,引导过程的阶段比前面的步骤要复杂一些,主要是由于读取文件系统的额外复杂性。引导加载程序还必须获取有关底层机器硬件的信息(通过 BIOS 或自己获取),以便从正确的分区正确加载所需的操作系统并提供可能需要的任何其他文件或数据。它还必须从存储在引导分区的文件系统上的常规文件中读取自己的配置文件,因此它至少需要对其驻留的任何文件系统具有完整的读取支持。
引导加载程序流程图
启动文件系统访问
在其他事情发生之前,当引导加载程序第一次运行时,它必须加载并运行原始文件系统“驱动程序”,使其至少能够读取它所在的文件系统。由于在此之前无法读取文件系统,因此必须将提供此功能的代码编译到核心引导加载程序文件本身中。
加载和读取配置文件
通过支持加载的文件系统,引导加载程序现在可以从磁盘读取操作系统列表以及指定多个操作系统的事件,准备显示。
加载和运行支持模块
对于不是完全独立的引导加载程序(例如 NTLDR 和 GRUB 2),引导加载程序现在从磁盘加载任何支持模块或帮助程序(例如 NTDETECT.COM)。要加载的模块列表可以在刚刚读取或硬编码/编译到引导加载程序本身的配置文件中指定。通常,每个模块都会在它被定位并从磁盘加载时执行。
显示引导菜单
此时,所有相关配置都已准备就绪,引导加载程序可以在屏幕上显示通常所说的引导菜单。如果安装了多个操作系统,则计算机用户可以通过引导菜单浏览操作系统列表并选择要加载的操作系统。从这里开始,某些引导加载程序还可以指定运行时选项,例如是否以安全模式加载选定的操作系统。
加载操作系统内核
一旦记录了用户的选择,引导加载程序就会进入引导过程的最后阶段。根据操作系统和内核类型,引导加载程序将从配置文件中指定的路径(在任何子模块的帮助下,如果需要)加载内核映像到内存中。然后它指示 CPU JMP 到新加载的内核中的某个位置并从那里开始执行。
4 结论
这样就结束了从按下按钮开始到操作系统内核加载到内存并执行的漫长旅程。引导加载程序过程肯定比大多数人意识到的要微妙和复杂得多,而且它的设计和发展都以相当标准化的方式跨不同平台和各种操作系统工作。
引导加载程序的各个组件大体上是自给自足的。它们可以单独换出而不会影响整体,这意味着您可以添加磁盘并从不同的设备启动,而不必担心扰乱现有的配置和操作系统。这也意味着,您不再需要一个硬件/软件来配置、设置、维护和调试,而是留下一个复杂且通常非常脆弱的链条,其中有多个容易损坏和故障的点。
正常工作时,启动过程是一台运行良好的机器,但是当灾难发生时,它可能是一个非常难以理解和调试的过程。
5 引导加载程序故障排除
启动过程的复杂性意味着需要设置和配置很多东西,还有很多可能会出错。下面列出了对引导加载程序进行故障排除时可以派上用场的一些资源:
适用于 Windows 的 Easy Recovery Essentials:点击式可启动恢复 CD,它将重新创建整个上述启动链,无论出现什么问题,都可以让您几乎回到 Windows。
EasyBCD:一个易于使用的实用程序,允许您在 Windows、Linux、Mac、FreeBSD 等之间设置和配置双引导或多引导。
超级 GRUB2 磁盘:一个可引导的 GRUB2 磁盘,当您的 GRUB 或 GRUB2 配置错误或出现故障时,可用于引导至 Linux。
也可以看看
我们 wiki 和其他在线网站中的这些附加文章和资源包含与此主题相关的附加信息:
EFI/GPT 引导过程:本文档涵盖了 BIOS/MBR 引导过程的基础知识,现在阅读并了解具有 UEFI 和 GPT 的较新 PC 如何引导。
EFI/GPT和BIOS/MBR的区别
6 补充 提出修改意见
最初,BIOS 存储在所谓的 ROM(“只读存储器”)芯片上:BIOS 代码被硬编码到芯片中,永远无法更改。对 BIOS 的更新很少见,而且只能通过物理更换主板上的 BIOS 芯片来完成。随着时间的推移和更好的技术,可擦除 ROM 芯片被开发出来,可以通过将它们放在一个盒子里并用一定剂量的紫外线(紫外线)辐射来清除它们,然后用 ROM 芯片编程硬件重新编程它们的内容。当它变得陈旧和累人时,开发了电可擦除可编程 ROM(简称 EEPROM)——有了它,EEPROM 芯片的特殊选择引脚上的电子信号将触发擦除,芯片可以直接从它的位置进行编程位于主板上。简单的柠檬汁, ↩
现在几乎每个主要的硬件组件都将固件控制在其逻辑硬件中,但我们在这里忽略了微控制器固件。 ↩
根据操作系统和平台的不同,引导代码实际上可能只有 434 到 446 字节,因为该区域的一部分可能会留出用于其他目的,例如磁盘签名和磁盘时间戳。在大多数现代操作系统上,440 是上限,因为最后 6 个字节是为偏移量 0x01B8 处的 4 字节磁盘签名和指示偏移量 0x01BC 处的驱动器读写状态的 2 字节字段(0x00指示读写和 0x5A5A 指示只读驱动器)。 ↩
这里有一个巨大的警告:可引导/活动标志实际上是单个(四个之一)分区记录的属性,而不是分区表(分区记录列表)或 MBR 本身。这意味着从 技术上讲 ,指示分区可引导的实际位实际上可以同时存在(设置为值 0x80)一个以上(或全部!)个分区!这是一个无效的配置,但可能会导致许多不同的启动问题! ↩
在像所有 x86 CPU 一样的小端机器上,这将是单个字 0xAA55,而在像 PowerPC 这样的大端架构上,它将被读取和写入 0x55AA。 ↩
汇编是最原始的编程语言,由 CPU 直接读取和执行的单个指令组成。 ↩
在 NTFS 上,这称为主文件表,简称 MFT。在 FAT32 上,这称为 FAT(文件分配表)。 ↩
事实上,BCD 文件是一个标准的 Windows 注册表配置单元,可以安装它以使用诸如 regedit.exe 之类的工具进行编辑。 ↩
互相交流
读者你好!如果你对本文内容感兴趣,我十分希望能够和你互相学习,可以扫码和我联系!一起进步