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.

Signed-off-by: Jordan Justen <[email protected]>
---
 OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c      |    5 +
 OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h      |   11 ++
 OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf |    4 +-
 OvmfPkg/Library/PlatformBdsLib/QemuKernel.c       |  159 +++++++++++++++++++++
 4 files changed, 178 insertions(+), 1 deletion(-)
 create mode 100644 OvmfPkg/Library/PlatformBdsLib/QemuKernel.c

diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c 
b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
index d6e1e93..781b415 100644
--- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
@@ -1128,6 +1128,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 cf8bb12..72b0e14 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 81602f5..7f7f473 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 0000000..fa8bcbc
--- /dev/null
+++ b/OvmfPkg/Library/PlatformBdsLib/QemuKernel.c
@@ -0,0 +1,159 @@
+/** @file
+
+  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+  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 <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/LoadLinuxLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/QemuFwCfgLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+
+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;
+}
+
-- 
1.7.9.5


------------------------------------------------------------------------------
The Windows 8 Center 
In partnership with Sourceforge
Your idea - your app - 30 days. Get started!
http://windows8center.sourceforge.net/
what-html-developers-need-to-know-about-coding-windows-8-metro-style-apps/
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to