申明:本文只是在阅读国内文章基础上整理而来,并不深入,也不专业,请务必带着怀疑态度来阅读本文,并希望得到您的建议和指正。
前言:
电脑(现代计算机)的整个启动过程可以概括为:
- 计算机通电。
- CPU读取保存在主板上ROM芯片里的BIOS或UEFI程序(BootLoader)。
- 该程序加载指定启动介质(包括从网络启动,但一般为本地硬盘),并从该介质启动操作系统。
为便于理解启动过程,有必要先了解一些相关的名词,如主板固件类型(第一节),硬盘分区方式(第二节),然后在前两节的基础上简单了解操作系统是如何被引导启动的,以及多系统引导的管理(该节尚未完成)。
目录:
- 一、主板固件(BIOS与UEFI)
- 二、硬盘分区结构(MBR与GPT)
- 三、操作系统的引导过程
- 四、多系统引导的管理(未完成)
一、主板固件(BIOS与UEFI)
可以把UEFI 和 BIOS都理解成一种固件(即Firmware,固化在特定芯片里的程序,是硬件设备最底层的软件),其主要功能是为计算机提供最底层的、最直接的硬件设置和控制(当然包括启动操作系统)。而UEFI是传统BIOS升级替代品,功能更强,并兼容传统BIOS。
1.什么是BIOS
1.1 BIOS产生:
由于计算机启动是一个很矛盾的过程,即必须先运行程序,然后计算机才能启动,但是计算机不启动就无法运行程序!因此需要想法把一小段程序装进内存,然后计算机才能正常运行,这段程序称为BIOS(基本输入输出系统),保存在计算机主板上的一个芯片里(称为BIOS ROM),如下图。
通常BIOS会被认为是随着IBM PC(大名鼎鼎的商用电脑)的出现而产生的,实际上BIOS要早于IBM PC,早在1975年,BIOS的概念就在CP/M系统上出现。后来随着计算机硬件的发展,除了上面提到的主板BIOS(也叫系统BIOS)以外,其他硬件也有了BIOS程序(固件),如显卡BIOS,硬盘BIOS等,但我们一般提到的BIOS固件专门指主板ROM芯片里的BIOS程序(即系统BIOS)。
1.2 BIOS功能:
- 检测硬件,又叫POST,就是看看你的硬件是否还正常的工作。
- 初始化硬件,设置其基本状态,使得整个计算机达到所谓的"可用状态"(Ready State)。
- 启动OS Loader加载操作系统。
BIOS固定地加载存储器最前面扇区(LBA0)里的引导代码(即BootLoader),然后由BootLoader启动操作系统。
- 在操作系统启动起来以后,一部分继续驻留内存,向操作系统以及其他软件提供基本的系统级的服务,如磁盘读写(INT13中断服务)等。
- 修复硬件缺陷,如Intel CPU的SMM功能。
1.3 BIOS启动过程
- 通电:CPU初始化,并执行BIOS程序。
- 自检:BIOS程序启动开始POST自检(此阶段无法屏幕显示,只能通过主板扬声器报警),进行更完整的硬件(检查CPU/RAM/键盘/鼠标等)检测。
- 其他初始化:初始化显卡和其他设备并显示到屏幕。
- 加载MBR:BIOS提供中断服务,读取CMOS设置,读取第一个启动磁盘的MBR到内存让CPU执行(此后BIOS就撒手不管了),然后由MBR引导代码启动操作系统。
2.什么是(U)EFI
2.1 产生:
由于BIOS各种缺点(不支持2.2TB硬盘作为启动盘,安全与扩展性差等),英特尔公司从2000年开始,发明了可扩展固件接口(Extensible Firmware Interface),用以规范BIOS的开发。而支持EFI规范的BIOS也被称为EFI BIOS。之后为了推广EFI,业界多家著名公司共同成立了统一可扩展固件接口论坛(UEFI Forum),英特尔公司将EFI 1.1规范贡献给业界,用以制订新的国际标准UEFI规范。
UEFI是一种规范,不同厂商根据该规范对UEFI的实现并烧录到芯片里,该实现程序就称为UEFI固件(固件的英文为Firmware,可理解为固化在特定芯片里的软件程序,是硬件设备最底层的软件)。
2.2 (U)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的简单命令行界面,可在此界面做简单维护和诊断。
3.启用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两种分区方式。
1.什么是MBR:
1.1 含义
MBR磁盘分区是一种使用广泛的分区结构,它也被称为DOS分区结构(什么?感觉它与微软有关?是的),但它并不仅仅应用于Windows系统平台,也应用于Linux,基于X86的UNIX等系统平台。最早在1983年在IBM PC DOS 2.0中提出(微软最早与IBM合作的操作系统,但更早期的Unix系统没有这个概念,更多需要阅读操作系统发展简史)。它是存在于驱动器开始部分的一个特殊的启动扇区,磁盘的第一个扇区。这个扇区包含了已安装的操作系统的BootLoader和驱动器的分区信息。
注:'MBR'与'MBR分区结构'的区别:前者(狭义)专指主引导记录(磁盘第一扇区),后者(广义)是整个硬盘的组成结构(包括主引导记录扇区与其他扇区)。
1.2 结构
广义的MBR包含整个扇区(引导程序、分区表及分隔标识,即下图红色部分),狭义的MBR仅指引导程序(bootloader),这里统一按广义MBR的定义进行讨论。
①主引导代码(BootLoader):占446字节,由操作系统或特殊工具写入。
②硬盘分区表DPT:占64字节,用16字节表示一个分区信息(其中),因此只能容纳4个分区。后来随着磁盘空间越来越大,又发明了扩展分区和逻辑分区(为区分把原来的普通分区改称为主分区了)。
③结束标志:占MBR扇区最后2个字节,一直为"55 AA"(也称幻数Magic Number),表示该磁盘可启动。
注:引导代码(也叫魔术代码、神奇代码)种类较多这里不展开讨论,在第三节'操作系统的启动'会再次提起bootloader。
1.3 关于MBR分区结构的小疑问
- MBR:磁盘第一个扇区的别名。
- PBR:分区里第一个扇区的别名。
- 磁盘为什么要分区?与磁盘的发展有关(很久以前就一个分区或没有分区的概念),更方便使用和管理磁盘吧。
- 为什么要定义MBR?启动操作系统。
- 为什么要定义PBR?由于MBR空间有限无法完成引导操作系统的工作。
- 引导代码为什么这么神奇?使用汇编语言编写,直接操作底层硬件的代码程序。
- 为什么存在多种引导代码?底层硬件不同,操作系统不同。
- BIOS怎么知道MBR的地址?有一个硬件中断INT13会告诉BIOS外设的MBR地址。
- 如何知道我的硬盘/U盘/光盘上有没有安装操作系统?
- 为什么一个分区只能安装一个操作系统?安装操作系统时会向分区引导记录PBR写入引导代码,不同的操作系统会相互覆盖。
2.什么是GPT
2.1 含义
GUID分区表简称GPT,使用GUID分区表的磁盘称为GPT磁盘,是源自EFI标准的一种较新的磁盘分区表结构的标准。相对于MBR更为先进,因为GPT分区表头可自定义分区数量(而MBR最大4个)并且支持2TB以上的磁盘空间,在Windows系统中微软限定GPT最大128个分区。GPT分区结构只能被支持UEFI的计算机识别(BIOS无法识别)。
2.2 结构
- 保护MBR
在GPT分区表的最开头,处于兼容性考虑仍然存储了一份传统的MBR(LBA0),这个MBR叫做保护性MBR(Protective MBR)。由分区表和结束标志组成,没有引导代码。而且分区表内只有一个分区表项(标识为EE),MBR工具无法识别和操作(从而起到保护作用),GPT工具则不使用它。 - GPT头
起始于磁盘的LBA1,通常也只占用这个单一扇区。其作用是定义分区表的位置和大小。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所表示的一个逻辑块就是2KB的空间。 为了方便,我们后面仍然将逻辑块称为扇区。
2.3 关于GPT分区结构的小疑问
- MBR与GPT区别:支持的最大空间(2T),分区数(4主分区),安全性与扩展性。
- 如何选择:GPT需要UEFI支持,如果电脑主板固件是UEFI类型肯定优先选择GPT分区结构。
-
支持UEFI的操作系统:Linux(2000年开始)。Apple从 Mac OS X 10.4(代号Tiger)开始支持Intel版的EFI。微软的64位版Windows基本都支持UEFI。
三、操作系统的引导过程
简单的概括传统BIOS与UEFI主板引导操作系统过程如下:
BIOS:设备加电 -> BIOS初始化/自检 -> boot loader引导(扇区代码) -> OS操作系统。
UEFI:设备加电 -> UEFI平台 -> efi应用(硬盘文件) -> OS操作系统。
1.传统BIOS引导操作系统
理论上传统BIOS仅支持MBR硬盘启动(在操作系统支持的情况下,GPT类型的磁盘仅可做数据盘)。
具体启动过程:
- 按下电源,主板通电,CPU重置。
- 固化在主板ROM芯片里的BIOS程序就会被CPU加载到内存运行。
- BIOS程序自检(POST)完毕以后加载COMS芯片里保存的参数。
- 通过COMS的参数, BIOS程序加载指定(启动顺序)磁盘的第一个扇区(即主引导记录MBR)到内存里运行。
- 不同的引导代码(BootLoader)引导操作系统流程略有不同,微软的BootLoader做法是加载分区表(DPT)中标记为活动标志的分区引导记录(PBR),PBR里的引导代码加载操作系统的引导文件到内存运行,例如 Windows 的 bootmgr。而Linux的BootLoader(如Gurb)则会分阶段加载,直接查找所有分区,加载第一个引导文件grldr(详情点击阅读)。
- 当引导文件运行后,操作系统内核就被加载运行,完成从 BIOS 程序(准确的说是从MBR)中接手的引导流程。
传统的 BIOS比较低级,只读取指定磁盘最前面第一个扇区(MBR)里的代码,MBR里面的引导代码(BootLoader)如何启动操作系统BIOS是一无所知的。微软的BootLoader只是一条跳转语句,跳转到标记为活动分区的PBR(分区引导记录,类似于主引导记录,位于分区最前面的扇区)执行。由于BIOS并没有具体规定用户的第一个分区(我们平时说的C盘)从哪个位置(相对于MBR)开始,因此可以利用MBR后面的扇区空间保存更多的引导代码(实现更多的功能),比如GRUB4DOS占用16个扇区,因此改变BootLoader代码就可以实现多系统的引导,这样的软件也比较多,这里不一一列举了。也有人把MBR里的引导代码称为引导的第一阶段,其他扇区的引导代码称为第二阶段(实现更多功能,比如识别文件系统等)
2.UEFI启动操作系统
EFI基本启动流程(如下图):首先EFI初始化,EFI平台加载,设备驱动与EFI应用程序加载,boot manager启动,OS loader启动,OS启动。
但由于UEFI规范只有要求标准,并没有具体的呈现方式,因此每家主板以及操作系统的引导过程也略有不同,这里以Windows系统为例。
- 系统开机 - 上电自检。
- UEFI 固件被加载,并由它初始化启动要用的硬件。
- 固件读取其引导管理器以确定从何处(比如,从哪个硬盘及分区)加载哪个 UEFI 应用。
- 固件按照引导管理器中的启动项目,加载UEFI 应用。
即UEFI引导管理器加载FAT分区里的efi文件来启动操作系统。
- 已启动的 UEFI 应用还可以启动其他应用(对应于 UEFI shell 或 rEFInd 之类的引导管理器的情况)或者启动内核及initramfs(对应于GRUB之类引导器的情况),这取决于 UEFI 应用的配置。
在 EFI 系统启动后,GUID 分区表(GPT)就会被识别,之后 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。
3.总结
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分区)只用来升级系统。
四、多系统引导的管理(未完成)
附录
- 《UEFI原理小结》http://www.178linux.com/15793
- 《GPT分区表详解》https://blog.csdn.net/li33293884/article/details/50562527
- 《GPT分区数据格式分析》https://blog.csdn.net/diaoxuesong/article/details/9406015
- 《Windows启动过程(MBR引导过程分析)》:https://www.cnblogs.com/LittleHann/p/6974928.html
- 远景论坛关于GPT讨论贴 http://bbs.pcbeta.com/forum.php?mod=viewthread&tid=1750735
- 《GRUB 与系统引导》https://blog.nanpuyue.com/2017/037.html
- 《科普贴:BIOS和UEFI的启动项》https://zhuanlan.zhihu.com/p/31365115
- 《启动U盘简单手动制作BIOS+UEFI》 http://bbs.wuyou.net/forum.php?mod=viewthread&tid=370578