问:在PEI阶段,PeiReadOnlyVariable2->GetVariable()可以从Pei Hob或NV RAM中获取UEFI变量,例如Setup默认值。若平台首次烧录BIOS并开机,在Hob尚未建立,而且还没有将Setup默认值set到NVRAM中之前,第一次是如何读取到Setup默认值的?
先来看一下 EFI_PEI_READ_ONLY_VARIABLE2_PPI,
//
// This PPI provides a lightweight, read-only variant of the full EFI
// variable services.
//
struct _EFI_PEI_READ_ONLY_VARIABLE2_PPI {
EFI_PEI_GET_VARIABLE2 GetVariable;
EFI_PEI_GET_NEXT_VARIABLE_NAME2 NextVariableName;
};
在PEI阶段,该PPI允许以read-only的方式获取UEFI variable store。
//
// This service retrieves a variable's value using its name and GUID.
//
// Read the specified variable from the UEFI variable store. If the Data
// buffer is too small to hold the contents of the variable,
// the error EFI_BUFFER_TOO_SMALL is returned and DataSize is set to the
// required buffer size to obtain the data.
//
typedef
EFI_STATUS
(EFIAPI *EFI_PEI_GET_VARIABLE2)(
IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
IN CONST CHAR16 *VariableName,
IN CONST EFI_GUID *VariableGuid,
OUT UINT32 *Attributes,
IN OUT UINTN *DataSize,
OUT VOID *Data
);
EFI_PEI_GET_VARIABLE2 interface的作用是从PEI Hob或NVRAM中获取variable storages。
对于上面所提问题,一开始认为GetVariable()可以直接从SPI Flash中的Bios binary中读取到Variable storages。实际上不然,GetVariable()只能根据VariableName和VariableGuid从PEI Hob或NVRAM中读取相应的variable,若Hob list与NVRAM中都不存在相应的varible header,则返回EFI_NOT_FOUND。因此,对于第一次BIOS开机,第一次执行GetVariable()是不可能得到想要的setup默认值的。
Setup默认值是通过FCE工具打到Bios binary中的,并且以PEIM FFS文件的形式存在于PEI FV中。BIOS首次开机时,会根据GUID检索Flash BIOS中的Setup FFS文件,读取到内存中,并建立相应的Variable Hob,Boot OS之前再将Setup默认值写入到NVRAM中。下次开机,就可以直接从NVRAM中读取了。