PEI Phase 一些重要的结构体

EFI_SEC_PEI_HAND_OFF

EFI_SEC_PEI_HAND_OFF结构保存着PEI核心运行环境的信息,如临时RAM的位置大小、堆栈位置和BFV位置。

typedef struct _EFI_SEC_PEI_HAND_OFF {

  /// 数据结构的大小
  UINT16  DataSize;

  /// 指向引导固件卷的第一个字节,PEI Dispatcher应该搜索PEI模块。
  VOID    *BootFirmwareVolumeBase;

  /// 引导固件卷的大小,以字节为单位。
  UINTN   BootFirmwareVolumeSize;

  /// 指向临时RAM的第一个字节。
  VOID    *TemporaryRamBase;

  /// 临时RAM的大小,以字节为单位。
  UINTN   TemporaryRamSize;

  /// 指向PEI Foundation可使用的临时RAM的第一个字节。由PeiTemporaryRamBase和PeiTemporaryRamSize描述的区域
  /// 不能超出由TemporaryRamBase和TemporaryRamSize描述的区域。这个区域不应该与StackBase和StackSize报告的区域重叠。
  VOID    *PeiTemporaryRamBase;

  /// 可供PEI Foundation使用的可用临时RAM的大小,以字节为单位。
  UINTN   PeiTemporaryRamSize;

  ///指向堆栈的第一个字节。这可能是由TemporaryRamBase和TemporaryRamSize描述的内存的一部分,也可能是一个完全独立的区域。 
  VOID    *StackBase;

  /// 堆栈的大小,以字节为单位。
  UINTN   StackSize;
} EFI_SEC_PEI_HAND_OFF;

PEI_PPI_DATABASE

这是PeiMain 的内部数据结构,定义了一个数组用来存储所有安装的PEI PPI.每个安装PPI 及通知PPI 都会保存在这个结构中的一个数组单元。由于PEI 早期阶段内存还没有初始化,没有足够的内存可以使用,所以此数据结构的大小是不可能动态调整的,只能保存一定数量的PPI,最大的个数由固定类型的PciPeiCoreMaxPpiSupported 的值来起决定,用户可以通过配置此PCD来允许系统安装更多的PPI。

/// PEI_PPI_DATABAASE的PpiListPtrs存储了所有安装的PPi和通知PPI。
/// PPI数据库结构中包含两个链接:PpiList和NotifyList。
/// PpiList在PpiListPtrs数组的头,notify在PpiListPtrs数组的尾。
///
typedef struct {
  ///
  /// PpiList链表结束索引。
  /// PpiListEnd 记录了最后一个安装的PPI的数组索引,PPI的索引是从零开始递增的,
  /// 
  INTN                    PpiListEnd;
  ///
  /// notify链表结束索引。
  /// NotfifyListEnd记录了最后一个安装的通知PPI的数组索引,通知PPI 的索引是从最大值开始递减的,
  /// 一旦PpiListEnd等于NotifyListEnd,则说明安装的PPI数量超出了最大允许的安装个数,
  /// 新的PPI 无法安装,可能会导致系统出错。
  INTN                    NotifyListEnd;
  ///
  /// 已发送notify列表的索引。
  ///
  INTN                    DispatchListEnd;
  ///
  /// 在PpiList链接列表中最后安装的Ppi描述的索引。
  ///
  INTN                    LastDispatchedInstall;
  ///
  /// 在notify链表中最后一次发送notify的索引。
  /// 
  INTN                    LastDispatchedNotify;
  ///
  /// Ppi数据库有pcdpeicoremaxppissupported的entries。
  ///
  PEI_PPI_LIST_POINTERS   *PpiListPtrs;
} PEI_PPI_DATABASE;

PEI_CORE_FV_HANDLE

此数据结构用来记录一个PeiMain识别的FV空间的数据信息,包括其的起始地址、数据格式解析的PPI 、自己的句柄以及所包含的每个PEI模块的派遣状态和每个文件的句柄,最后一个标识符号记录这个FV是否已经被解析。这个数据结构支持的最大文件个数是由PcdPeiCoreMaxPeimPerFv的值决定。如果一个FV空间包含的文件个数大于此PCD的值,PEIMain将无法记录其的完整信息,可能会导致系统出错。些数据结构定义在PeiMain.h

//用来记录一个PEIMain识别的FV空间的数据信息,包括起始位置,数据格式解析的PPI,自己的句柄
typedef struct {
  EFI_FIRMWARE_VOLUME_HEADER          *FvHeader;
  EFI_PEI_FIRMWARE_VOLUME_PPI         *FvPpi;
  EFI_PEI_FV_HANDLE                   FvHandle;
  //
  // Ponter to the buffer with the PcdPeiCoreMaxPeimPerFv number of Entries.
  // 每个PEI模块的派遣状态
  //
  UINT8                               *PeimState;
  //
  // Ponter to the buffer with the PcdPeiCoreMaxPeimPerFv number of Entries.
  // 每个文件的句柄
  //
  EFI_PEI_FILE_HANDLE                 *FvFileHandles;
  BOOLEAN                             ScanFv;
  UINT32                              AuthenticationStatus;
} PEI_CORE_FV_HANDLE;

EFI_PEI_SERVICES

/// 
/// EFI_PEI_SERVICES是一个函数集合,其实现由PEI Foundation提供.
/// 这些服务分为不同的类别,包括:
/// - 管理启动方式
/// - 同时分配早期和永久内存
/// - 支持固件文件系统(FFS)
/// - 抽象PPI数据库抽象
/// - 创建HOB(HOBs)。
///
struct _EFI_PEI_SERVICES {
  ///
  /// PEI Services表的表头。
  ///
  EFI_TABLE_HEADER                Hdr;

  //
  // PPI相关功能函数
  //
  EFI_PEI_INSTALL_PPI             InstallPpi;
  EFI_PEI_REINSTALL_PPI           ReInstallPpi;
  EFI_PEI_LOCATE_PPI              LocatePpi;
  EFI_PEI_NOTIFY_PPI              NotifyPpi;

  //
  // Boot Mode(引导模式)相关功能函数
  //
  EFI_PEI_GET_BOOT_MODE           GetBootMode;
  EFI_PEI_SET_BOOT_MODE           SetBootMode;

  //
  // HOB 相关功能函数
  //
  EFI_PEI_GET_HOB_LIST            GetHobList;
  EFI_PEI_CREATE_HOB              CreateHob;

  //
  // Firmware Volume (FV)相关功能函数
  //
  EFI_PEI_FFS_FIND_NEXT_VOLUME2   FfsFindNextVolume;
  EFI_PEI_FFS_FIND_NEXT_FILE2     FfsFindNextFile;
  EFI_PEI_FFS_FIND_SECTION_DATA2  FfsFindSectionData;

  //
  // PEI 内存相关功能函数
  //
  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
  // (通过发布PEIM来安装以下接口)I/O 抽象接口
  //
  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;
};

PEI_CORE_INSTANCE

///
/// Pei核心私有数据结构实例 PrivateData
/// 该结构叫做PeiMain的内部数据结构,维护运行PEI阶段所有需要的数据信息,包括PEI服务,FV数据空间,PEI模块的dispatch 状态,
/// 可使用的内存空间等等,由于pei 早期没有内存可用,PeiMain定义了一个该数据的局部变量,把其存储在PeiMain入口函数的栈上,
/// 而PeiMain 的入口函数在整个PEI 阶段并不会退出,所以栈上的数据可作为全局数据使用,
/// 但是全局变量的地址需要函数参数在不同的函数之间传递。
///
struct _PEI_CORE_INSTANCE {
  UINTN                              Signature;
  
  ///
  /// 指向ServiceTableShadow
  /// PEI_CORE_INSTANCE结构的创建,填充成员ServiceTableShadow。为全局的gPs
  ///
  EFI_PEI_SERVICES                   *Ps;
  PEI_PPI_DATABASE                   PpiData;
  
  ///
  /// 包含FFS且可以由PeiCore发送的FVs计数。
  ///
  UINTN                              FvCount;
  
  ///
  /// 指向带有PcdPeiCoreMaxFvSupported entries的缓冲区的指针。
  /// 每个entry都是针对一个FV的,它包含FFS,可以被PeiCore发送。
  /// 通过SetPeiServicesTablePointer()保存Ps,以便可以在任何地方检索它。由全局的gPeiServices维护
  ///
  PEI_CORE_FV_HANDLE                 *Fv;

