Files
system76-edk2/ArmPkg/Application/LinuxLoader/LinuxFdtLoader.c
oliviermartin 75e4db2d3b ArmPkg/Application/LinuxLoader: Create a Linux Loader EFI application
There are two variants of the Linux Loader EFI application:
- the ATAG version 'LinuxAtagLoader.inf': expect to start an ATAG 'zImage'
in the same directory as the EFI application
- the FDT version 'LinuxFdtLoader.inf': load the FDT blob 'platform.dtb'
and the FDT 'zImage' from the same directory as the EFI application.

When these applications are started without any argument, a menu appears
to the user to create/update a boot entry.



git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12410 6f19259b-4bc3-4df7-8a09-765794883524
2011-09-22 22:57:03 +00:00

106 lines
3.6 KiB
C

/** @file
*
* Copyright (c) 2011, ARM Limited. All rights reserved.
*
* 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 "LinuxInternal.h"
#include <Library/PrintLib.h>
#include <Library/UefiApplicationEntryPoint.h>
/**
The user Entry Point for Application. The user code starts with this function
as the real entry point for the application.
@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
)
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
LINUX_LOADER_OPTIONAL_DATA* LinuxOptionalData;
EFI_DEVICE_PATH* DevicePathKernel;
EFI_DEVICE_PATH* DevicePathFdt;
EFI_DEVICE_PATH* InitrdDevicePath;
CHAR16* OptionalDataInitrd;
CHAR8* OptionalDataArguments;
CHAR16* Initrd;
Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);
ASSERT_EFI_ERROR (Status);
if (LoadedImage->LoadOptionsSize == 0) {
Status = LinuxLoaderConfig (LoadedImage);
} else {
// Ensure the signature is correct
LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)LoadedImage->LoadOptions;
if (LinuxOptionalData->Signature != LINUX_LOADER_SIGNATURE) {
return EFI_UNSUPPORTED;
}
// Generate the File Path Node for the Linux Kernel & Device Tree blobl
DevicePathKernel = FileDevicePath (LoadedImage->DeviceHandle, LINUX_KERNEL_NAME);
DevicePathFdt = FileDevicePath (LoadedImage->DeviceHandle, FDT_NAME);
if (LinuxOptionalData->CmdLineLength > 0) {
OptionalDataArguments = (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA);
} else {
OptionalDataArguments = NULL;
}
if (LinuxOptionalData->InitrdPathListLength > 0) {
if (OptionalDataArguments != NULL) {
OptionalDataInitrd = (CHAR16*)(OptionalDataArguments + LinuxOptionalData->CmdLineLength);
} else {
OptionalDataInitrd = (CHAR16*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA);
}
// If pointer not aligned
if ((UINTN)OptionalDataInitrd & 0x1) {
Initrd = (CHAR16*)AllocateCopyPool (LinuxOptionalData->InitrdPathListLength, OptionalDataInitrd);
} else {
Initrd = OptionalDataInitrd;
}
InitrdDevicePath = FileDevicePath (LoadedImage->DeviceHandle, Initrd);
} else {
OptionalDataInitrd = NULL;
InitrdDevicePath = NULL;
Initrd = NULL;
}
// Load and Start the Linux Kernel (we should never return)
Status = BdsBootLinuxFdt (DevicePathKernel, InitrdDevicePath, OptionalDataArguments, DevicePathFdt);
if ((UINTN)OptionalDataInitrd & 0x1) {
FreePool (Initrd);
}
FreePool (DevicePathKernel);
if (InitrdDevicePath) {
FreePool (InitrdDevicePath);
}
}
return Status;
}