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

Reply via email to