  ///
  /// 指向带有PcdPeiCoreMaxFvSupported entries的缓冲区的指针。
  /// 每个entry是针对PeiCore无法发送的FV的。
  /// 通过ProcessLibraryConstructorList(),传入Ps指针,初始化PEI核心所链接的库。
  ///
  PEI_CORE_UNKNOW_FORMAT_FV_INFO     *UnknownFvInfo;
  UINTN                              UnknownFvInfoCount;
  
  ///
  /// 指向带有PcdPeiCoreMaxPeimPerFv entries的缓冲区的指针。
  /// 通过InitializeMemoryServices(),传入PrivateData,    SecCoreData,初始化PEI Core,
  /// 即根据PeiTemporaryRamBase,和PeiTemporaryRamSize构建一个切换信息表HOB
  /// (一个EFI_HOB_GENERIC_HEADER和一个EFI_HOB_GENERIC_HEADER,这些都在PeiTemporaryRamBase起始位置)。
  ///
  EFI_PEI_FILE_HANDLE                *CurrentFvFileHandles;
  UINTN                              AprioriCount;
  UINTN                              CurrentPeimFvCount;
  UINTN                              CurrentPeimCount;
  EFI_PEI_FILE_HANDLE                CurrentFileHandle;
  BOOLEAN                            PeimNeedingDispatch;
  BOOLEAN                            PeimDispatchOnThisPass;
  BOOLEAN                            PeimDispatcherReenter;
  ///
  /// 初始化PEI核心私有数据缓冲区。
  ///
  EFI_PEI_HOB_POINTERS               HobList;
  BOOLEAN                            SwitchStackSignal;
  BOOLEAN                            PeiMemoryInstalled;
  VOID                               *CpuIo;
  EFI_PEI_SECURITY2_PPI              *PrivateSecurityPpi;
  EFI_PEI_SERVICES                   ServiceTableShadow;
  EFI_PEI_PPI_DESCRIPTOR             *XipLoadFile;
  EFI_PHYSICAL_ADDRESS               PhysicalMemoryBegin;
  UINT64                             PhysicalMemoryLength;
  EFI_PHYSICAL_ADDRESS               FreePhysicalMemoryTop;
  UINTN                              HeapOffset;
  BOOLEAN                            HeapOffsetPositive;
  UINTN                              StackOffset;
  BOOLEAN                            StackOffsetPositive;
  PEICORE_FUNCTION_POINTER           ShadowedPeiCore;
  CACHE_SECTION_DATA                 CacheSection;
  //
  // 在加载固定地址功能的模块时,将运行时代码、启动时代码和PEI内存的顶部地址缓存在下面。
  // 请注意,这个字段和Ps之间的偏移量不应该被改变,因为也许用户可以通过使用Ps的偏移量得到这个顶部地址。
  //
  EFI_PHYSICAL_ADDRESS               LoadModuleAtFixAddressTopAddress;
  //
  // 该字段是为加载固定地址的模块来跟踪PEI代码内存范围的使用而定义的。
  // 它是一个位映射数组,其中的每个位都表示相应的内存页是否可用。
  //
  UINT64                            *PeiCodeMemoryRangeUsageBitMap;
  //
  // This field points to the shadowed image read function
  // 这个字段指向阴影图像读取函数
  //
  PE_COFF_LOADER_READ_FILE          ShadowedImageRead;

  //
  // 指向临时缓冲区的指针,entry为PcdPeiCoreMaxPeimPerFv + 1。
  //
  EFI_PEI_FILE_HANDLE               *FileHandles;
  //
  // 指向临时缓冲区的指针,包含PcdPeiCoreMaxPeimPerFv条目数 entries。
  // 通过InitializePpiServices()初始化ppi 服务。PEI_PPI_DATABASE     PpiData。
  //
  EFI_GUID                          *FileGuid;

  //
  // PeiTempMem和Stack没有覆盖临时内存范围。
  // 这些内存范围将被迁移到物理内存中。
  //
  HOLE_MEMORY_DATA                  HoleData[HOLE_MAX_NUMBER];
};

参考博文:https://blog.csdn.net/robinsongsog/article/details/102653826

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值