/** @file Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include #include 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; }