summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/QemuKernelLoaderFsDxe
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2020-02-29 13:59:52 +0100
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2020-03-05 19:45:05 +0000
commitf98608ab3f237595839a78d89dc6bd6c6c6b0252 (patch)
tree6c8def104ccd9416064f8191845079192866d2f4 /OvmfPkg/QemuKernelLoaderFsDxe
parent859b55443a4253bad8bb618d04a51b2ded67f24b (diff)
downloadedk2-f98608ab3f237595839a78d89dc6bd6c6c6b0252.tar.gz
edk2-f98608ab3f237595839a78d89dc6bd6c6c6b0252.tar.bz2
edk2-f98608ab3f237595839a78d89dc6bd6c6c6b0252.zip
OvmfPkg/QemuKernelLoaderFsDxe: add support for new Linux initrd device path
Linux v5.7 will introduce a new method to load the initial ramdisk (initrd) from the loader, using the LoadFile2 protocol installed on a special vendor GUIDed media device path. Add support for this to our QEMU command line kernel/initrd loader. Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2566 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Diffstat (limited to 'OvmfPkg/QemuKernelLoaderFsDxe')
-rw-r--r--OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c79
-rw-r--r--OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf2
2 files changed, 81 insertions, 0 deletions
diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
index 8ccb198317..869549f164 100644
--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
+++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
@@ -13,15 +13,18 @@
#include <Guid/FileInfo.h>
#include <Guid/FileSystemInfo.h>
#include <Guid/FileSystemVolumeLabelInfo.h>
+#include <Guid/LinuxEfiInitrdMedia.h>
#include <Guid/QemuKernelLoaderFsMedia.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Protocol/DevicePath.h>
+#include <Protocol/LoadFile2.h>
#include <Protocol/SimpleFileSystem.h>
//
@@ -84,6 +87,19 @@ STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mFileSystemDevicePath = {
}
};
+STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mInitrdDevicePath = {
+ {
+ {
+ MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,
+ { sizeof (VENDOR_DEVICE_PATH) }
+ },
+ LINUX_EFI_INITRD_MEDIA_GUID
+ }, {
+ END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ { sizeof (EFI_DEVICE_PATH_PROTOCOL) }
+ }
+};
+
//
// The "file in the EFI stub filesystem" abstraction.
//
@@ -839,6 +855,48 @@ STATIC CONST EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mFileSystem = {
StubFileSystemOpenVolume
};
+STATIC
+EFI_STATUS
+EFIAPI
+InitrdLoadFile2 (
+ IN EFI_LOAD_FILE2_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN BOOLEAN BootPolicy,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer OPTIONAL
+ )
+{
+ CONST KERNEL_BLOB *InitrdBlob = &mKernelBlob[KernelBlobTypeInitrd];
+
+ ASSERT (InitrdBlob->Size > 0);
+
+ if (BootPolicy) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (BufferSize == NULL || !IsDevicePathValid (FilePath, 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (FilePath->Type != END_DEVICE_PATH_TYPE ||
+ FilePath->SubType != END_ENTIRE_DEVICE_PATH_SUBTYPE) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (Buffer == NULL || *BufferSize < InitrdBlob->Size) {
+ *BufferSize = InitrdBlob->Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ CopyMem (Buffer, InitrdBlob->Data, InitrdBlob->Size);
+
+ *BufferSize = InitrdBlob->Size;
+ return EFI_SUCCESS;
+}
+
+STATIC CONST EFI_LOAD_FILE2_PROTOCOL mInitrdLoadFile2 = {
+ InitrdLoadFile2,
+};
//
// Utility functions.
@@ -949,6 +1007,7 @@ QemuKernelLoaderFsDxeEntrypoint (
KERNEL_BLOB *KernelBlob;
EFI_STATUS Status;
EFI_HANDLE FileSystemHandle;
+ EFI_HANDLE InitrdLoadFile2Handle;
if (!QemuFwCfgIsAvailable ()) {
return EFI_NOT_FOUND;
@@ -993,8 +1052,28 @@ QemuKernelLoaderFsDxeEntrypoint (
goto FreeBlobs;
}
+ if (KernelBlob[KernelBlobTypeInitrd].Size > 0) {
+ InitrdLoadFile2Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (&InitrdLoadFile2Handle,
+ &gEfiDevicePathProtocolGuid, &mInitrdDevicePath,
+ &gEfiLoadFile2ProtocolGuid, &mInitrdLoadFile2,
+ NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: InstallMultipleProtocolInterfaces(): %r\n",
+ __FUNCTION__, Status));
+ goto UninstallFileSystemHandle;
+ }
+ }
+
return EFI_SUCCESS;
+UninstallFileSystemHandle:
+ Status = gBS->UninstallMultipleProtocolInterfaces (FileSystemHandle,
+ &gEfiDevicePathProtocolGuid, &mFileSystemDevicePath,
+ &gEfiSimpleFileSystemProtocolGuid, &mFileSystem,
+ NULL);
+ ASSERT_EFI_ERROR (Status);
+
FreeBlobs:
while (BlobType > 0) {
CurrentBlob = &mKernelBlob[--BlobType];
diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
index 5ba88063de..7b35adb8e0 100644
--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
+++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
@@ -28,6 +28,7 @@
BaseLib
BaseMemoryLib
DebugLib
+ DevicePathLib
MemoryAllocationLib
QemuFwCfgLib
UefiBootServicesTableLib
@@ -42,6 +43,7 @@
[Protocols]
gEfiDevicePathProtocolGuid ## PRODUCES
+ gEfiLoadFile2ProtocolGuid ## PRODUCES
gEfiSimpleFileSystemProtocolGuid ## PRODUCES
[Depex]