在PEI阶段,全局变量大概有这么几个: gPs PEI Service 结构的实现,包括所有的PEI 服务的函数指针。比如学见的PeiInstallPPi, PeiCreateHob, PeiSetSystem.
其次就是PrivateData, 这个是今天我们要讨论的问题,其类型为 PEI_CORE_INSTANCE.
具体就是长这个样子:
struct _PEI_CORE_INSTANCE { 184 UINTN Signature; 185 189 EFI_PEI_SERVICES *Ps; 190 PEI_PPI_DATABASE PpiData; 191 195 UINTN FvCount; 196 201 PEI_CORE_FV_HANDLE *Fv; 202 207 PEI_CORE_UNKNOW_FORMAT_FV_INFO *UnknownFvInfo; 208 UINTN UnknownFvInfoCount; 209 213 EFI_PEI_FILE_HANDLE *CurrentFvFileHandles; 214 UINTN AprioriCount; 215 UINTN CurrentPeimFvCount; 216 UINTN CurrentPeimCount; 217 EFI_PEI_FILE_HANDLE CurrentFileHandle; 218 BOOLEAN PeimNeedingDispatch; 219 BOOLEAN PeimDispatchOnThisPass; 220 BOOLEAN PeimDispatcherReenter; 221 EFI_PEI_HOB_POINTERS HobList; 222 BOOLEAN SwitchStackSignal; 223 BOOLEAN PeiMemoryInstalled; 224 VOID *CpuIo; 225 EFI_PEI_SECURITY2_PPI *PrivateSecurityPpi; 226 EFI_PEI_SERVICES ServiceTableShadow; 227 EFI_PEI_PPI_DESCRIPTOR *XipLoadFile; 228 EFI_PHYSICAL_ADDRESS PhysicalMemoryBegin; 229 UINT64 PhysicalMemoryLength; 230 EFI_PHYSICAL_ADDRESS FreePhysicalMemoryTop; 231 UINTN HeapOffset; 232 BOOLEAN HeapOffsetPositive; 233 UINTN StackOffset; 234 BOOLEAN StackOffsetPositive; 235 PEICORE_FUNCTION_POINTER ShadowedPeiCore; 236 CACHE_SECTION_DATA CacheSection; 237 // 238 // For Loading modules at fixed address feature to cache the top address below which the 239 // Runtime code, boot time code and PEI memory will be placed. Please note that the offset between this field 240 // and Ps should not be changed since maybe user could get this top address by using the offet to Ps. 241 // 242 EFI_PHYSICAL_ADDRESS LoadModuleAtFixAddressTopAddress; 243 // 244 // The field is define for Loading modules at fixed address feature to tracker the PEI code 245 // memory range usage. It is a bit mapped array in which every bit indicates the correspoding memory page 246 // available or not. 247 // 248 UINT64 *PeiCodeMemoryRangeUsageBitMap; 249 // 250 // This field points to the shadowed image read function 251 // 252 PE_COFF_LOADER_READ_FILE ShadowedImageRead; 253 254 // 255 // Pointer to the temp buffer with the PcdPeiCoreMaxPeimPerFv + 1 number of entries. 256 // 257 EFI_PEI_FILE_HANDLE *FileHandles; 258 // 259 // Pointer to the temp buffer with the PcdPeiCoreMaxPeimPerFv number of entries. 260 // 261 EFI_GUID *FileGuid; 262 263 // 264 // Temp Memory Range is not covered by PeiTempMem and Stack. 265 // Those Memory Range will be migrated into phisical memory. 266 // 267 HOLE_MEMORY_DATA HoleData[HOLE_MAX_NUMBER]; 268 }; PrivateData 我们通常叫做PeiMain的内部数据结构,维护运行PEI阶段所有需要的数据信息,包括PEI 服务, FV 数据空间,PEI 模块的dispatch 状态, 可使用的内存空间等等,由于pei 早期没有内存可用,PeiMain定义了一个该数据的局部变量,把其存储在PeiMain入口函数的栈上,而PeiMain 的入口函数在整个PEI 阶段并不会退出,所以栈上的数据可作为全局数据使用,但是全局变量的地址需要函数参数在不同的函数之间传递。
PEI_CORE_FV_HANDLE 数据结构
此数据结构用来记录一个PeiMain 识别的FV空间的数据信息,包括其起始位置,数据格式解析的PPI, 自己的句柄以及所包含的每个PEI模块的派遣状态和每个文件的句柄,
它的真实样子是这样的:
typedef struct { 110 EFI_FIRMWARE_VOLUME_HEADER *FvHeader; 111 EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi; 112 EFI_PEI_FV_HANDLE FvHandle; 113 // 114 // Ponter to the buffer with the PcdPeiCoreMaxPeimPerFv number of Entries. 115 // 116 UINT8 *PeimState; 117 // 118 // Ponter to the buffer with the PcdPeiCoreMaxPeimPerFv number of Entries. 119 // 120 EFI_PEI_FILE_HANDLE *FvFileHandles; 121 BOOLEAN ScanFv; 122 UINT32 AuthenticationStatus; 123 } PEI_CORE_FV_HANDLE;