mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-07 19:45:07 +02:00
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>
This commit is contained in:
parent
859b55443a
commit
f98608ab3f
@ -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];
|
||||
|
@ -28,6 +28,7 @@
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
DevicePathLib
|
||||
MemoryAllocationLib
|
||||
QemuFwCfgLib
|
||||
UefiBootServicesTableLib
|
||||
@ -42,6 +43,7 @@
|
||||
|
||||
[Protocols]
|
||||
gEfiDevicePathProtocolGuid ## PRODUCES
|
||||
gEfiLoadFile2ProtocolGuid ## PRODUCES
|
||||
gEfiSimpleFileSystemProtocolGuid ## PRODUCES
|
||||
|
||||
[Depex]
|
||||
|
Loading…
x
Reference in New Issue
Block a user