mirror of https://github.com/acidanthera/audk.git
299 lines
9.5 KiB
C
299 lines
9.5 KiB
C
|
/** @file
|
||
|
*
|
||
|
* Copyright (c) 2011-2015, 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 "LinuxLoader.h"
|
||
|
|
||
|
//
|
||
|
// Internal variables
|
||
|
//
|
||
|
|
||
|
CONST EFI_GUID mLinuxLoaderHiiGuid = {
|
||
|
0xd5d16edc, 0x35c5, 0x4866,
|
||
|
{0xbd, 0xe5, 0x2b, 0x64, 0xa2, 0x26, 0x55, 0x6e}
|
||
|
};
|
||
|
EFI_HANDLE mLinuxLoaderHiiHandle;
|
||
|
|
||
|
STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
|
||
|
{L"-f", TypeValue},
|
||
|
{L"-d", TypeValue},
|
||
|
{L"-c", TypeValue},
|
||
|
{L"-a", TypeValue},
|
||
|
{NULL , TypeMax }
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
Print a string given the "HII Id" of the format string and a list of
|
||
|
arguments.
|
||
|
|
||
|
@param[in] Language The language of the string to retrieve. If
|
||
|
this parameter is NULL, then the current
|
||
|
platform language is used.
|
||
|
@param[in] HiiFormatStringId The format string Id for getting from Hii.
|
||
|
@param[in] ... The variable argument list.
|
||
|
|
||
|
@retval EFI_SUCCESS The printing was successful.
|
||
|
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
|
||
|
|
||
|
**/
|
||
|
EFI_STATUS
|
||
|
PrintHii (
|
||
|
IN CONST CHAR8 *Language OPTIONAL,
|
||
|
IN CONST EFI_STRING_ID HiiFormatStringId,
|
||
|
...
|
||
|
)
|
||
|
{
|
||
|
VA_LIST Marker;
|
||
|
CHAR16 *HiiFormatString;
|
||
|
CHAR16 Buffer[MAX_MSG_LEN];
|
||
|
|
||
|
VA_START (Marker, HiiFormatStringId);
|
||
|
|
||
|
HiiFormatString = HiiGetString (mLinuxLoaderHiiHandle, HiiFormatStringId, Language);
|
||
|
if (HiiFormatString != NULL) {
|
||
|
UnicodeVSPrint (Buffer, sizeof (Buffer), HiiFormatString, Marker);
|
||
|
Print (L"%s", Buffer);
|
||
|
FreePool (HiiFormatString);
|
||
|
} else {
|
||
|
ASSERT (FALSE);
|
||
|
return EFI_OUT_OF_RESOURCES;
|
||
|
}
|
||
|
|
||
|
VA_END (Marker);
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Print the help.
|
||
|
|
||
|
@param[in] Language The language of the string to retrieve. If this
|
||
|
parameter is NULL, then the current platform
|
||
|
language is used.
|
||
|
**/
|
||
|
VOID
|
||
|
PrintHelp (
|
||
|
IN CONST CHAR8 *Language OPTIONAL
|
||
|
)
|
||
|
{
|
||
|
CHAR16 *Help;
|
||
|
CHAR16 *Walker;
|
||
|
CHAR16 *LineEnd;
|
||
|
|
||
|
//
|
||
|
// Print the help line by line as it is too big to be printed at once.
|
||
|
//
|
||
|
|
||
|
Help = HiiGetString (mLinuxLoaderHiiHandle, STRING_TOKEN (STR_HELP), Language);
|
||
|
if (Help != NULL) {
|
||
|
Walker = Help;
|
||
|
while (*Walker != L'\0') {
|
||
|
LineEnd = StrStr (Walker, L"\r\n");
|
||
|
if (LineEnd != NULL) {
|
||
|
*LineEnd = L'\0';
|
||
|
}
|
||
|
Print (L"%s\r\n", Walker);
|
||
|
if (LineEnd == NULL) {
|
||
|
break;
|
||
|
}
|
||
|
Walker = LineEnd + 2;
|
||
|
}
|
||
|
FreePool (Help);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Process the Shell parameters in the case the application has been called
|
||
|
from the EFI Shell.
|
||
|
|
||
|
@param[out] KernelPath A pointer to the buffer where the path
|
||
|
to the Linux kernel (EFI Shell file path
|
||
|
or device path is stored. The address of
|
||
|
the buffer is NULL in case of an error.
|
||
|
Otherwise, the returned address is the
|
||
|
address of a buffer allocated with
|
||
|
a call to AllocatePool() that has to be
|
||
|
freed by the caller.
|
||
|
@param[out] FdtPath A pointer to the buffer where the path
|
||
|
to the FDT (EFI Shell file path or
|
||
|
device path) is stored. The address of
|
||
|
the buffer is NULL in case of an error or
|
||
|
if the path to the FDT is not defined.
|
||
|
Otherwise, the returned address is the
|
||
|
address of a buffer allocated with a call
|
||
|
to AllocatePool() that has to be freed by
|
||
|
the caller.
|
||
|
@param[out] InitrdPath A pointer to the buffer where the path
|
||
|
(EFI Shell file path or device path)
|
||
|
to the RAM root file system is stored.
|
||
|
The address of the buffer is NULL in case
|
||
|
of an error or if the path to the RAM root
|
||
|
file system is not defined. Otherwise, the
|
||
|
returned address is the address of a
|
||
|
buffer allocated with a call to
|
||
|
AllocatePool() that has to be freed by
|
||
|
the caller.
|
||
|
@param[out] LinuxCommandLine A pointer to the buffer where the Linux
|
||
|
kernel command line is stored. The address
|
||
|
of the buffer is NULL in case of an error
|
||
|
or if the Linux command line is not
|
||
|
defined. Otherwise, the returned address
|
||
|
is the address of a buffer allocated with
|
||
|
a call to AllocatePool() that has to be
|
||
|
freed by the caller.
|
||
|
@param[out] AtagMachineType Value of the ARM Machine Type
|
||
|
|
||
|
@retval EFI_SUCCESS The processing was successfull.
|
||
|
@retval EFI_ABORTED The initialisation of the Shell Library failed.
|
||
|
@retval EFI_NOT_FOUND Path to the Linux kernel not found.
|
||
|
@retval EFI_INVALID_PARAMETER At least one parameter is not valid or there is a
|
||
|
conflict between two parameters.
|
||
|
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
|
||
|
|
||
|
**/
|
||
|
EFI_STATUS
|
||
|
ProcessShellParameters (
|
||
|
OUT CHAR16 **KernelPath,
|
||
|
OUT CHAR16 **FdtPath,
|
||
|
OUT CHAR16 **InitrdPath,
|
||
|
OUT CHAR16 **LinuxCommandLine,
|
||
|
OUT UINTN *AtagMachineType
|
||
|
)
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
LIST_ENTRY *CheckPackage;
|
||
|
CHAR16 *ProblemParam;
|
||
|
CONST CHAR16 *FlagValue;
|
||
|
CONST CHAR16 *ParameterValue;
|
||
|
UINTN LinuxCommandLineLen;
|
||
|
|
||
|
|
||
|
*KernelPath = NULL;
|
||
|
*FdtPath = NULL;
|
||
|
*InitrdPath = NULL;
|
||
|
*LinuxCommandLine = NULL;
|
||
|
*AtagMachineType = ARM_FDT_MACHINE_TYPE;
|
||
|
|
||
|
//
|
||
|
// Initialise the Shell Library as we are going to use it.
|
||
|
// Assert that the return code is EFI_SUCCESS as it should.
|
||
|
// To anticipate any change is the codes returned by
|
||
|
// ShellInitialize(), leave in case of error.
|
||
|
//
|
||
|
Status = ShellInitialize ();
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
return EFI_ABORTED;
|
||
|
}
|
||
|
|
||
|
Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
if ((Status == EFI_VOLUME_CORRUPTED) &&
|
||
|
(ProblemParam != NULL) ) {
|
||
|
PrintHii (
|
||
|
NULL, STRING_TOKEN (STR_SHELL_INVALID_PARAMETER), ProblemParam
|
||
|
);
|
||
|
FreePool (ProblemParam);
|
||
|
} else {
|
||
|
ASSERT (FALSE);
|
||
|
}
|
||
|
goto Error;
|
||
|
}
|
||
|
|
||
|
Status = EFI_INVALID_PARAMETER;
|
||
|
if (ShellCommandLineGetCount (CheckPackage) != 2) {
|
||
|
PrintHelp (NULL);
|
||
|
goto Error;
|
||
|
}
|
||
|
|
||
|
Status = EFI_OUT_OF_RESOURCES;
|
||
|
|
||
|
FlagValue = ShellCommandLineGetValue (CheckPackage, L"-a");
|
||
|
if (FlagValue != NULL) {
|
||
|
if (ShellCommandLineGetFlag (CheckPackage, L"-d")) {
|
||
|
PrintHii (NULL, STRING_TOKEN (STR_ATAG_FDT_CONFLICT));
|
||
|
goto Error;
|
||
|
}
|
||
|
*AtagMachineType = StrDecimalToUintn (FlagValue);
|
||
|
}
|
||
|
|
||
|
ParameterValue = ShellCommandLineGetRawValue (CheckPackage, 1);
|
||
|
*KernelPath = AllocateCopyPool (StrSize (ParameterValue), ParameterValue);
|
||
|
if (*KernelPath == NULL) {
|
||
|
goto Error;
|
||
|
}
|
||
|
|
||
|
FlagValue = ShellCommandLineGetValue (CheckPackage, L"-d");
|
||
|
if (FlagValue != NULL) {
|
||
|
*FdtPath = AllocateCopyPool (StrSize (FlagValue), FlagValue);
|
||
|
if (*FdtPath == NULL) {
|
||
|
goto Error;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
FlagValue = ShellCommandLineGetValue (CheckPackage, L"-f");
|
||
|
if (FlagValue != NULL) {
|
||
|
*InitrdPath = AllocateCopyPool (StrSize (FlagValue), FlagValue);
|
||
|
if (*InitrdPath == NULL) {
|
||
|
goto Error;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
FlagValue = ShellCommandLineGetValue (CheckPackage, L"-c");
|
||
|
if (FlagValue != NULL) {
|
||
|
LinuxCommandLineLen = StrLen (FlagValue);
|
||
|
if ((LinuxCommandLineLen != 0) &&
|
||
|
(FlagValue[0] == L'"' ) &&
|
||
|
(FlagValue[LinuxCommandLineLen - 1] == L'"')) {
|
||
|
FlagValue++;
|
||
|
LinuxCommandLineLen -= 2;
|
||
|
}
|
||
|
|
||
|
*LinuxCommandLine = AllocateCopyPool (
|
||
|
(LinuxCommandLineLen + 1) * sizeof (CHAR16),
|
||
|
FlagValue
|
||
|
);
|
||
|
if (*LinuxCommandLine == NULL) {
|
||
|
goto Error;
|
||
|
}
|
||
|
(*LinuxCommandLine)[LinuxCommandLineLen] = L'\0';
|
||
|
}
|
||
|
|
||
|
Status = EFI_SUCCESS;
|
||
|
|
||
|
Error:
|
||
|
ShellCommandLineFreeVarList (CheckPackage);
|
||
|
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
if (*KernelPath != NULL) {
|
||
|
FreePool (*KernelPath);
|
||
|
*KernelPath = NULL;
|
||
|
}
|
||
|
if (*FdtPath != NULL) {
|
||
|
FreePool (*FdtPath);
|
||
|
*FdtPath = NULL;
|
||
|
}
|
||
|
if (*InitrdPath != NULL) {
|
||
|
FreePool (*InitrdPath);
|
||
|
*InitrdPath = NULL;
|
||
|
}
|
||
|
if (*LinuxCommandLine != NULL) {
|
||
|
FreePool (*LinuxCommandLine);
|
||
|
*LinuxCommandLine = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return Status;
|
||
|
}
|