]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/QemuKernelLoaderFsDxe: add support for new Linux initrd device path
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Sat, 29 Feb 2020 12:59:52 +0000 (13:59 +0100)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 5 Mar 2020 19:45:05 +0000 (19:45 +0000)
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>
OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf

index 8ccb1983170c11c7ecca8511f32f53242c5ac611..869549f164f0d523b8d562fc190633b32e7f6a6e 100644 (file)
 #include <Guid/FileInfo.h>\r
 #include <Guid/FileSystemInfo.h>\r
 #include <Guid/FileSystemVolumeLabelInfo.h>\r
+#include <Guid/LinuxEfiInitrdMedia.h>\r
 #include <Guid/QemuKernelLoaderFsMedia.h>\r
 #include <Library/BaseLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
+#include <Library/DevicePathLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/QemuFwCfgLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UefiRuntimeServicesTableLib.h>\r
 #include <Protocol/DevicePath.h>\r
+#include <Protocol/LoadFile2.h>\r
 #include <Protocol/SimpleFileSystem.h>\r
 \r
 //\r
@@ -84,6 +87,19 @@ STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mFileSystemDevicePath = {
   }\r
 };\r
 \r
+STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mInitrdDevicePath = {\r
+  {\r
+    {\r
+      MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,\r
+      { sizeof (VENDOR_DEVICE_PATH) }\r
+    },\r
+    LINUX_EFI_INITRD_MEDIA_GUID\r
+  }, {\r
+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+    { sizeof (EFI_DEVICE_PATH_PROTOCOL) }\r
+  }\r
+};\r
+\r
 //\r
 // The "file in the EFI stub filesystem" abstraction.\r
 //\r
@@ -839,6 +855,48 @@ STATIC CONST EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mFileSystem = {
   StubFileSystemOpenVolume\r
 };\r
 \r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+InitrdLoadFile2 (\r
+  IN      EFI_LOAD_FILE2_PROTOCOL       *This,\r
+  IN      EFI_DEVICE_PATH_PROTOCOL      *FilePath,\r
+  IN      BOOLEAN                       BootPolicy,\r
+  IN  OUT UINTN                         *BufferSize,\r
+  OUT     VOID                          *Buffer     OPTIONAL\r
+  )\r
+{\r
+  CONST KERNEL_BLOB   *InitrdBlob = &mKernelBlob[KernelBlobTypeInitrd];\r
+\r
+  ASSERT (InitrdBlob->Size > 0);\r
+\r
+  if (BootPolicy) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (BufferSize == NULL || !IsDevicePathValid (FilePath, 0)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (FilePath->Type != END_DEVICE_PATH_TYPE ||\r
+      FilePath->SubType != END_ENTIRE_DEVICE_PATH_SUBTYPE) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  if (Buffer == NULL || *BufferSize < InitrdBlob->Size) {\r
+    *BufferSize = InitrdBlob->Size;\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  CopyMem (Buffer, InitrdBlob->Data, InitrdBlob->Size);\r
+\r
+  *BufferSize = InitrdBlob->Size;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC CONST EFI_LOAD_FILE2_PROTOCOL     mInitrdLoadFile2 = {\r
+  InitrdLoadFile2,\r
+};\r
 \r
 //\r
 // Utility functions.\r
@@ -949,6 +1007,7 @@ QemuKernelLoaderFsDxeEntrypoint (
   KERNEL_BLOB               *KernelBlob;\r
   EFI_STATUS                Status;\r
   EFI_HANDLE                FileSystemHandle;\r
+  EFI_HANDLE                InitrdLoadFile2Handle;\r
 \r
   if (!QemuFwCfgIsAvailable ()) {\r
     return EFI_NOT_FOUND;\r
@@ -993,8 +1052,28 @@ QemuKernelLoaderFsDxeEntrypoint (
     goto FreeBlobs;\r
   }\r
 \r
+  if (KernelBlob[KernelBlobTypeInitrd].Size > 0) {\r
+    InitrdLoadFile2Handle = NULL;\r
+    Status = gBS->InstallMultipleProtocolInterfaces (&InitrdLoadFile2Handle,\r
+                    &gEfiDevicePathProtocolGuid,  &mInitrdDevicePath,\r
+                    &gEfiLoadFile2ProtocolGuid,   &mInitrdLoadFile2,\r
+                    NULL);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_ERROR, "%a: InstallMultipleProtocolInterfaces(): %r\n",\r
+        __FUNCTION__, Status));\r
+      goto UninstallFileSystemHandle;\r
+    }\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 \r
+UninstallFileSystemHandle:\r
+  Status = gBS->UninstallMultipleProtocolInterfaces (FileSystemHandle,\r
+                  &gEfiDevicePathProtocolGuid,       &mFileSystemDevicePath,\r
+                  &gEfiSimpleFileSystemProtocolGuid, &mFileSystem,\r
+                  NULL);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
 FreeBlobs:\r
   while (BlobType > 0) {\r
     CurrentBlob = &mKernelBlob[--BlobType];\r
index 5ba88063def02902d4600b2ccf7ea58b948e7ad5..7b35adb8e0342ab438932fd39c57a0ab6abeee5d 100644 (file)
@@ -28,6 +28,7 @@
   BaseLib\r
   BaseMemoryLib\r
   DebugLib\r
+  DevicePathLib\r
   MemoryAllocationLib\r
   QemuFwCfgLib\r
   UefiBootServicesTableLib\r
@@ -42,6 +43,7 @@
 \r
 [Protocols]\r
   gEfiDevicePathProtocolGuid                ## PRODUCES\r
+  gEfiLoadFile2ProtocolGuid                 ## PRODUCES\r
   gEfiSimpleFileSystemProtocolGuid          ## PRODUCES\r
 \r
 [Depex]\r