uefi下的开机顺序_干货分享|UEFI启动流程介绍

8963ef1d9cb4e33fc156ffc3068933e9.png

友情提示:全文3000多文字,预计阅读时间8分钟

摘要

举个类比,想象一下计算机主板是工厂里的机器流水线,只有机器是无法自己生产的,需要领导的统筹安排,比如操作系统。操作系统作为厂长与调度员,不会直接参与机器的调试与清洁还有工厂大门的开关,这就需要一位外协物业也就是UEFI的帮忙。

一个完整的计算机设备,不仅包括了硬件,如主板,芯片等,也包括了软件部分用于硬件检测与初始化以及操作系统的引导启动。该部分代码通常固化在只读ROM芯片内部,与常见的软件不同,该部分代码通常为只读不可写,为了区别也称其为固件,主要用于输入输出设备的基本设置。后期随着存储介质的不断优化,从传统的只读ROM,变为目前常见的电气可擦除Flash,固件也不再为只读性质,还包括了部分系统设置功能,逐步形成我们通常意义上的BIOS(Basic Input Output System)。

对于操作系统而言,固件的意义在于建立操作系统与低层硬件之间的联系。操作系统自身是无法直接获取硬件信息,更无法直接完成所有硬件的初始化,因而需要固件为操作系统创建软件意义上的硬件抽象,提供必要的底层硬件信息,这些信息包括了SMBIOS表(硬件信息),ACPI表(电源状态信息)和内存映射表(建立虚拟内存与物理内存映射)等等。

01 BIOS的介绍

BIOS(Basic Input Output System),全称为基本输入输出系统,诞生于上世纪70年代,主要由上电自检代码、初始化代码、I/O驱动代码、CMOS设置代码组成,程序运行在16位实模式下。传统的BIOS最大寻址范围仅为1MB,基本为汇编语言编写[1]。

简单介绍一下传统BIOS的启动流程。BIOS启动时,首先将PC指针指向0xFFFF0地址处(此处以16位8086为例,如果是32位的80386及以上,地址则为0xFFFF_FFF0)。0xFFFF0地址处的指令通常为一个跳转指令,跳转的目的地址为实际BIOS的入口地址。之后BIOS开始执行POST(Power On Self Test,上电自检),检测硬件设备是否正常,并与CMOS中储存的上次配置参数进行对比,POST完成后开始进行设备初始化工作,检查CPU与内存状态,内存检测完成后开始进行外围设备的初始化,包括分配I/O端口、中断号等工作,若发现有新硬件产生或配置发生变化,则更新CMOS,最后根据CMOS中的启动顺序开始进行扫描启动设备,最终将控制权交给引导程序,最终引导进入操作系统。需要注意的是BIOS中几乎所有的操作都是采用中断的方式。

78a55820df7dbcc4445a99e610e47599.png

图1  传统BIOS启动流程

02 UEFI介绍

传统BIOS系统目前已经很少使用,主要原因在于传统BIOS存在汇编语言编写,开发维护效率低;采用中断操作方式,大量的空白时间浪费在了等待中断上,此外BIOS的在安全性上几乎没有多少设计,且不支持2G以上硬盘,因此传统BIOS逐步已被UEFI替代。

随着32/64位系统的普及,以往16位实模式下的BIOS启动方式已经不再适用于现在的计算机启动环境,因此UEFI成为了主流。UEFI(Unified Extensible Firmware Interface)全称为统一可扩展固件接口,是由UEFI forum发布的一种固件标准。相比于传统BIOS,UEFI的优势在于:有更多的寻址空间,代码大部分为C语言,比汇编语言更友好,降低固件开发和维护所需的门槛,支持UEFI Shell操作环境,可以提供代码更新、系统诊断等各种功能。从实质上说,UEFI是硬件与OS之间的中间层,其任务就是为在PC进入OS之前启动所有的硬件设备,并引导系统启动。UEFI是大部分代码运行在32位或64位保护模式,而非16位实模式,可以实现处理器的最大寻址,因此可以在任何内存地址存放任何信息。

