UEFI启动阶段学习SEC阶段和PEI阶段_2020-05-12

   昨天学习了UEFI和BIOS的区别,以及UEFI系统的优点。今天学习UEFI系统驱动的七个不同阶段。
UEFI系统的启动过程

UEFI系统从加电到关机可分为以下七个阶段:

SEC(安全验证)->PEI(EFI前期初始化)->DXE(驱动执行环境)

->BDS(BS?)(启动设备选择)->TSL(操作系统加载前期)

->RT(Run Time)

->AL(系统灾难恢复期)

其中,前三个阶段为UEFI初始化加载阶段,DXE阶段结束后UEFI环境已经准备完毕。

BDS和TSL是UEFI运行OS Loader的阶段。

OS Loader调用ExitBootServices()服务后系统启动进入RT阶段,操作系统加载后期和操作系统运行期均属于RT阶段。

硬件系统或操作系统出现严重错误不能继续正常运行时,固件会尝试进行修复,此时系统进入AL期。但是PI规范和UEFI规范都没有规定AL期的行为。AL期的系统行为由系统供应商自行定义。

上述过程可见下图:
UEFI启动阶段学习SEC阶段和PEI阶段_2020-05-12_第1张图片
每个阶段具体的功能和流程:

  1. SEC(Security Phase,安全阶段)阶段

    SEC(Security Phase)阶段时平台初始话的第一个阶段,计算机系统加电后首先进入这个阶段。

    • SEC阶段的功能:UEFI系统开机或重启后首先进入SEC阶段,SEC阶段系统执行以下四种任务:

      • 接收并处理系统启动和重启信号,系统加电信号、系统重启信号、系统运行过程中的异常信号。
      • 初始化临时存储区域:系统运行在SEC阶段时,仅CPU和CPU内部资源被初始化,而各种外部设备和内存都没有被初始化。因此系统需要一部分临时内存用于代码和数据的存储,一般称为临时RAM,临时RAM只能位于CPU内部(CPU和CPU内部的资源最先被初始化)。最常用的临时RAM是Cache,通过将Cache设置为no-eviction模式,来把其当成内存使用(此时读取命中则返回Cache中的数据,读取缺失并不会向主存发出缺失事件;写命中时写入Cache,写缺失时也不会向主存发出缺失事件),这种技术称为CAR(Cache As RAM)。
      • SEC阶段是可信系统的根:作为系统启动的第一部分,只有SEC能被系统信任,以后的各个阶段才有被信任的基础。因此,大部分情况下SEC再转交控制权给PEI前可以验证PEI是否可信。
      • 传递系统参数给下一阶段:SEC阶段的一切工作都是为PEI阶段做准备的,最重要把系统的控制权转交给PEI,并将SEC阶段的运行信息汇报给PEI。SEC通过将以下信息作为参数传递给PEI的入口程序来向PEI汇报信息:
        • 系统当前状态,PEI根据状态值判断系统当前的健康情况。
        • 可启动固件(Boot Firmware Volume)的地址和大小,PEI据此判断可用硬件。
        • 临时RAM区域的地址和大小。
        • 栈的地址和大小。
    • SEC阶段执行流程:

      根据临时RAM是否初始化为界限,SEC阶段分为两部分:临时RAM初始化前称为Reset Vector阶段;临时RAM初始化后调用SEC入口函数从而进入SEC功能区。其流程如下图:

      UEFI启动阶段学习SEC阶段和PEI阶段_2020-05-12_第2张图片

      其中Reset Vector的执行流程如下:

      1. 进入固件接口。
      2. 从实模式转换到32位平坦模式。
      3. 定位固件中的BFV(Boot Firmware Volume)。
      4. 定位BFV中的SEC影响。
      5. 如果是64位系统,则从32位模式转换至64位模式。
      6. 调用SEC入口函数。
PEI(Pre-EFI Initialization,预先EFI初始化)阶段

虽然SEC阶段对CPU和CPU内的资源进行了初始化,但是PEI阶段可用的资源依旧十分有限,该阶段对内存进行初始化,主要功能是为DXE阶段准备执行环境,将所需要传递给DXE的信息组成HOB(Hand Off Block)列表,最终将控制权转交到DXE。

UEFI具有模块化设计的特点,PEI就是一个模块。PEI Image的入口函数调用PEI模块的入口函数PEICore。

  • PEI阶段的功能:

    • 初始化内存。
    • 为DXE阶段准备执行环境。
  • PEI划分:

    • PEI内核(PEI Foundation):负责PEI基础服务和流程。

    • PEIM(PEI Module)派遣器:找出系统中的所有PEIM,并根据PEIM之间的依赖关系按顺序执行PEIM。PEI阶段对系统的初始化主要由PEIM完成。

      每个PEIM都是一个独立的模块。通过PEIServices,PEIM可以调用PEI阶段(UEFI?)提供的系统服务。通过调用这些服务,PEIM可以访问PEI内核。PEIM之间的的通信通过PPI(PEIM-to-PEIM Interfaces)完成。

  • PEI阶段执行流程:

    1. 进入PEI入口。

    2. 根据SEC阶段传入的信息初始化PS(PEI Core Service)。

    3. 调度系统中的PEIM(PEI Module),准备HOB列表。

      具体调用的系统中的PEIM有:CPU PEIM(提供CPU相关功能,如进行Cache设置、主频设置等);平台相关PEIM(初始化内存控制器、I/O控制器等);内存初始化PEIM(对内存进行初始化,此时内存才可用,之前使用的CPU模拟的临时内存)。

    4. 调用PEIServices得到DEX IPL PPI的Entry服务(即DEXLoadCore)。

      注:PPI与DEX阶段的Protocol类似,每个PPI都是一个结构体,包含有函数指针和变量。每个PPI都有一个GUID。通过PEIServices的LocatePPI服务可以找到GUID对应的PPI实例。

    5. DXELoadCore服务找出并运行DXEImage的入口函数,将HOB列表传递给DXE。

    PEI阶段执行流程完整描述:SEC模块找到PEI Image的入口函数 _ModuleEntryPoint(该函数位于MdePkg/Library/PeimEntryPoint/PeimEntryPoint.c), _ModuleEntryPoint函数最终调用PEI模块的入口函数PEICore(该函数位于MdeModulePkg/Core/Pei/PeiMain/PeiMain.c),进入PEICore后,首先根据从SEC阶段出入的信息设置PEI Core Services,然后调用PEIDispatcher执行系统总的PEIM,在内存初始化完成后,系统切换栈并重新进入PEICore。重新进入PEICore后使用的不再是 临时RAM 而是真正的内存。在所有PEIM执行完成后,调用PEIServices的LocatePPI服务得到DXE IPL PPI,并调用DXE IPL PPI的Entry服务(即DEXLoadCore),找出DEX Image的入口函数,执行DXE Image函数并将HOB列表传递给DXE。

    PEI阶段执行流程如下图:
    UEFI启动阶段学习SEC阶段和PEI阶段_2020-05-12_第3张图片

你可能感兴趣的:(底层开发,#UEFI,底层应用开发,uefi)