From: jljusten Date: Fri, 2 Nov 2012 18:28:17 +0000 (+0000) Subject: OvmfPkg: Add support for qemu's -kernel parameter X-Git-Tag: edk2-stable201903~12902 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=52fba28994e9d54e552264a76cda1834122f04d7 OvmfPkg: Add support for qemu's -kernel parameter If QEMU's -kernel parameter was used, then download the kernel from the FwCfg interface, and launch it. (See -kernel, -initrd, -append) The application uses the LoadLinuxLib to boot the kernel image. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jordan Justen Reviewed-by: Laszlo Ersek git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13923 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c index d6e1e93399..781b415178 100644 --- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c +++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c @@ -1127,6 +1127,11 @@ Returns: // PlatformBdsConnectSequence (); + // + // Process QEMU's -kernel command line option + // + TryRunningQemuKernel (); + // // Give one chance to enter the setup if we // have the time out diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h index cf8bb12cde..72b0e149e0 100644 --- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h +++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h @@ -295,4 +295,15 @@ PlatformBdsEnterFrontPage ( IN BOOLEAN ConnectAllHappened ); +/** + Loads and boots UEFI Linux via the FwCfg interface. + + @retval EFI_NOT_FOUND - The Linux kernel was not found + +**/ +EFI_STATUS +TryRunningQemuKernel ( + VOID + ); + #endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_ diff --git a/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf b/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf index 81602f5e61..7f7f473794 100644 --- a/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf +++ b/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf @@ -18,7 +18,7 @@ FILE_GUID = F844172E-9985-44f2-BADE-0DD783462E95 MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 - LIBRARY_CLASS = PlatformBdsLib|DXE_DRIVER + LIBRARY_CLASS = PlatformBdsLib|DXE_DRIVER # # The following information is for reference only and not required by the build tools. @@ -30,6 +30,7 @@ BdsPlatform.c PlatformData.c QemuBootOrder.c + QemuKernel.c BdsPlatform.h QemuBootOrder.h @@ -50,6 +51,7 @@ PciLib NvVarsFileLib QemuFwCfgLib + LoadLinuxLib [Pcd] gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPlatformBootTimeOut diff --git a/OvmfPkg/Library/PlatformBdsLib/QemuKernel.c b/OvmfPkg/Library/PlatformBdsLib/QemuKernel.c new file mode 100644 index 0000000000..fa8bcbc9bf --- /dev/null +++ b/OvmfPkg/Library/PlatformBdsLib/QemuKernel.c @@ -0,0 +1,159 @@ +/** @file + + Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include +#include +#include +#include +#include + + +EFI_STATUS +TryRunningQemuKernel ( + VOID + ) +{ + EFI_STATUS Status; + UINTN KernelSize; + UINTN KernelInitialSize; + VOID *KernelBuf; + UINTN SetupSize; + VOID *SetupBuf; + UINTN CommandLineSize; + CHAR8 *CommandLine; + UINTN InitrdSize; + VOID* InitrdData; + + SetupBuf = NULL; + SetupSize = 0; + KernelBuf = NULL; + KernelInitialSize = 0; + CommandLine = NULL; + CommandLineSize = 0; + InitrdData = NULL; + InitrdSize = 0; + + if (!QemuFwCfgIsAvailable ()) { + return EFI_NOT_FOUND; + } + + QemuFwCfgSelectItem (QemuFwCfgItemKernelSize); + KernelSize = (UINTN) QemuFwCfgRead64 (); + + QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupSize); + SetupSize = (UINTN) QemuFwCfgRead64 (); + + if (KernelSize == 0 || SetupSize == 0) { + DEBUG ((EFI_D_INFO, "qemu -kernel was not used.\n")); + return EFI_NOT_FOUND; + } + + SetupBuf = LoadLinuxAllocateKernelSetupPages (EFI_SIZE_TO_PAGES (SetupSize)); + if (SetupBuf == NULL) { + DEBUG ((EFI_D_ERROR, "Unable to allocate memory for kernel setup!\n")); + return EFI_OUT_OF_RESOURCES; + } + + DEBUG ((EFI_D_INFO, "Setup size: 0x%x\n", (UINT32) SetupSize)); + DEBUG ((EFI_D_INFO, "Reading kernel setup image ...")); + QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupData); + QemuFwCfgReadBytes (SetupSize, SetupBuf); + DEBUG ((EFI_D_INFO, " [done]\n")); + + Status = LoadLinuxCheckKernelSetup (SetupBuf, SetupSize); + if (EFI_ERROR (Status)) { + goto FreeAndReturn; + } + + KernelInitialSize = LoadLinuxGetKernelSize (SetupBuf, KernelSize); + if (KernelInitialSize == 0) { + Status = EFI_UNSUPPORTED; + goto FreeAndReturn; + } + + KernelBuf = LoadLinuxAllocateKernelPages ( + SetupBuf, + EFI_SIZE_TO_PAGES (KernelInitialSize)); + if (KernelBuf == NULL) { + DEBUG ((EFI_D_ERROR, "Unable to allocate memory for kernel!\n")); + Status = EFI_OUT_OF_RESOURCES; + goto FreeAndReturn; + } + + DEBUG ((EFI_D_INFO, "Kernel size: 0x%x\n", (UINT32) KernelSize)); + DEBUG ((EFI_D_INFO, "Reading kernel image ...")); + QemuFwCfgSelectItem (QemuFwCfgItemKernelData); + QemuFwCfgReadBytes (KernelSize, KernelBuf); + DEBUG ((EFI_D_INFO, " [done]\n")); + + QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize); + CommandLineSize = (UINTN) QemuFwCfgRead64 (); + + if (CommandLineSize > 0) { + CommandLine = LoadLinuxAllocateCommandLinePages ( + EFI_SIZE_TO_PAGES (CommandLineSize)); + QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData); + QemuFwCfgReadBytes (CommandLineSize, CommandLine); + } else { + CommandLine = NULL; + } + + Status = LoadLinuxSetCommandLine (SetupBuf, CommandLine); + if (EFI_ERROR (Status)) { + goto FreeAndReturn; + } + + QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize); + InitrdSize = (UINTN) QemuFwCfgRead64 (); + + if (InitrdSize > 0) { + InitrdData = LoadLinuxAllocateInitrdPages ( + SetupBuf, + EFI_SIZE_TO_PAGES (InitrdSize) + ); + DEBUG ((EFI_D_INFO, "Initrd size: 0x%x\n", (UINT32) InitrdSize)); + DEBUG ((EFI_D_INFO, "Reading initrd image ...")); + QemuFwCfgSelectItem (QemuFwCfgItemInitrdData); + QemuFwCfgReadBytes (InitrdSize, InitrdData); + DEBUG ((EFI_D_INFO, " [done]\n")); + } else { + InitrdData = NULL; + } + + Status = LoadLinuxSetInitrd (SetupBuf, InitrdData, InitrdSize); + if (EFI_ERROR (Status)) { + goto FreeAndReturn; + } + + Status = LoadLinux (KernelBuf, SetupBuf); + +FreeAndReturn: + if (SetupBuf != NULL) { + FreePages (SetupBuf, EFI_SIZE_TO_PAGES (SetupSize)); + } + if (KernelBuf != NULL) { + FreePages (KernelBuf, EFI_SIZE_TO_PAGES (KernelInitialSize)); + } + if (CommandLine != NULL) { + FreePages (CommandLine, EFI_SIZE_TO_PAGES (CommandLineSize)); + } + if (InitrdData != NULL) { + FreePages (InitrdData, EFI_SIZE_TO_PAGES (InitrdSize)); + } + + return Status; +} +