37 KernelBlobTypeCommandLine,
44 FIRMWARE_CONFIG_ITEM
CONST SizeKey;
45 FIRMWARE_CONFIG_ITEM
CONST DataKey;
56 { QemuFwCfgItemKernelSetupSize, QemuFwCfgItemKernelSetupData, },
57 { QemuFwCfgItemKernelSize, QemuFwCfgItemKernelData, },
62 { QemuFwCfgItemInitrdSize, QemuFwCfgItemInitrdData, },
67 { QemuFwCfgItemCommandLineSize, QemuFwCfgItemCommandLineData, },
72STATIC UINT64 mTotalBlobBytes;
90 QEMU_KERNEL_LOADER_FS_MEDIA_GUID
92 END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
103 LINUX_EFI_INITRD_MEDIA_GUID
105 END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
115#define STUB_FILE_SIG SIGNATURE_64 ('S', 'T', 'U', 'B', 'F', 'I', 'L', 'E')
120 KERNEL_BLOB_TYPE BlobType;
130#define STUB_FILE_FROM_FILE(FilePointer) \
131 CR (FilePointer, STUB_FILE, File, STUB_FILE_SIG)
203 FreePool (STUB_FILE_FROM_FILE (This));
226 FreePool (STUB_FILE_FROM_FILE (This));
227 return EFI_WARN_DELETE_FAILURE;
261 IN KERNEL_BLOB_TYPE BlobType,
273 UINTN OriginalBufferSize;
275 if (BlobType == KernelBlobTypeMax) {
280 FileSize = KernelBlobTypeMax;
281 Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
285 Blob = &mKernelBlob[BlobType];
287 FileSize = Blob->Size;
288 Attribute = EFI_FILE_READ_ONLY;
291 NameSize = (
StrLen (Name) + 1) * 2;
293 ASSERT (FileInfoSize >=
sizeof *
FileInfo);
295 OriginalBufferSize = *BufferSize;
296 *BufferSize = FileInfoSize;
297 if (OriginalBufferSize < *BufferSize) {
298 return EFI_BUFFER_TOO_SMALL;
362 StubFile = STUB_FILE_FROM_FILE (This);
367 if (StubFile->BlobType == KernelBlobTypeMax) {
370 if (StubFile->Position == KernelBlobTypeMax) {
379 (KERNEL_BLOB_TYPE)StubFile->Position,
383 if (EFI_ERROR (Status)) {
387 ++StubFile->Position;
394 Blob = &mKernelBlob[StubFile->BlobType];
395 if (StubFile->Position > Blob->Size) {
396 return EFI_DEVICE_ERROR;
399 Left = Blob->Size - StubFile->Position;
400 if (*BufferSize > Left) {
401 *BufferSize = (
UINTN)Left;
404 if (Blob->Data !=
NULL) {
405 CopyMem (Buffer, Blob->Data + StubFile->Position, *BufferSize);
408 StubFile->Position += *BufferSize;
446 StubFile = STUB_FILE_FROM_FILE (This);
447 return (StubFile->BlobType == KernelBlobTypeMax) ?
476 StubFile = STUB_FILE_FROM_FILE (This);
477 if (StubFile->BlobType == KernelBlobTypeMax) {
478 return EFI_UNSUPPORTED;
481 *Position = StubFile->Position;
512 StubFile = STUB_FILE_FROM_FILE (This);
514 if (StubFile->BlobType == KernelBlobTypeMax) {
519 StubFile->Position = 0;
523 return EFI_UNSUPPORTED;
529 Blob = &mKernelBlob[StubFile->BlobType];
530 if (Position == MAX_UINT64) {
534 StubFile->Position = Blob->Size;
539 StubFile->Position = Position;
594 UINTN OriginalBufferSize;
596 StubFile = STUB_FILE_FROM_FILE (This);
598 if (
CompareGuid (InformationType, &gEfiFileInfoGuid)) {
606 OriginalBufferSize = *BufferSize;
608 if (
CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
611 *BufferSize =
sizeof *FileSystemInfo;
612 if (OriginalBufferSize < *BufferSize) {
613 return EFI_BUFFER_TOO_SMALL;
617 FileSystemInfo->
Size =
sizeof *FileSystemInfo;
627 if (
CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
630 *BufferSize =
sizeof *FileSystemVolumeLabel;
631 if (OriginalBufferSize < *BufferSize) {
632 return EFI_BUFFER_TOO_SMALL;
641 return EFI_UNSUPPORTED;
695 return EFI_WRITE_PROTECTED;
719 return EFI_WRITE_PROTECTED;
726 EFI_FILE_PROTOCOL_REVISION,
762 case EFI_FILE_MODE_READ:
765 case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
766 case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:
767 return EFI_WRITE_PROTECTED;
770 return EFI_INVALID_PARAMETER;
776 StubFile = STUB_FILE_FROM_FILE (This);
777 if (StubFile->BlobType != KernelBlobTypeMax) {
778 return EFI_UNSUPPORTED;
784 for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) {
785 if (
StrCmp (FileName, mKernelBlob[BlobType].Name) == 0) {
790 if (BlobType == KernelBlobTypeMax) {
791 return EFI_NOT_FOUND;
798 if (NewStubFile ==
NULL) {
799 return EFI_OUT_OF_RESOURCES;
802 NewStubFile->Signature = STUB_FILE_SIG;
803 NewStubFile->BlobType = (KERNEL_BLOB_TYPE)BlobType;
804 NewStubFile->Position = 0;
807 &mEfiFileProtocolTemplate,
808 sizeof mEfiFileProtocolTemplate
810 *NewHandle = &NewStubFile->File;
853 if (StubFile ==
NULL) {
854 return EFI_OUT_OF_RESOURCES;
857 StubFile->Signature = STUB_FILE_SIG;
858 StubFile->BlobType = KernelBlobTypeMax;
859 StubFile->Position = 0;
862 &mEfiFileProtocolTemplate,
863 sizeof mEfiFileProtocolTemplate
865 *Root = &StubFile->File;
871 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
881 IN BOOLEAN BootPolicy,
883 OUT VOID *Buffer OPTIONAL
888 ASSERT (InitrdBlob->Size > 0);
891 return EFI_UNSUPPORTED;
895 return EFI_INVALID_PARAMETER;
898 if ((FilePath->Type != END_DEVICE_PATH_TYPE) ||
899 (FilePath->SubType != END_ENTIRE_DEVICE_PATH_SUBTYPE))
901 return EFI_NOT_FOUND;
904 if ((Buffer ==
NULL) || (*BufferSize < InitrdBlob->Size)) {
905 *BufferSize = InitrdBlob->Size;
906 return EFI_BUFFER_TOO_SMALL;
909 CopyMem (Buffer, InitrdBlob->Data, InitrdBlob->Size);
911 *BufferSize = InitrdBlob->Size;
949 for (Idx = 0; Idx <
ARRAY_SIZE (Blob->FwCfgItem); Idx++) {
950 if (Blob->FwCfgItem[Idx].SizeKey == 0) {
956 Blob->Size += Blob->FwCfgItem[Idx].Size;
959 if (Blob->Size == 0) {
967 if (Blob->Data ==
NULL) {
970 "%a: failed to allocate %Ld bytes for \"%s\"\n",
975 return EFI_OUT_OF_RESOURCES;
980 "%a: loading %Ld bytes for \"%s\"\n",
986 ChunkData = Blob->Data;
987 for (Idx = 0; Idx <
ARRAY_SIZE (Blob->FwCfgItem); Idx++) {
988 if (Blob->FwCfgItem[Idx].DataKey == 0) {
994 Left = Blob->FwCfgItem[Idx].Size;
998 Chunk = (Left < SIZE_1MB) ? Left : SIZE_1MB;
1003 "%a: %Ld bytes remaining for \"%s\" (%d)\n",
1011 ChunkData += Blob->FwCfgItem[Idx].Size;
1050 return EFI_NOT_FOUND;
1053 Status =
gRT->GetTime (&mInitTime,
NULL );
1054 if (EFI_ERROR (Status)) {
1055 DEBUG ((DEBUG_ERROR,
"%a: GetTime(): %r\n", __func__, Status));
1062 for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) {
1063 CurrentBlob = &mKernelBlob[BlobType];
1072 if (EFI_ERROR (Status)) {
1076 mTotalBlobBytes += CurrentBlob->Size;
1079 KernelBlob = &mKernelBlob[KernelBlobTypeKernel];
1081 if (KernelBlob->Data ==
NULL) {
1082 Status = EFI_NOT_FOUND;
1090 FileSystemHandle =
NULL;
1091 Status =
gBS->InstallMultipleProtocolInterfaces (
1093 &gEfiDevicePathProtocolGuid,
1094 &mFileSystemDevicePath,
1095 &gEfiSimpleFileSystemProtocolGuid,
1099 if (EFI_ERROR (Status)) {
1102 "%a: InstallMultipleProtocolInterfaces(): %r\n",
1109 if (KernelBlob[KernelBlobTypeInitrd].Size > 0) {
1110 InitrdLoadFile2Handle =
NULL;
1111 Status =
gBS->InstallMultipleProtocolInterfaces (
1112 &InitrdLoadFile2Handle,
1113 &gEfiDevicePathProtocolGuid,
1115 &gEfiLoadFile2ProtocolGuid,
1119 if (EFI_ERROR (Status)) {
1122 "%a: InstallMultipleProtocolInterfaces(): %r\n",
1126 goto UninstallFileSystemHandle;
1132UninstallFileSystemHandle:
1133 Status =
gBS->UninstallMultipleProtocolInterfaces (
1135 &gEfiDevicePathProtocolGuid,
1136 &mFileSystemDevicePath,
1137 &gEfiSimpleFileSystemProtocolGuid,
1144 while (BlobType > 0) {
1145 CurrentBlob = &mKernelBlob[--BlobType];
1146 if (CurrentBlob->Data !=
NULL) {
1148 CurrentBlob->Size = 0;
1149 CurrentBlob->Data =
NULL;
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
EFI_STATUS EFIAPI VerifyBlob(IN CONST CHAR16 *BlobName, IN CONST VOID *Buf, IN UINT32 BufSize, IN EFI_STATUS FetchStatus)
#define MEDIA_VENDOR_DP
Media vendor device path subtype.
BOOLEAN EFIAPI IsDevicePathValid(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN UINTN MaxSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_RUNTIME_SERVICES * gRT
#define ARRAY_SIZE(Array)
#define OFFSET_OF(TYPE, Field)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT32 EFIAPI QemuFwCfgRead32(VOID)
VOID EFIAPI QemuFwCfgReadBytes(IN UINTN Size, IN VOID *Buffer OPTIONAL)
VOID EFIAPI QemuFwCfgSelectItem(IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem)
BOOLEAN EFIAPI QemuFwCfgIsAvailable(VOID)
STATIC EFI_STATUS EFIAPI StubFileWrite(IN EFI_FILE_PROTOCOL *This, IN OUT UINTN *BufferSize, IN VOID *Buffer)
STATIC EFI_STATUS EFIAPI StubFileSystemOpenVolume(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, OUT EFI_FILE_PROTOCOL **Root)
STATIC EFI_STATUS EFIAPI StubFileClose(IN EFI_FILE_PROTOCOL *This)
STATIC EFI_STATUS EFIAPI StubFileOpen(IN EFI_FILE_PROTOCOL *This, OUT EFI_FILE_PROTOCOL **NewHandle, IN CHAR16 *FileName, IN UINT64 OpenMode, IN UINT64 Attributes)
STATIC EFI_STATUS EFIAPI StubFileSetPosition(IN EFI_FILE_PROTOCOL *This, IN UINT64 Position)
STATIC EFI_STATUS EFIAPI StubFileGetInfo(IN EFI_FILE_PROTOCOL *This, IN EFI_GUID *InformationType, IN OUT UINTN *BufferSize, OUT VOID *Buffer)
STATIC EFI_STATUS EFIAPI StubFileDelete(IN EFI_FILE_PROTOCOL *This)
STATIC EFI_STATUS EFIAPI StubFileGetPosition(IN EFI_FILE_PROTOCOL *This, OUT UINT64 *Position)
STATIC EFI_STATUS EFIAPI StubFileRead(IN EFI_FILE_PROTOCOL *This, IN OUT UINTN *BufferSize, OUT VOID *Buffer)
STATIC EFI_STATUS EFIAPI StubFileFlush(IN EFI_FILE_PROTOCOL *This)
STATIC EFI_STATUS ConvertKernelBlobTypeToFileInfo(IN KERNEL_BLOB_TYPE BlobType, IN OUT UINTN *BufferSize, OUT VOID *Buffer)
STATIC EFI_STATUS EFIAPI StubFileSetInfo(IN EFI_FILE_PROTOCOL *This, IN EFI_GUID *InformationType, IN UINTN BufferSize, IN VOID *Buffer)
EFI_STATUS EFIAPI QemuKernelLoaderFsDxeEntrypoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
STATIC EFI_STATUS FetchBlob(IN OUT KERNEL_BLOB *Blob)
EFI_FILE_INFO * FileInfo(IN EFI_FILE_HANDLE FHand)
EFI_TIME ModificationTime