On 10/20/12 00:38, Jordan Justen wrote: > This application uses QEMU's FwCfg interface to read a kernel > specified on the QEMU command line. (See -kernel, -initrd, -append) > > The application uses the LoadLinuxLib to boot the kernel image. > > Signed-off-by: Jordan Justen <jordan.l.jus...@intel.com>
Since it is an application, is it meant to be used from the UEFI shell? If so, should it print messages to the console rather than to the debug output? > --- > OvmfPkg/Application/QemuKernelDxe/QemuKernelDxe.c | 161 > ++++++++++++++++++++ > .../Application/QemuKernelDxe/QemuKernelDxe.inf | 47 ++++++ > OvmfPkg/OvmfPkgIa32.dsc | 3 + > OvmfPkg/OvmfPkgIa32.fdf | 2 + > OvmfPkg/OvmfPkgIa32X64.dsc | 3 + > OvmfPkg/OvmfPkgIa32X64.fdf | 2 + > OvmfPkg/OvmfPkgX64.dsc | 3 + > OvmfPkg/OvmfPkgX64.fdf | 2 + > 8 files changed, 223 insertions(+) > create mode 100644 OvmfPkg/Application/QemuKernelDxe/QemuKernelDxe.c > create mode 100644 OvmfPkg/Application/QemuKernelDxe/QemuKernelDxe.inf > > diff --git a/OvmfPkg/Application/QemuKernelDxe/QemuKernelDxe.c > b/OvmfPkg/Application/QemuKernelDxe/QemuKernelDxe.c > new file mode 100644 > index 0000000..f9b7092 > --- /dev/null > +++ b/OvmfPkg/Application/QemuKernelDxe/QemuKernelDxe.c > @@ -0,0 +1,161 @@ > +/** @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> > + > + > +/** > + Loads and boots UEFI Linux via the FwCfg interface. > + > + @retval EFI_NOT_FOUND - The Linux kernel was not found > + > +**/ > +EFI_STATUS > +EFIAPI > +QemuFwCfgLoadLinux ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + UINTN KernelSize; > + UINTN KernelInitialSize; > + VOID *KernelBuf; > + UINTN SetupSize; > + VOID *SetupBuf; > + UINTN CommandLineSize; > + CHAR8 *CommandLine; > + UINTN InitrdSize; > + VOID* InitrdData; > + struct boot_params *Bp; > + > + if (!QemuFwCfgIsAvailable ()) { > + return EFI_NOT_FOUND; > + } > + > + QemuFwCfgSelectItem (QemuFwCfgItemKernelSize); > + KernelSize = (UINTN) QemuFwCfgRead64 (); > + DEBUG ((EFI_D_INFO, "Kernel size: 0x%x\n", KernelSize)); > + > + QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupSize); > + SetupSize = (UINTN) QemuFwCfgRead64 (); > + DEBUG ((EFI_D_INFO, "Setup size: 0x%x\n", SetupSize)); I guess we can live with the "potential" 64->32 truncation here in the assignments, but the conversion specifier "%x" is for UINT32 (see BasePrintLibSPrintMarker()), and UINTN is UINT64 on X64. In practice it should not be visible due to little-endianness and absence of further parameters (I guess). > + > + 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, "Reading kernel setup image ...")); > + QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupData); > + QemuFwCfgReadBytes (SetupSize, SetupBuf); > + DEBUG ((EFI_D_INFO, " [done]\n")); > + > + Status = LoadLinuxCheckKernelSetup (SetupBuf, SetupSize); > + if (EFI_ERROR (Status)) { > + return Status; > + } This leaks memory allocated by LoadLinuxAllocateKernelSetupPages(). Admittedly we're going to exit the application immediately. Does UEFI isolate applications, or is app-leaked memory lost? > + > + KernelInitialSize = LoadLinuxGetKernelSize (SetupBuf, KernelSize); I presume the possible multiplication by 3 inside won't overflow UINTN. > + if (KernelInitialSize == 0) { > + return EFI_UNSUPPORTED; > + } > + > + Bp = (struct boot_params*) SetupBuf; The Bp variable is not consumed by anything. > + > + KernelBuf = LoadLinuxAllocateKernelPages ( > + SetupBuf, > + EFI_SIZE_TO_PAGES (KernelInitialSize)); > + if (KernelBuf == NULL) { > + DEBUG ((EFI_D_ERROR, "Unable to allocate memory for kernel!\n")); > + return EFI_OUT_OF_RESOURCES; > + } (leaks LoadLinuxAllocateKernelSetupPages()) > + > + DEBUG ((EFI_D_INFO, "Reading kernel image ...")); > + QemuFwCfgSelectItem (QemuFwCfgItemKernelData); > + QemuFwCfgReadBytes (KernelSize, KernelBuf); > + DEBUG ((EFI_D_INFO, " [done]\n")); > + > + QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize); > + CommandLineSize = (UINTN) QemuFwCfgRead64 (); > + DEBUG ((EFI_D_INFO, "Command line size: 0x%x\n", CommandLineSize)); %x vs. UINTN > + > + if (CommandLineSize > 0) { > + CommandLine = LoadLinuxAllocateCommandLinePages ( > + EFI_SIZE_TO_PAGES (CommandLineSize)); > + QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData); > + QemuFwCfgReadBytes (CommandLineSize, CommandLine); > + } else { > + CommandLine = NULL; > + } > + > + Status = LoadLinuxSetCommandLine (SetupBuf, CommandLine); Works for NULL too, OK. > + if (EFI_ERROR (Status)) { > + return Status; > + } (leaks LoadLinuxAllocateKernelSetupPages() and potentially LoadLinuxAllocateCommandLinePages() -- in practice LoadLinuxSetCommandLine() always succeeds; it could return VOID) > + > + QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize); > + InitrdSize = (UINTN) QemuFwCfgRead64 (); > + DEBUG ((EFI_D_INFO, "Initrd size: 0x%x\n", InitrdSize)); %x vs. UINTN > + > + if (InitrdSize > 0) { > + InitrdData = LoadLinuxAllocateInitrdPages (EFI_SIZE_TO_PAGES > (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)) { > + return Status; > + } (see at LoadLinuxSetCommandLine) > + > + return LoadLinux (KernelBuf, SetupBuf); > +} > +/** > + > + @param[in] ImageHandle The firmware allocated handle for the EFI image. > + @param[in] SystemTable A pointer to the EFI System Table. > + > + @retval EFI_SUCCESS The entry point is executed successfully. > + @retval other Some error occurs when executing this entry > point. > + > +**/ > +EFI_STATUS > +EFIAPI > +UefiMain ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + QemuFwCfgLoadLinux (); > + > + return EFI_SUCCESS; > +} I suggest "return QemuFwCfgLoadLinux ()". Laszlo ------------------------------------------------------------------------------ Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_sfd2d_oct _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel