/** A simple check of the kernel setup image An assumption is made that the size of the data is at least the size of struct boot_params. @param[in] KernelSetup - The kernel setup image @retval EFI_SUCCESS - The kernel setup looks valid and supported @retval EFI_INVALID_PARAMETER - KernelSetup was NULL @retval EFI_UNSUPPORTED - The kernel setup is not valid or supported **/ STATIC EFI_STATUS EFIAPI BasicKernelSetupCheck ( IN VOID *KernelSetup ) { return LoadLinuxCheckKernelSetup(KernelSetup, sizeof (struct boot_params)); }
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; } 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; }