]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: Add support for qemu's -kernel parameter
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 2 Nov 2012 18:28:17 +0000 (18:28 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 2 Nov 2012 18:28:17 +0000 (18:28 +0000)
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 <jordan.l.justen@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13923 6f19259b-4bc3-4df7-8a09-765794883524

OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h
OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
OvmfPkg/Library/PlatformBdsLib/QemuKernel.c [new file with mode: 0644]

index d6e1e93399170340200de82b7c75e2c0e1da10cd..781b415178ae6420fb3580632356fddc7f6b53d6 100644 (file)
@@ -1127,6 +1127,11 @@ Returns:
   //\r
   PlatformBdsConnectSequence ();\r
 \r
+  //\r
+  // Process QEMU's -kernel command line option\r
+  //\r
+  TryRunningQemuKernel ();\r
+\r
   //\r
   // Give one chance to enter the setup if we\r
   // have the time out\r
index cf8bb12cde54e08eb06d01cbfb1d3dfa8eb9479c..72b0e149e0534db3f6df6a9d20be11ced0306e1a 100644 (file)
@@ -295,4 +295,15 @@ PlatformBdsEnterFrontPage (
   IN BOOLEAN                ConnectAllHappened\r
   );\r
 \r
+/**\r
+  Loads and boots UEFI Linux via the FwCfg interface.\r
+\r
+  @retval    EFI_NOT_FOUND - The Linux kernel was not found\r
+\r
+**/\r
+EFI_STATUS\r
+TryRunningQemuKernel (\r
+  VOID\r
+  );\r
+\r
 #endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_\r
index 81602f5e61ec9068924f094bd6fb6d95986294f2..7f7f4737944a44c3694b30c96c566d467ed8927e 100644 (file)
@@ -18,7 +18,7 @@
   FILE_GUID                      = F844172E-9985-44f2-BADE-0DD783462E95\r
   MODULE_TYPE                    = DXE_DRIVER\r
   VERSION_STRING                 = 1.0\r
-  LIBRARY_CLASS                  = PlatformBdsLib|DXE_DRIVER   \r
+  LIBRARY_CLASS                  = PlatformBdsLib|DXE_DRIVER\r
 \r
 #\r
 # The following information is for reference only and not required by the build tools.\r
@@ -30,6 +30,7 @@
   BdsPlatform.c\r
   PlatformData.c\r
   QemuBootOrder.c\r
+  QemuKernel.c\r
   BdsPlatform.h\r
   QemuBootOrder.h\r
 \r
@@ -50,6 +51,7 @@
   PciLib\r
   NvVarsFileLib\r
   QemuFwCfgLib\r
+  LoadLinuxLib\r
 \r
 [Pcd]\r
   gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPlatformBootTimeOut\r
diff --git a/OvmfPkg/Library/PlatformBdsLib/QemuKernel.c b/OvmfPkg/Library/PlatformBdsLib/QemuKernel.c
new file mode 100644 (file)
index 0000000..fa8bcbc
--- /dev/null
@@ -0,0 +1,159 @@
+/** @file\r
+\r
+  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/LoadLinuxLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/QemuFwCfgLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+\r
+EFI_STATUS\r
+TryRunningQemuKernel (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  UINTN                     KernelSize;\r
+  UINTN                     KernelInitialSize;\r
+  VOID                      *KernelBuf;\r
+  UINTN                     SetupSize;\r
+  VOID                      *SetupBuf;\r
+  UINTN                     CommandLineSize;\r
+  CHAR8                     *CommandLine;\r
+  UINTN                     InitrdSize;\r
+  VOID*                     InitrdData;\r
+\r
+  SetupBuf = NULL;\r
+  SetupSize = 0;\r
+  KernelBuf = NULL;\r
+  KernelInitialSize = 0;\r
+  CommandLine = NULL;\r
+  CommandLineSize = 0;\r
+  InitrdData = NULL;\r
+  InitrdSize = 0;\r
+\r
+  if (!QemuFwCfgIsAvailable ()) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  QemuFwCfgSelectItem (QemuFwCfgItemKernelSize);\r
+  KernelSize = (UINTN) QemuFwCfgRead64 ();\r
+\r
+  QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupSize);\r
+  SetupSize = (UINTN) QemuFwCfgRead64 ();\r
+\r
+  if (KernelSize == 0 || SetupSize == 0) {\r
+    DEBUG ((EFI_D_INFO, "qemu -kernel was not used.\n"));\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  SetupBuf = LoadLinuxAllocateKernelSetupPages (EFI_SIZE_TO_PAGES (SetupSize));\r
+  if (SetupBuf == NULL) {\r
+    DEBUG ((EFI_D_ERROR, "Unable to allocate memory for kernel setup!\n"));\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "Setup size: 0x%x\n", (UINT32) SetupSize));\r
+  DEBUG ((EFI_D_INFO, "Reading kernel setup image ..."));\r
+  QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupData);\r
+  QemuFwCfgReadBytes (SetupSize, SetupBuf);\r
+  DEBUG ((EFI_D_INFO, " [done]\n"));\r
+\r
+  Status = LoadLinuxCheckKernelSetup (SetupBuf, SetupSize);\r
+  if (EFI_ERROR (Status)) {\r
+    goto FreeAndReturn;\r
+  }\r
+\r
+  KernelInitialSize = LoadLinuxGetKernelSize (SetupBuf, KernelSize);\r
+  if (KernelInitialSize == 0) {\r
+    Status = EFI_UNSUPPORTED;\r
+    goto FreeAndReturn;\r
+  }\r
+\r
+  KernelBuf = LoadLinuxAllocateKernelPages (\r
+                SetupBuf,\r
+                EFI_SIZE_TO_PAGES (KernelInitialSize));\r
+  if (KernelBuf == NULL) {\r
+    DEBUG ((EFI_D_ERROR, "Unable to allocate memory for kernel!\n"));\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto FreeAndReturn;\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "Kernel size: 0x%x\n", (UINT32) KernelSize));\r
+  DEBUG ((EFI_D_INFO, "Reading kernel image ..."));\r
+  QemuFwCfgSelectItem (QemuFwCfgItemKernelData);\r
+  QemuFwCfgReadBytes (KernelSize, KernelBuf);\r
+  DEBUG ((EFI_D_INFO, " [done]\n"));\r
+\r
+  QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);\r
+  CommandLineSize = (UINTN) QemuFwCfgRead64 ();\r
+\r
+  if (CommandLineSize > 0) {\r
+    CommandLine = LoadLinuxAllocateCommandLinePages (\r
+                    EFI_SIZE_TO_PAGES (CommandLineSize));\r
+    QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData);\r
+    QemuFwCfgReadBytes (CommandLineSize, CommandLine);\r
+  } else {\r
+    CommandLine = NULL;\r
+  }\r
+\r
+  Status = LoadLinuxSetCommandLine (SetupBuf, CommandLine);\r
+  if (EFI_ERROR (Status)) {\r
+    goto FreeAndReturn;\r
+  }\r
+\r
+  QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);\r
+  InitrdSize = (UINTN) QemuFwCfgRead64 ();\r
+\r
+  if (InitrdSize > 0) {\r
+    InitrdData = LoadLinuxAllocateInitrdPages (\r
+                   SetupBuf,\r
+                   EFI_SIZE_TO_PAGES (InitrdSize)\r
+                   );\r
+    DEBUG ((EFI_D_INFO, "Initrd size: 0x%x\n", (UINT32) InitrdSize));\r
+    DEBUG ((EFI_D_INFO, "Reading initrd image ..."));\r
+    QemuFwCfgSelectItem (QemuFwCfgItemInitrdData);\r
+    QemuFwCfgReadBytes (InitrdSize, InitrdData);\r
+    DEBUG ((EFI_D_INFO, " [done]\n"));\r
+  } else {\r
+    InitrdData = NULL;\r
+  }\r
+\r
+  Status = LoadLinuxSetInitrd (SetupBuf, InitrdData, InitrdSize);\r
+  if (EFI_ERROR (Status)) {\r
+    goto FreeAndReturn;\r
+  }\r
+\r
+  Status = LoadLinux (KernelBuf, SetupBuf);\r
+\r
+FreeAndReturn:\r
+  if (SetupBuf != NULL) {\r
+    FreePages (SetupBuf, EFI_SIZE_TO_PAGES (SetupSize));\r
+  }\r
+  if (KernelBuf != NULL) {\r
+    FreePages (KernelBuf, EFI_SIZE_TO_PAGES (KernelInitialSize));\r
+  }\r
+  if (CommandLine != NULL) {\r
+    FreePages (CommandLine, EFI_SIZE_TO_PAGES (CommandLineSize));\r
+  }\r
+  if (InitrdData != NULL) {\r
+    FreePages (InitrdData, EFI_SIZE_TO_PAGES (InitrdSize));\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r