1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
#include <Uefi.h> #include <Library/UefiLib.h> #include <Library/ShellLib.h> #include <Protocol/FirmwareManagement.h> #include <Protocol/LoadedImage.h> #include <Protocol/SimpleFileSystem.h>
EFI_GUID gEfiFirmwareManagementProtocolGuid = { 0x86570D99, 0x6E70, 0x464D, { 0xA0, 0x8F, 0x7F, 0x51, 0x83, 0x51, 0xA6, 0x7E } };
VOID PrintFirmwareInfo( IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *Descriptor ) { Print(L"========================================\n"); Print(L" BH799 Firmware Information\n"); Print(L"========================================\n"); Print(L" Image Index: %d\n", Descriptor->ImageIndex); Print(L" Image ID: %s\n", Descriptor->ImageId); Print(L" Version: 0x%x (%d.%d.%d.%d)\n", Descriptor->ImageVersion, (Descriptor->ImageVersion >> 24) & 0xFF, (Descriptor->ImageVersion >> 16) & 0xFF, (Descriptor->ImageVersion >> 8) & 0xFF, Descriptor->ImageVersion & 0xFF); Print(L" Lowest Version: 0x%x\n", Descriptor->LowestSupportedImageVersion); Print(L" Image Size: %lu bytes\n", Descriptor->ImageSize); Print(L" Attributes: 0x%lx\n", Descriptor->Attributes); Print(L"========================================\n"); }
INTN EFIAPI UefiMain( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp; UINT32 ImageInfoSize; EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo; CHAR16 **Argv; UINTN Argc; CHAR16 *ImagePath; UINT8 *FileBuffer; UINTN FileSize; UINT32 ImageUpdatable;
Status = ShellGetArgcArgv((SHELL_ARGUMENT_PACKAGE**)&Argc, (CHAR16***)&Argv); if (EFI_ERROR(Status)) { Print(L"Error: Failed to get command line args\n"); return Status; }
Status = gBS->LocateProtocol( &gEfiFirmwareManagementProtocolGuid, NULL, (VOID**)&Fmp ); if (EFI_ERROR(Status)) { Print(L"Error: FMP Protocol not found. Please load FmpDxe first!\n"); return Status; }
if (Argc < 2) { Print(L"Usage:\n"); Print(L" BH799App -I : Query firmware info\n"); Print(L" BH799App -S <firmware.bin> : Update with version check\n"); Print(L" BH799App -U <firmware.bin> : Update without version check\n"); return EFI_INVALID_PARAMETER; }
if (StrCmp(Argv[1], L"-I") == 0) { ImageInfoSize = 0; Status = Fmp->GetImageInfo(Fmp, &ImageInfoSize, NULL, NULL, NULL, NULL, NULL, NULL); if (Status != EFI_BUFFER_TOO_SMALL) { Print(L"Error: GetImageInfo failed\n"); return Status; }
ImageInfo = AllocatePool(ImageInfoSize); Status = Fmp->GetImageInfo(Fmp, &ImageInfoSize, ImageInfo, NULL, NULL, NULL, NULL, NULL); if (EFI_ERROR(Status)) { Print(L"Error: GetImageInfo failed\n"); FreePool(ImageInfo); return Status; }
PrintFirmwareInfo(ImageInfo); FreePool(ImageInfo); } else if (StrCmp(Argv[1], L"-S") == 0 || StrCmp(Argv[1], L"-U") == 0) { if (Argc < 3) { Print(L"Error: Missing firmware file path\n"); return EFI_INVALID_PARAMETER; }
ImagePath = Argv[2];
Status = ReadFileToBuffer(ImagePath, &FileBuffer, &FileSize); if (EFI_ERROR(Status)) { Print(L"Error: Cannot read firmware file: %s\n", ImagePath); return Status; }
if (StrCmp(Argv[1], L"-S") == 0) { Status = Fmp->CheckImage(Fmp, FileBuffer, FileSize, &ImageUpdatable); if (EFI_ERROR(Status) || ImageUpdatable == 0) { Print(L"Error: CheckImage failed or image not updatable\n"); FreePool(FileBuffer); return EFI_ACCESS_DENIED; } Print(L"CheckImage passed, proceed to set image...\n"); }
Print(L"Starting firmware update...\n"); Status = Fmp->SetImage(Fmp, 1, FileBuffer, FileSize, 0, NULL, NULL); FreePool(FileBuffer);
if (EFI_ERROR(Status)) { Print(L"Error: Firmware update failed: %r\n", Status); return Status; }
Print(L"========================================\n"); Print(L" Firmware update completed!\n"); Print(L" Please reboot to activate new firmware.\n"); Print(L"========================================\n"); } else { Print(L"Error: Unknown command: %s\n", Argv[1]); return EFI_INVALID_PARAMETER; }
return EFI_SUCCESS; }
|