#include <Base.h>\r
#include <Guid/QemuKernelLoaderFsMedia.h>\r
#include <Library/DebugLib.h>\r
+#include <Library/FileHandleLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
#include <Library/PrintLib.h>\r
-#include <Library/QemuFwCfgLib.h>\r
#include <Library/QemuLoadImageLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
#include <Protocol/DevicePath.h>\r
#include <Protocol/LoadedImage.h>\r
+#include <Protocol/SimpleFileSystem.h>\r
\r
#pragma pack (1)\r
typedef struct {\r
KERNEL_FILE_DEVPATH FileNode;\r
EFI_DEVICE_PATH_PROTOCOL EndNode;\r
} KERNEL_VENMEDIA_FILE_DEVPATH;\r
+\r
+typedef struct {\r
+ VENDOR_DEVICE_PATH VenMediaNode;\r
+ EFI_DEVICE_PATH_PROTOCOL EndNode;\r
+} SINGLE_VENMEDIA_NODE_DEVPATH;\r
#pragma pack ()\r
\r
STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH mKernelDevicePath = {\r
}\r
};\r
\r
+STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mQemuKernelLoaderFsDevicePath = {\r
+ {\r
+ {\r
+ MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,\r
+ { sizeof (VENDOR_DEVICE_PATH) }\r
+ },\r
+ QEMU_KERNEL_LOADER_FS_MEDIA_GUID\r
+ }, {\r
+ END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+ { sizeof (EFI_DEVICE_PATH_PROTOCOL) }\r
+ }\r
+};\r
+\r
+STATIC\r
+EFI_STATUS\r
+GetQemuKernelLoaderBlobSize (\r
+ IN EFI_FILE_HANDLE Root,\r
+ IN CHAR16 *FileName,\r
+ OUT UINTN *Size\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_FILE_HANDLE FileHandle;\r
+ UINT64 FileSize;\r
+\r
+ Status = Root->Open (Root, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ Status = FileHandleGetSize (FileHandle, &FileSize);\r
+ if (EFI_ERROR (Status)) {\r
+ goto CloseFile;\r
+ }\r
+ if (FileSize > MAX_UINTN) {\r
+ Status = EFI_UNSUPPORTED;\r
+ goto CloseFile;\r
+ }\r
+ *Size = (UINTN)FileSize;\r
+ Status = EFI_SUCCESS;\r
+CloseFile:\r
+ FileHandle->Close (FileHandle);\r
+ return Status;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+ReadWholeQemuKernelLoaderBlob (\r
+ IN EFI_FILE_HANDLE Root,\r
+ IN CHAR16 *FileName,\r
+ IN UINTN Size,\r
+ OUT VOID *Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_FILE_HANDLE FileHandle;\r
+ UINTN ReadSize;\r
+\r
+ Status = Root->Open (Root, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ ReadSize = Size;\r
+ Status = FileHandle->Read (FileHandle, &ReadSize, Buffer);\r
+ if (EFI_ERROR (Status)) {\r
+ goto CloseFile;\r
+ }\r
+ if (ReadSize != Size) {\r
+ Status = EFI_PROTOCOL_ERROR;\r
+ goto CloseFile;\r
+ }\r
+ Status = EFI_SUCCESS;\r
+CloseFile:\r
+ FileHandle->Close (FileHandle);\r
+ return Status;\r
+}\r
+\r
/**\r
Download the kernel, the initial ramdisk, and the kernel command line from\r
QEMU's fw_cfg. The kernel will be instructed via its command line to load\r
OUT EFI_HANDLE *ImageHandle\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_HANDLE KernelImageHandle;\r
- EFI_LOADED_IMAGE_PROTOCOL *KernelLoadedImage;\r
- UINTN CommandLineSize;\r
- CHAR8 *CommandLine;\r
- UINTN InitrdSize;\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE KernelImageHandle;\r
+ EFI_LOADED_IMAGE_PROTOCOL *KernelLoadedImage;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;\r
+ EFI_HANDLE FsVolumeHandle;\r
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FsProtocol;\r
+ EFI_FILE_HANDLE Root;\r
+ UINTN CommandLineSize;\r
+ CHAR8 *CommandLine;\r
+ UINTN InitrdSize;\r
\r
//\r
// Load the image. This should call back into the QEMU EFI loader file system.\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
- QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);\r
- CommandLineSize = (UINTN)QemuFwCfgRead32 ();\r
+ //\r
+ // Open the Qemu Kernel Loader abstract filesystem (volume) which will be\r
+ // used to query the "initrd" and to read the "cmdline" synthetic files.\r
+ //\r
+ DevicePathNode = (EFI_DEVICE_PATH_PROTOCOL *)&mQemuKernelLoaderFsDevicePath;\r
+ Status = gBS->LocateDevicePath (\r
+ &gEfiSimpleFileSystemProtocolGuid,\r
+ &DevicePathNode,\r
+ &FsVolumeHandle\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto UnloadImage;\r
+ }\r
+\r
+ Status = gBS->HandleProtocol (\r
+ FsVolumeHandle,\r
+ &gEfiSimpleFileSystemProtocolGuid,\r
+ (VOID **)&FsProtocol\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto UnloadImage;\r
+ }\r
+\r
+ Status = FsProtocol->OpenVolume (FsVolumeHandle, &Root);\r
+ if (EFI_ERROR (Status)) {\r
+ goto UnloadImage;\r
+ }\r
+\r
+ Status = GetQemuKernelLoaderBlobSize (Root, L"cmdline", &CommandLineSize);\r
+ if (EFI_ERROR (Status)) {\r
+ goto CloseRoot;\r
+ }\r
\r
if (CommandLineSize == 0) {\r
KernelLoadedImage->LoadOptionsSize = 0;\r
CommandLine = AllocatePool (CommandLineSize);\r
if (CommandLine == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
- goto UnloadImage;\r
+ goto CloseRoot;\r
}\r
\r
- QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData);\r
- QemuFwCfgReadBytes (CommandLineSize, CommandLine);\r
+ Status = ReadWholeQemuKernelLoaderBlob (Root, L"cmdline", CommandLineSize,\r
+ CommandLine);\r
+ if (EFI_ERROR (Status)) {\r
+ goto FreeCommandLine;\r
+ }\r
\r
//\r
// Verify NUL-termination of the command line.\r
KernelLoadedImage->LoadOptionsSize = (UINT32)((CommandLineSize - 1) * 2);\r
}\r
\r
- QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);\r
- InitrdSize = (UINTN)QemuFwCfgRead32 ();\r
+ Status = GetQemuKernelLoaderBlobSize (Root, L"initrd", &InitrdSize);\r
+ if (EFI_ERROR (Status)) {\r
+ goto FreeCommandLine;\r
+ }\r
\r
if (InitrdSize > 0) {\r
//\r
if (CommandLineSize > 0) {\r
FreePool (CommandLine);\r
}\r
+CloseRoot:\r
+ Root->Close (Root);\r
UnloadImage:\r
if (EFI_ERROR (Status)) {\r
gBS->UnloadImage (KernelImageHandle);\r