mirror of https://github.com/acidanthera/audk.git
175 lines
5.1 KiB
C
175 lines
5.1 KiB
C
/** @file
|
|
|
|
Copyright (c) 2006 - 2015, 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/ReportStatusCodeLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/UefiLib.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;
|
|
}
|
|
|
|
Status = LoadLinuxInitializeKernelSetup (SetupBuf);
|
|
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;
|
|
}
|
|
|
|
//
|
|
// Signal the EVT_SIGNAL_READY_TO_BOOT event
|
|
//
|
|
EfiSignalEventReadyToBoot();
|
|
|
|
REPORT_STATUS_CODE (EFI_PROGRESS_CODE,
|
|
(EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT));
|
|
|
|
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;
|
|
}
|
|
|