This page provides a way to observe reclaiming process of EDKII Variable Services with UEFI Fault Tolerant Write Protocol.
EDKII Variable Services provides reclaim process with the recovery mechanism. When the platform restarts after power-off happens on NV reclaiming process, the driver checks the flag NV_FTW_WORKING that the NV reclaiming is not completed, it restores variables from NV_FTW_SPARE into NV_VARIABLE_STORE. Below files which are generated in build-time provide the regions information.
FlashMap.h
#define FLASH_REGION_NVSTORAGE_SUBREGION_NV_VARIABLE_STORE_OFFSET 0x590000
#define FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_OFFSET 0x5ae000
#define FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_OFFSET 0x5b0000
AutoGenFlashMap.h
#define _PCD_VALUE_PcdFlashNvStorageVariableBase 0xFFF90000U
#define _PCD_VALUE_PcdFlashNvStorageVariableSize 0x0001D000U
#define _PCD_VALUE_PcdFlashNvStorageFtwWorkingBase 0xFFFAE000U
#define _PCD_VALUE_PcdFlashNvStorageFtwWorkingSize 0x00002000U
#define _PCD_VALUE_PcdFlashNvStorageFtwSpareBase 0xFFFB0000U
#define _PCD_VALUE_PcdFlashNvStorageFtwSpareSize 0x00020000U
Please follow the steps to observe the reclaiming process.
Step 1. Burn BIOS in ROM and dump it with DediProg to observe the region of NV_FTW_WORKING.
We see the header of NV_FTW_WORKING. The header is used to check if data is successfully written by FTW protocol. If the writing data is completed, FTW driver set a flag in NV_FTW_WORKING to indicator the completion.
Step 2. Boot UEFI shell and observe NV_FTW_WORKING.
We use a tool to observe the region of NV_FTW_WORKING.
> ToolA.efi -read -id 3 -lba 1 -offset e000 -size 70
We see that the region only has header.
Step 3. Make variable reclaiming.
We use a tool to make reclaiming process happen.
> ToolB.efi -tc1:rt=1,size=1000
Step 4. Observe NV_FTW_WORKING and NV_FTW_SPARE
We use a tool to observe the region of NV_FTW_WORKING.
> ToolA.efi -read -id 3 -lba 1 -offset e000 -size 70
We a tool to observe the region of NV_FTW_SPARE.
> ToolA.efi -read -id 3 -lba 2 -offset 0000 -size 70
We find that the NV_FTW_SPARE is empty because FTW erased it after the large data were written successfully in NV variable store. If we disable the following code in FaultTolerantWrite.c,
#if 0
Status = FtwEraseSpareBlock (FtwDevice);
Ptr = SpareBuffer;
for (Index = 0; Index < FtwDevice->NumberOfSpareBlock; Index += 1) {
MyLength = FtwDevice->BlockSize;
Status = FtwDevice->FtwBackupFvb->Write (
FtwDevice->FtwBackupFvb,
FtwDevice->FtwSpareLba + Index,
0,
&MyLength,
Ptr
);
if (EFI_ERROR (Status)) {
FreePool (SpareBuffer);
DPRINTF_INST ("}..19\n");
return EFI_ABORTED;
}
Ptr += MyLength;
}
#endif
and repeat the step 1, 2, and 3 again, we can find that the the NV_FTW_SPARE stores the backup data.
> ToolA.efi -read -id 3 -lba 2 -offset 0000 -size 70
It proofs that the region of NV_FTW_SPARE is built by UEFI Fault Tolerant Write Protocol. The region is a backup of NV_VARIABLE_STORE that is reclaimed.
Where can we get ToolA.efi and ToolB.efi?
ReplyDeleteEspecially ToolB.efi.
I have been looking evevywhere for a shell tool that can reclaim the EFI Variable space. In your write up ToolB.efi did just that. It the tool I been looking for. THe UEFI firmware update will not go through because the ESVA space is exhausted. ToolB.efi sound like the answer. I see its used in the example above. But where did toolB.efi come from and how can get it?
ReplyDelete