在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;