| /** @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; | |
| } |