UEFI一改以往BIOS的中断触发模式。BIOS中所有的操作都是以触发各种中断作为基础,而在UEFI中采用的事件event轮询的方式,并且可实现异步操作,降低了等待中断的空操作时间,提高了执行效率。UEFI虽然采用的是面向过程的C语言进行编写,但通过模块化编程思想,引入protocol结构体概念,在C语言中使用struct结构体模拟class对象操作。另外,在传统BIOS中较少的安全性设计也在UEFI中进行了修正,加入了Secure Boot,通过签名验证等方式保证了固件的安全性。此外,UEFI支持BIOS所不支持的GPT格式硬盘,UEFI+GPT方式突破了以往BIOS+MBR在硬盘容量上的限制,为实现大容量存储提供了基础[2]。

a0c0b6a8695fceddb0d75a49a304fd52.png

图2 UEFI是介于低层硬件与操作系统间的中间层

03 UEFI的启动流程

UEFI从启动到关机断电分为七个流程,包括SEC,PEI,DXE,BDS,TSL,RT和AL阶段,其中SEC、PEI和DXE为UEFI的验证与初始化环节,主要承担对的是映像验证和运行环境的初始化,BDS和TSL为UEFI的运行环节,主要承担操作系统的引导,RT阶段控制权已交至系统,UEFI进保留运行时服务,AL为灾难恢复阶段,用于定义运行异常处理(此环节在UEFI架构中并未定义具体操作)。

回到最开始的那个类比,想一想UEFI这位物业大总管在每次开工前都做了些什么。首先UEFI作为厂区安保人员,每次开厂前都会手握钥匙打开工厂大门,只有正确的钥匙才能打开厂区,这就是最初的安全验证SEC阶段。工厂开门后,UEFI转变为保洁U阿姨,U阿姨上班的第一件事是穿上工作服拿起扫帚,这就是UEFI平台的自身的初始化PEI阶段。穿好工作服的阿姨开始本职工作,打扫卫生并清点设备,这就是驱动安装DXE阶段。工厂打扫好了,可以通知厂长开工,但是如果这个工厂是几个厂长共用的,为了避免纠纷,U阿姨变成前台小姐姐,小姐姐参照工厂的优先使用记录表Bootorder选择把工厂的控制权交给第一厂长,若第一厂长生病了或者辞职不干了,那就会去找第二厂长并以此类推,也就是BDS与TSL阶段。工厂控制器转移后,UEFI物业为了不打扰厂区的正常工作,留了一组叫做Runtime service的联系方式后,就回到了茶水间喝茶休息了。

8e0fe218bc42026b90b1347d0a84bc26.png

图3 UEFI启动流程

3.1 SEC阶段

SEC(Security Phase),顾名思义主要出于安全性考虑,SEC是整个可信系统的根,只有SEC被系统信任,之后的各个阶段才有被信任的基础。除此之外,SEC的功能还包括了:1.系统上电信号的接收,2.初始化Cache,并将其视为RAM以搭建C语言运行环境,3.找到BFV(Boot Firmware Volume),之后进入PEI环节,4.MTRR等CPU寄存器的初始化。

当计算机开机后,PC指针跳转至0xFFFF_FFF0地址空间,通常此处为一个跳转指令,跳转至固件程序的真正入口地址,而后从实模式转为保护模式,若为64位系统,则再次转为64位模式。在SEC阶段内,由于计算机的内存资源还未准备完成,无法实现堆栈操作,C语言环境还没有搭建完成,程序主要使用汇编代码实现,之后随着Cache的准备完成,并将其作为RAM使用,C语言的运行环境准备完成,后续环节代码大部分则通过C语言进行实现,我们将该技术成为CAR技术(Cache as RAM)。找到BFV的入口地址,并进入PEI阶段。

SEC环节将安全启动的思想引入固件中,改变了传统BIOS对于安全性设计的欠缺,增强系统的安全性。

14da54c67b8a853fb0c013b6f07216a0.png

图4 SEC环节执行顺序

3.2 PEI阶段

PEI(Pre-EFI Initialization),在这个环节内完成的工作主要由三个,1、建立Hob,通过Hob表向后续环节传递必要的信息,2、包括内存在内初始化工作,3、引导进入DXE阶段。

在PEI阶段,主要启动流程为:启动PEI service,安装相应的PPI接口;内存初始化,Disable CAR功能,打开Cache;创建相应的Hob表,为了向DXE环节传递必要的系统信息;引导进入DXE流程。

在PEI环节还有一个重要的特性在于Boot Mode的选择,并不是所有启动都需要经过完整的启动流程,当系统根据ACPI电源状态设置了S3 Resume,则不执行DXE环节,直接进行系统引导,减少系统启动时间,实现待机启动,实现秒开电脑。

