mirror of https://github.com/acidanthera/audk.git
155 lines
4.9 KiB
C
155 lines
4.9 KiB
C
|
/** @file
|
||
|
*
|
||
|
* Copyright (c) 2014, ARM Ltd. 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 <Library/BaseLib.h>
|
||
|
#include <Library/BaseMemoryLib.h>
|
||
|
#include <Library/MemoryAllocationLib.h>
|
||
|
#include <Library/DebugLib.h>
|
||
|
#include <Library/UefiLib.h>
|
||
|
|
||
|
#include <Guid/BootMonFsFileInfo.h>
|
||
|
#include <Protocol/SimpleFileSystem.h> // EFI_FILE_HANDLE
|
||
|
|
||
|
#include "ArmShellCmdRunAxf.h"
|
||
|
#include "BootMonFsLoader.h"
|
||
|
|
||
|
/**
|
||
|
Check that loading the file is supported.
|
||
|
|
||
|
Not all information is checked, only the properties that matters to us in
|
||
|
our simplified loader.
|
||
|
|
||
|
BootMonFS file properties is not in a file header but in the file-system
|
||
|
metadata, so we need to pass a handle to the file to allow access to the
|
||
|
information.
|
||
|
|
||
|
@param[in] FileHandle Handle of the file to check.
|
||
|
|
||
|
@retval EFI_SUCCESS on success.
|
||
|
@retval EFI_INVALID_PARAMETER if the header is invalid.
|
||
|
@retval EFI_UNSUPPORTED if the file type/platform is not supported.
|
||
|
**/
|
||
|
EFI_STATUS
|
||
|
BootMonFsCheckFile (
|
||
|
IN CONST EFI_FILE_HANDLE FileHandle
|
||
|
)
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
BOOTMON_FS_FILE_INFO Info;
|
||
|
UINTN InfoSize;
|
||
|
UINTN Index;
|
||
|
|
||
|
ASSERT (FileHandle != NULL);
|
||
|
|
||
|
// Try to load the file information as BootMonFS executable.
|
||
|
InfoSize = sizeof (Info);
|
||
|
// Get BootMon File info and see if it gives us what we need to load the file.
|
||
|
Status = FileHandle->GetInfo (FileHandle, &gArmBootMonFsFileInfoGuid,
|
||
|
&InfoSize, &Info);
|
||
|
|
||
|
if (!EFI_ERROR (Status)) {
|
||
|
// Check the values return to see if they look reasonable.
|
||
|
// Do we have a good entrypoint and at least one good load region?
|
||
|
// We assume here that we cannot load to address 0x0.
|
||
|
if ((Info.Size == 0) || (Info.EntryPoint == 0) || (Info.RegionCount == 0) ||
|
||
|
(Info.RegionCount > BOOTMONFS_IMAGE_DESCRIPTION_REGION_MAX)) {
|
||
|
// The file does not seem to be of the right type.
|
||
|
Status = EFI_UNSUPPORTED;
|
||
|
} else {
|
||
|
// Check load regions. We just check for valid numbers, we dont do the
|
||
|
// checksums. Info.Offset can be zero if it loads from the start of the
|
||
|
// file.
|
||
|
for (Index = 0; Index < Info.RegionCount; Index++) {
|
||
|
if ((Info.Region[Index].LoadAddress == 0) || (Info.Region[Index].Size == 0)) {
|
||
|
Status = EFI_UNSUPPORTED;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Load a binary file from BootMonFS.
|
||
|
|
||
|
@param[in] FileHandle Handle of the file to load.
|
||
|
|
||
|
@param[in] FileData Address of the file data in memory.
|
||
|
|
||
|
@param[out] EntryPoint Will be filled with the ELF entry point address.
|
||
|
|
||
|
@param[out] ImageSize Will be filled with the file size in memory. This
|
||
|
will effectively be equal to the sum of the load
|
||
|
region sizes.
|
||
|
|
||
|
This function assumes the file is valid and supported as checked with
|
||
|
BootMonFsCheckFile().
|
||
|
|
||
|
@retval EFI_SUCCESS on success.
|
||
|
@retval EFI_INVALID_PARAMETER if the file is invalid.
|
||
|
**/
|
||
|
EFI_STATUS
|
||
|
BootMonFsLoadFile (
|
||
|
IN CONST EFI_FILE_HANDLE FileHandle,
|
||
|
IN CONST VOID *FileData,
|
||
|
OUT VOID **EntryPoint,
|
||
|
OUT LIST_ENTRY *LoadList
|
||
|
)
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
BOOTMON_FS_FILE_INFO Info;
|
||
|
UINTN InfoSize;
|
||
|
UINTN Index;
|
||
|
UINTN ImageSize;
|
||
|
RUNAXF_LOAD_LIST *LoadNode;
|
||
|
|
||
|
ASSERT (FileHandle != NULL);
|
||
|
ASSERT (FileData != NULL);
|
||
|
ASSERT (EntryPoint != NULL);
|
||
|
ASSERT (LoadList != NULL);
|
||
|
|
||
|
ImageSize = 0;
|
||
|
|
||
|
InfoSize = sizeof (Info);
|
||
|
Status = FileHandle->GetInfo (FileHandle, &gArmBootMonFsFileInfoGuid,
|
||
|
&InfoSize, &Info);
|
||
|
|
||
|
if (!EFI_ERROR (Status)) {
|
||
|
*EntryPoint = (VOID*)((UINTN)Info.EntryPoint);
|
||
|
// Load all the regions to run-time memory
|
||
|
for (Index = 0; Index < Info.RegionCount; Index++) {
|
||
|
LoadNode = AllocateRuntimeZeroPool (sizeof (RUNAXF_LOAD_LIST));
|
||
|
if (LoadNode == NULL) {
|
||
|
Status = EFI_OUT_OF_RESOURCES;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
LoadNode->MemOffset = (UINTN)Info.Region[Index].LoadAddress;
|
||
|
LoadNode->FileOffset = (UINTN)FileData + Info.Region[Index].Offset;
|
||
|
LoadNode->Length = (UINTN)Info.Region[Index].Size;
|
||
|
InsertTailList (LoadList, &LoadNode->Link);
|
||
|
|
||
|
ImageSize += LoadNode->Length;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ((!EFI_ERROR (Status)) && (ImageSize == 0)) {
|
||
|
Status = EFI_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
return Status;
|
||
|
}
|