summaryrefslogtreecommitdiff
path: root/ArmPkg/Application/LinuxLoader/LinuxLoaderShellApp.c
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPkg/Application/LinuxLoader/LinuxLoaderShellApp.c')
-rw-r--r--ArmPkg/Application/LinuxLoader/LinuxLoaderShellApp.c298
1 files changed, 298 insertions, 0 deletions
diff --git a/ArmPkg/Application/LinuxLoader/LinuxLoaderShellApp.c b/ArmPkg/Application/LinuxLoader/LinuxLoaderShellApp.c
new file mode 100644
index 0000000000..2245185394
--- /dev/null
+++ b/ArmPkg/Application/LinuxLoader/LinuxLoaderShellApp.c
@@ -0,0 +1,298 @@
+/** @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;
+}