diff --git a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c b/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c index b99fb350aa8f..75a267c8e3d2 100644 --- a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c +++ b/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c @@ -57,6 +57,25 @@ STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH mKernelDevicePath = { } }; +STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH mShimDevicePath = { + { + { + MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, + { sizeof (VENDOR_DEVICE_PATH) } + }, + QEMU_KERNEL_LOADER_FS_MEDIA_GUID + }, { + { + MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, + { sizeof (KERNEL_FILE_DEVPATH) } + }, + L"shim", + }, { + END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, + { sizeof (EFI_DEVICE_PATH_PROTOCOL) } + } +}; + STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mQemuKernelLoaderFsDevicePath = { { { @@ -174,6 +193,7 @@ QemuLoadKernelImage ( UINTN CommandLineSize; CHAR8 *CommandLine; UINTN InitrdSize; + BOOLEAN Shim; // // Load the image. This should call back into the QEMU EFI loader file system. @@ -181,11 +201,30 @@ QemuLoadKernelImage ( Status = gBS->LoadImage ( FALSE, // BootPolicy: exact match required gImageHandle, // ParentImageHandle - (EFI_DEVICE_PATH_PROTOCOL *)&mKernelDevicePath, + (EFI_DEVICE_PATH_PROTOCOL *)&mShimDevicePath, NULL, // SourceBuffer 0, // SourceSize &KernelImageHandle ); + if (Status == EFI_SUCCESS) { + Shim = TRUE; + DEBUG ((DEBUG_INFO, "%a: booting via shim\n", __func__)); + } else { + Shim = FALSE; + if (Status == EFI_SECURITY_VIOLATION) { + gBS->UnloadImage (KernelImageHandle); + } + + Status = gBS->LoadImage ( + FALSE, // BootPolicy: exact match required + gImageHandle, // ParentImageHandle + (EFI_DEVICE_PATH_PROTOCOL *)&mKernelDevicePath, + NULL, // SourceBuffer + 0, // SourceSize + &KernelImageHandle + ); + } + switch (Status) { case EFI_SUCCESS: break; @@ -303,6 +342,13 @@ QemuLoadKernelImage ( KernelLoadedImage->LoadOptionsSize += sizeof (L" initrd=initrd") - 2; } + if (Shim) { + // + // Prefix 'kernel ' in UTF-16. + // + KernelLoadedImage->LoadOptionsSize += sizeof (L"kernel ") - 2; + } + if (KernelLoadedImage->LoadOptionsSize == 0) { KernelLoadedImage->LoadOptions = NULL; } else { @@ -323,7 +369,8 @@ QemuLoadKernelImage ( UnicodeSPrintAsciiFormat ( KernelLoadedImage->LoadOptions, KernelLoadedImage->LoadOptionsSize, - "%a%a", + "%a%a%a", + (Shim == FALSE) ? "" : "kernel ", (CommandLineSize == 0) ? "" : CommandLine, (InitrdSize == 0) ? "" : " initrd=initrd" );