UEFI——PEI阶段
一、PEI介绍
Pre-EFI Initialization(PEI)在引导的早期被调用,仅利用CPU资源调用PEIM,这些PEIM负责:
(1)初始化一些永久内存
(2)在HOBs中描述内存信息
(3)将控制权传递给驱动执行环境(DXE)阶段
(4)此外,PEI阶段还负责危机恢复和从S3苏醒。
PEI提供了一个公共框架,通过这个框架可以独立的设计、开发、更新初始化模块。开发PEI模块是为了满足PI框架中的以下模块:
(1)维护信任链,防止未经授权更新PEI阶段或PEIM
(2)提供一个PEI核心,这个核心对于其它处理器厂商或多或少的保持不变,但它将支持来不同供应商的外接模块,特别是处理器、芯片组、RAM初始化等
(3)允许独立开发早期初始化模块
PEI的支持的功能限于:
(1)定位、验证和调度PEIMs
(2)促进PEIMs之间的通信
(3)为后续阶段提供交接数据
PEI foundation会建立一个名为PEI Services Table的系统表,这张表对所有的PEIM是可见的。由于PEI foundation和临时RAM在构建的时候是未知的,因此指向PEI Services Table的指针被传递给每一个PEIM和PEIM to PEIM(PPI)的一部分。PEI foundation提供的服务有:
二、PEI阶段名词解释
PEI Foundation :是负责派遣PEIMs、维护引导模式、初始化永久内存、调用DXE加载的实体。
PEI Dispatcher:PEI派遣器的实质是PEI Foundation中实现的状态机,PEI dispatcher会评估固件卷中的PEIM的依赖表达式是PPIs的逻辑组合,描述了在调用给定的PEIM必须能够用的PPI,PEI派遣器会参考IEI Foundation中的PPI数据库决定安装哪些PPI,如果PPI已经安装,依赖表达式将求值为true,这代表告诉PEI派遣器可以运行PEIM。
PEIM:PEIM用于实现个性化的PEI Foundation,PEI Foundation代码的作用是按顺序调度PEIM,以实现基本服务。
PPI:PEIM之间使用一种名为PPI的数据结构进行通信
三、PEI Services Table
PEI Services Table中包含了一系列的函数指针,这个表位于临时内存或永久内存中,这取决于是处于PEI阶段的哪个时期。
typedef struct _EFI_PEI_SERVICES EFI_PEI_SERVICES;
EFI_PEI_SERVICES所提供的服务可以分为:(1)管理启动模式(2)分配早期和永久内存(3)支持固件文件系统 (4)创建交接块HOBs
struct _EFI_PEI_SERVICES {////// The table header for the PEI Services Table.///EFI_TABLE_HEADER Hdr;//// PPI Functions//EFI_PEI_INSTALL_PPI InstallPpi;EFI_PEI_REINSTALL_PPI ReInstallPpi;EFI_PEI_LOCATE_PPI LocatePpi;EFI_PEI_NOTIFY_PPI NotifyPpi;//// Boot Mode Functions//EFI_PEI_GET_BOOT_MODE GetBootMode;EFI_PEI_SET_BOOT_MODE SetBootMode;//// HOB Functions//EFI_PEI_GET_HOB_LIST GetHobList;EFI_PEI_CREATE_HOB CreateHob;//// Firmware Volume Functions//EFI_PEI_FFS_FIND_NEXT_VOLUME2 FfsFindNextVolume;EFI_PEI_FFS_FIND_NEXT_FILE2 FfsFindNextFile;EFI_PEI_FFS_FIND_SECTION_DATA2 FfsFindSectionData;//// PEI Memory Functions//EFI_PEI_INSTALL_PEI_MEMORY InstallPeiMemory;EFI_PEI_ALLOCATE_PAGES AllocatePages;EFI_PEI_ALLOCATE_POOL AllocatePool;EFI_PEI_COPY_MEM CopyMem;EFI_PEI_SET_MEM SetMem;//// Status Code//EFI_PEI_REPORT_STATUS_CODE ReportStatusCode;//// Reset//EFI_PEI_RESET_SYSTEM ResetSystem;//// (the following interfaces are installed by publishing PEIM)// I/O Abstractions//EFI_PEI_CPU_IO_PPI *CpuIo;EFI_PEI_PCI_CFG2_PPI *PciCfg;//// Future Installed Services//EFI_PEI_FFS_FIND_BY_NAME FfsFindFileByName;EFI_PEI_FFS_GET_FILE_INFO FfsGetFileInfo;EFI_PEI_FFS_GET_VOLUME_INFO FfsGetVolumeInfo;EFI_PEI_REGISTER_FOR_SHADOW RegisterForShadow;EFI_PEI_FFS_FIND_SECTION_DATA3 FindSectionData3;EFI_PEI_FFS_GET_FILE_INFO2 FfsGetFileInfo2;EFI_PEI_RESET2_SYSTEM ResetSystem2;EFI_PEI_FREE_PAGES FreePages;
};
四、PEI Foundation
PEI Foundation Entry Point:SEC阶段使用以下信息调用进入PEI Foundation的入口点:
PPI、BFV大小和位置、临时RAM的大小和位置、可供PEI foundation使用的临时RAM的大小和位置、堆栈的大小和位置、关键引导FV的大小和位置
PEI foundation的入口点函数原型为:
typedef
VOID
(EFIAPI *EFI_PEI_CORE_ENTRY_POINT)(IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, //指向PEI foundation的操作环境IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList //指向PEI core最初安装的一个或多个PPi列表);
其中,SecCoreData是一个数据结构,包含了 PEI core的操作环境,例如临时RAM的大小和位置、堆栈、BFV位置(UEFI的PEI阶段使用的栈是预先定义的,并且位于固件内部或某个已知的位置)。其原型为:
typedef struct _EFI_SEC_PEI_HAND_OFF {UINT16 DataSize; //数据结构的大小VOID *BootFirmwareVolumeBase; //指向bfv第一个字节UINTN BootFirmwareVolumeSize; //bfv的大小,以字节为单位VOID *TemporaryRamBase; //指向临时RAMUINTN TemporaryRamSize; //临时RAM的大小VOID *PeiTemporaryRamBase; //指向PEI foundation可用的临时RAM的第一个字节UINTN PeiTemporaryRamSize; //PEI foundation可用的临时RAM的大小VOID *StackBase; //指向堆栈UINTN StackSize; //堆栈的大小
} EFI_SEC_PEI_HAND_OFF;
PpiList指向由PEI核心最初安装的一个或多个PPI描述符的列表。一个空的PPI列表由一个带有结束标记EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST的描述符组成。作为其初始化阶段的一部分,PEI基础将添加这些由SEC托管的PPI到其PPI数据库中,以便PEI基础和任何模块都可以利用这些早期PPI中的相关服务调用和/或代码。其代码原型为:
typedef struct {UINTN Flags;EFI_GUID *Guid;VOID *Ppi;
} EFI_PEI_PPI_DESCRIPTOR;