196c96fdd1bb56fb86644acfb5040ce4.png

图5 PEI环节执行顺序

3.3 DXE阶段

DXE(Driver Execution Environment),该阶段执行大部分的系统初始化工作,在PEI阶段,内存已经初始化完成。因此在DXE相比于前两个阶段,可以承担大量复杂的执行工作。

DXE最主要的工作在于遍历所有的DXE Driver,完成硬件系统的初始化。DXE主要由三部分组成,包括DXE Core,用于产生Boot Service与Runtime Service两个服务结构体,这两个结构体中包含了DXE阶段所提供相应的服务,如事件管理,内存管理驱动管理等;DXE Dispatcher,用于为Driver的遍历执行提供相应的操作顺序;DXE Driver是相互间独立的模块,Driver与Driver之间的通信采用特定结构的Protocol结构体,每个Protocol结构体都有一个互斥的全局变量GUID用于标记,当所有Driver执行完毕后,UEFI系统完成初始化工作,进入BDS阶段,选择相应的启动设备引导系统启动。

7bf350176e46103b0383204e5c13dfa5.png

图6 DXE环节执行顺序

3.4 BDS阶段

BDS(Boot Device Selection)的主要作用是按照Bootorder选择相应的启动设备,并执行相应的启动策略。

在进入BDS后,系统首先完成必要的初始化工作,对PCI总线的枚举扫描,之后初始化console控制台设备,如键盘、鼠标等等。通过读取NVRAM中的非易失变量Bootoption获得启动必要的参数如Bootorder以及各个启动项Bootxxxx(xxxx为4位16进制数),最后系统根据Bootorder中的顺序逐个访问Bootxxxx,当存在Bootxxxx可用时则通过该启动项进行Boot Loader。

e39efbc97be8b856eb71366969fd5309.png

图7 BDS环节执行顺序

3.5 TSL阶段

在TSL阶段(Transient System Load)阶段,系统资源仍由UEFI进行控制,但会逐步将控制权转移至Boot Loader。在TSL,用户可进入UEFI Shell,通过Shell指令进行操作。一般情况下系统会直接跳过UEFI shell,直接进入Boot Loader,除非人为操作或产生异常。

3.6 RT&AL阶段

在RT阶段,Boot Loader获取系统的控制权,UEFI仅保留Runtime Service对接使用。而AL阶段则是指在RT阶段中出现异常时得操作过程,此部分在UEFI规范中并未做详细定义。

04 总结

从上述可以看出,相比以往的BIOS,UEFI更像一个微型操作系统,支持图形化界面,甚至有些场合可支持网络操作。从整个启动流程上看SEC、PEI、BDS是UEFI作为系统的初始化阶段,为UEFI的运行搭建必要的环境,而BDS与TSL则是UEFI的运行阶段,在这个阶段UEFI完成最重要的事情就是启动与系统引导,并将控制权转移给Boot Loader,另外在TSL环节可以通过UEFI Shell方式进行操作。而RT与AL则是UEFI作为系统的末期,所余留的与Boot Loader进行沟通与异常处理的阶段,在这个阶段整个系统的控制器已经在Boot Loader上,UEFI仅保留一组Runtime Service。

再结合BIOS与UEFI的特征,归根结底,固件所做的事情就是初始化与引导系统的启动。从运行流程上看也存在相同的三个步骤,首先是ROM stage阶段,在此期间系统资源大部分特别是内存资源是不可用的,因此采用汇编的方式,采用CAR技术或其他类似技术,为C语言的运行提供必要的环境;其次是RAM stage阶段,在这个阶段C语言环境已经初步完成,可运行C语言程序,此时固件将完成系统资源的初始化工作;最后一步也是最重要的一步就是引导系统,首先扫描启动设备Bootxxxx,根据Bootorder顺序选择可启动设备引导进入操作系统,并实现控制权的转移,最终实现系统启动。

参考文献

[1].    Intel.,BIOS Boot Specs V1.01. 1996

[2]. UEFI F.,Unified Extensible Firmware Interface (UEFI) Specification Version 2.7. 2019

往期精选

1

干货分享|深入理解JDK7 HashMap

2

干货分享|记一次JVM Crash分析及解决实践

3

大云制造|移动云消息队列E-MQTT正式发布上线

  • 12
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值