Skip to content

Instantly share code, notes, and snippets.

@deeglaze
Last active June 23, 2025 03:49
Show Gist options
  • Save deeglaze/efb75ab98cd834e16ffcc7a8d034f124 to your computer and use it in GitHub Desktop.
Save deeglaze/efb75ab98cd834e16ffcc7a8d034f124 to your computer and use it in GitHub Desktop.
Read firmware.igvm (Gemini 2.5 flash)
#include <efi.h>
#include <efiprot.h>
#include <efidef.h>
#include <efilib.h> // For LibLocateProtocol, Print, etc.
// Define the target GUID for the partition
// C12A7328-F81F-11D2-BA4B-00A0C93EC93B
#define TARGET_PARTITION_GUID \
{0xC12A7328, 0xF81F, 0x11D2, {0xBA, 0x4B,0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B}}
// Macro to compare GUIDs
#define CompareGuid(g1, g2) \
(g1->Data1 == g2->Data1 && \
g1->Data2 == g2->Data2 && \
g1->Data3 == g2->Data3 && \
g1->Data4[0] == g2->Data4[0] && \
g1->Data4[1] == g2->Data4[1] && \
g1->Data4[2] == g2->Data4[2] && \
g1->Data4[3] == g2->Data4[3] && \
g1->Data4[4] == g2->Data4[4] && \
g1->Data4[5] == g2->Data4[5] && \
g1->Data4[6] == g2->Data4[6] && \
g1->Data4[7] == g2->Data4[7])
EFI_STATUS
EFIAPI
UefiMain(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE* SystemTable
)
{
EFI_STATUS Status;
UINTN NoHandles;
EFI_HANDLE* Buffer = NULL;
UINTN Index;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* SimpleFs = NULL;
EFI_FILE_PROTOCOL* Root = NULL;
EFI_FILE_PROTOCOL* FileHandle = NULL;
EFI_GUID PartitionInfoProtocolGuid = EFI_PARTITION_INFO_PROTOCOL_GUID;
EFI_PARTITION_INFO_PROTOCOL* PartitionInfo = NULL;
EFI_GUID TargetGuid = TARGET_PARTITION_GUID;
UINT8* FileData = NULL;
UINTN FileSize = 0;
EFI_FILE_INFO* FileInfo = NULL;
UINTN FileInfoSize = 0;
CHAR16 Filename[] = L"\\FIRMWARE.IGVM"; // Note the backslash for root directory
// Initialize Lib (from EfiLib.h)
InitializeLib(ImageHandle, SystemTable);
ST->ConOut->OutputString(ST->ConOut, L"UEFI Application: Reading FIRMWARE.IGVM\r\n");
// 1. Locate all handles that support the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
Status = gBS->LocateHandleBuffer(
ByProtocol,
&gEfiSimpleFileSystemProtocolGuid,
NULL,
&NoHandles,
&Buffer
);
if (EFI_ERROR(Status)) {
Print(L"Failed to locate EFI_SIMPLE_FILE_SYSTEM_PROTOCOL handles: %r\r\n", Status);
goto Exit;
}
Print(L"Found %d handles with EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.\r\n", NoHandles);
// 2. Iterate through handles to find the partition with the target GUID
EFI_HANDLE TargetPartitionHandle = NULL;
for (Index = 0; Index < NoHandles; Index++) {
Status = gBS->HandleProtocol(
Buffer[Index],
&PartitionInfoProtocolGuid,
(VOID**)&PartitionInfo
);
if (!EFI_ERROR(Status)) {
// Check if it's a GPT partition
if (PartitionInfo->Info.Gpt.Header->PartitionType == PARTITION_TYPE_GPT) {
// Compare partition GUID
if (CompareGuid(&PartitionInfo->Info.Gpt.PartitionTypeGUID, &TargetGuid)) {
Print(L"Found target GPT partition at handle %p.\r\n", Buffer[Index]);
TargetPartitionHandle = Buffer[Index];
// Release the protocol we just opened on this handle
gBS->CloseProtocol(Buffer[Index], &PartitionInfoProtocolGuid, ImageHandle, NULL);
break; // Found it, no need to continue searching
}
}
// Close the protocol if it was opened but not the target
gBS->CloseProtocol(Buffer[Index], &PartitionInfoProtocolGuid, ImageHandle, NULL);
}
}
if (TargetPartitionHandle == NULL) {
Print(L"Error: EFI system partition not found.\r\n");
Status = EFI_NOT_FOUND;
goto Exit;
}
// 3. Open the Simple File System Protocol on the target partition handle
Status = gBS->HandleProtocol(
TargetPartitionHandle,
&gEfiSimpleFileSystemProtocolGuid,
(VOID**)&SimpleFs
);
if (EFI_ERROR(Status)) {
Print(L"Failed to open EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on target handle: %r\r\n", Status);
goto Exit;
}
// 4. Open the root directory
Status = SimpleFs->OpenVolume(SimpleFs, &Root);
if (EFI_ERROR(Status)) {
Print(L"Failed to open root volume: %r\r\n", Status);
goto Exit;
}
// 5. Open the FIRMWARE.IGVM file
Print(L"Attempting to open file: %s\r\n", Filename);
Status = Root->Open(Root, &FileHandle, Filename, EFI_FILE_MODE_READ, 0);
if (EFI_ERROR(Status)) {
Print(L"Error: Failed to open %s: %r\r\n", Filename, Status);
goto Exit;
}
Print(L"Successfully opened %s.\r\n", Filename);
// 6. Get file size
FileInfoSize = 0;
Status = FileHandle->GetInfo(FileHandle, &gEfiFileInfoGuid, &FileInfoSize, NULL);
if (Status == EFI_BUFFER_TOO_SMALL) {
Status = gBS->AllocatePool(EfiBootServicesData, FileInfoSize, (VOID**)&FileInfo);
if (EFI_ERROR(Status)) {
Print(L"Failed to allocate pool for FileInfo: %r\r\n", Status);
goto Exit;
}
Status = FileHandle->GetInfo(FileHandle, &gEfiFileInfoGuid, &FileInfoSize, FileInfo);
if (EFI_ERROR(Status)) {
Print(L"Failed to get file info: %r\r\n", Status);
goto Exit;
}
FileSize = FileInfo->FileSize;
Print(L"File size of %s: %Lu bytes\r\n", Filename, FileSize);
} else {
Print(L"Failed to get file info size: %r\r\n", Status);
goto Exit;
}
if (FileSize == 0) {
Print(L"Warning: %s has zero size. Nothing to read.\r\n", Filename);
goto Exit;
}
// 7. Allocate buffer and read file contents
Status = gBS->AllocatePool(EfiBootServicesData, FileSize, (VOID**)&FileData);
if (EFI_ERROR(Status)) {
Print(L"Failed to allocate pool for file data: %r\r\n", Status);
goto Exit;
}
Status = FileHandle->Read(FileHandle, &FileSize, FileData);
if (EFI_ERROR(Status)) {
Print(L"Failed to read file %s: %r\r\n", Filename, Status);
gBS->FreePool(FileData); // Free buffer on read error
FileData = NULL;
goto Exit;
}
Print(L"Successfully read %Lu bytes from %s.\r\n", FileSize, Filename);
// 8. Display/Process - print first 64 bytes for demonstration
Print(L"\r\nFirst 64 bytes of %s:\r\n", Filename);
for (UINTN i = 0; i < FileSize && i < 64; i++) {
Print(L"%02x ", FileData[i]);
if ((i + 1) % 16 == 0) {
Print(L"\r\n");
}
}
Print(L"\r\n");
// In a real scenario, you would now process FileData.
Exit:
// 9. Clean up
if (FileHandle != NULL) {
FileHandle->Close(FileHandle);
}
if (Root != NULL) {
Root->Close(Root); // Closing the root directory handle
}
if (FileData != NULL) {
gBS->FreePool(FileData);
}
if (FileInfo != NULL) {
gBS->FreePool(FileInfo);
}
if (Buffer != NULL) {
gBS->FreePool(Buffer);
}
// Give some time to see the output before exiting
gBS->Stall(5 * 1000 * 1000); // 5 seconds
return Status;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment