diff options
Diffstat (limited to 'ArmPkg/Application/LinuxLoader/LinuxConfig.c')
-rw-r--r-- | ArmPkg/Application/LinuxLoader/LinuxConfig.c | 706 |
1 files changed, 353 insertions, 353 deletions
diff --git a/ArmPkg/Application/LinuxLoader/LinuxConfig.c b/ArmPkg/Application/LinuxLoader/LinuxConfig.c index b95d0a4dc0..0d0b8b4746 100644 --- a/ArmPkg/Application/LinuxLoader/LinuxConfig.c +++ b/ArmPkg/Application/LinuxLoader/LinuxConfig.c @@ -1,353 +1,353 @@ -/** @file -* -* Copyright (c) 2011-2012, 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" - -#define DEFAULT_BOOT_ENTRY_DESCRIPTION L"Linux" -#define MAX_STR_INPUT 300 -#define MAX_ASCII_INPUT 300 - -typedef enum { - LINUX_LOADER_NEW = 1, - LINUX_LOADER_UPDATE -} LINUX_LOADER_ACTION; - -STATIC -EFI_STATUS -EditHIInputStr ( - IN OUT CHAR16 *CmdLine, - IN UINTN MaxCmdLine - ) -{ - UINTN CmdLineIndex; - UINTN WaitIndex; - CHAR8 Char; - EFI_INPUT_KEY Key; - EFI_STATUS Status; - - Print (CmdLine); - - for (CmdLineIndex = StrLen (CmdLine); CmdLineIndex < MaxCmdLine; ) { - Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex); - ASSERT_EFI_ERROR (Status); - - Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); - ASSERT_EFI_ERROR (Status); - - // Unicode character is valid when Scancode is NUll - if (Key.ScanCode == SCAN_NULL) { - // Scan code is NUll, hence read Unicode character - Char = (CHAR8)Key.UnicodeChar; - } else { - Char = CHAR_NULL; - } - - if ((Char == CHAR_LINEFEED) || (Char == CHAR_CARRIAGE_RETURN) || (Char == 0x7f)) { - CmdLine[CmdLineIndex] = '\0'; - Print (L"\n\r"); - - return EFI_SUCCESS; - } else if ((Key.UnicodeChar == L'\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){ - if (CmdLineIndex != 0) { - CmdLineIndex--; - Print (L"\b \b"); - } - } else if ((Key.ScanCode == SCAN_ESC) || (Char == 0x1B) || (Char == 0x0)) { - return EFI_INVALID_PARAMETER; - } else { - CmdLine[CmdLineIndex++] = Key.UnicodeChar; - Print (L"%c", Key.UnicodeChar); - } - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -EditHIInputAscii ( - IN OUT CHAR8 *CmdLine, - IN UINTN MaxCmdLine - ) -{ - CHAR16* Str; - EFI_STATUS Status; - - Str = (CHAR16*)AllocatePool (MaxCmdLine * sizeof(CHAR16)); - AsciiStrToUnicodeStr (CmdLine, Str); - - Status = EditHIInputStr (Str, MaxCmdLine); - - UnicodeStrToAsciiStr (Str, CmdLine); - FreePool (Str); - - return Status; -} - -STATIC -EFI_STATUS -GetHIInputInteger ( - OUT UINTN *Integer - ) -{ - CHAR16 CmdLine[255]; - EFI_STATUS Status; - - CmdLine[0] = '\0'; - Status = EditHIInputStr (CmdLine, 255); - if (!EFI_ERROR(Status)) { - *Integer = StrDecimalToUintn (CmdLine); - } - - return Status; -} - -#if 0 -EFI_STATUS -GenerateDeviceDescriptionName ( - IN EFI_HANDLE Handle, - IN OUT CHAR16* Description - ) -{ - EFI_STATUS Status; - EFI_COMPONENT_NAME_PROTOCOL* ComponentName2Protocol; - EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; - EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol; - CHAR16* DriverName; - CHAR16* DevicePathTxt; - EFI_DEVICE_PATH* DevicePathNode; - - ComponentName2Protocol = NULL; - Status = gBS->HandleProtocol (Handle, &gEfiComponentName2ProtocolGuid, (VOID **)&ComponentName2Protocol); - if (!EFI_ERROR(Status)) { - //TODO: Fixme. we must find the best langague - Status = ComponentName2Protocol->GetDriverName (ComponentName2Protocol,"en",&DriverName); - if (!EFI_ERROR(Status)) { - StrnCpy (Description,DriverName,BOOT_DEVICE_DESCRIPTION_MAX); - } - } - - if (EFI_ERROR(Status)) { - // Use the lastest non null entry of the Device path as a description - Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol); - if (EFI_ERROR(Status)) { - return Status; - } - - // Convert the last non end-type Device Path Node in text for the description - DevicePathNode = GetLastDevicePathNode (DevicePathProtocol); - Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); - ASSERT_EFI_ERROR(Status); - DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText(DevicePathNode,TRUE,TRUE); - StrnCpy (Description, DevicePathTxt, BOOT_DEVICE_DESCRIPTION_MAX); - FreePool (DevicePathTxt); - } - - return EFI_SUCCESS; -} -#endif - -EFI_STATUS -LinuxLoaderConfig ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage - ) -{ - EFI_STATUS Status; - LINUX_LOADER_ACTION Choice; - UINTN BootOrderSize; - UINT16* BootOrder; - UINTN BootOrderCount; - UINTN Index; - CHAR16 Description[MAX_ASCII_INPUT]; - CHAR8 CmdLine[MAX_ASCII_INPUT]; - CHAR16 Initrd[MAX_STR_INPUT]; - UINT16 InitrdPathListLength; - UINT16 CmdLineLength; - BDS_LOAD_OPTION* BdsLoadOption; - BDS_LOAD_OPTION** SupportedBdsLoadOptions; - UINTN SupportedBdsLoadOptionCount; - LINUX_LOADER_OPTIONAL_DATA* LinuxOptionalData; - EFI_DEVICE_PATH* DevicePathRoot; - - SupportedBdsLoadOptions = NULL; - SupportedBdsLoadOptionCount = 0; - - do { - Print (L"[%d] Create new Linux Boot Entry\n",LINUX_LOADER_NEW); - Print (L"[%d] Update Linux Boot Entry\n",LINUX_LOADER_UPDATE); - - Print (L"Option: "); - Status = GetHIInputInteger (&Choice); - if (Status == EFI_INVALID_PARAMETER) { - Print (L"\n"); - return Status; - } else if ((Choice != LINUX_LOADER_NEW) && (Choice != LINUX_LOADER_UPDATE)) { - Print (L"Error: the option should be either '%d' or '%d'\n",LINUX_LOADER_NEW,LINUX_LOADER_UPDATE); - Status = EFI_INVALID_PARAMETER; - } - } while (EFI_ERROR(Status)); - - if (Choice == LINUX_LOADER_UPDATE) { - // If no compatible entry then we just create a new entry - Choice = LINUX_LOADER_NEW; - - // Scan the OptionalData of every entry for the correct signature - Status = GetEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder); - if (!EFI_ERROR(Status)) { - BootOrderCount = BootOrderSize / sizeof(UINT16); - - // Allocate an array to handle maximum number of supported Boot Entry - SupportedBdsLoadOptions = (BDS_LOAD_OPTION**)AllocatePool(sizeof(BDS_LOAD_OPTION*) * BootOrderCount); - - SupportedBdsLoadOptionCount = 0; - - // Check if the signature is present in the list of the current Boot entries - for (Index = 0; Index < BootOrderCount; Index++) { - Status = BootOptionFromLoadOptionIndex (BootOrder[Index], &BdsLoadOption); - if (!EFI_ERROR(Status)) { - if ((BdsLoadOption->OptionalDataSize >= sizeof(UINT32)) && - (*(UINT32*)BdsLoadOption->OptionalData == LINUX_LOADER_SIGNATURE)) { - SupportedBdsLoadOptions[SupportedBdsLoadOptionCount++] = BdsLoadOption; - Choice = LINUX_LOADER_UPDATE; - } - } - } - } - FreePool (BootOrder); - } - - if (Choice == LINUX_LOADER_NEW) { - Description[0] = '\0'; - CmdLine[0] = '\0'; - Initrd[0] = '\0'; - - BdsLoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION)); - - DEBUG_CODE_BEGIN(); - CHAR16* DevicePathTxt; - EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol; - - Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol); - ASSERT_EFI_ERROR(Status); - DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (LoadedImage->FilePath, TRUE, TRUE); - - Print(L"EFI OS Loader: %s\n",DevicePathTxt); - - FreePool(DevicePathTxt); - DEBUG_CODE_END(); - - // - // Fill the known fields of BdsLoadOption - // - - BdsLoadOption->Attributes = LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT; - - // Get the full Device Path for this file - Status = gBS->HandleProtocol (LoadedImage->DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathRoot); - ASSERT_EFI_ERROR(Status); - - BdsLoadOption->FilePathList = AppendDevicePath (DevicePathRoot, LoadedImage->FilePath); - BdsLoadOption->FilePathListLength = GetDevicePathSize (BdsLoadOption->FilePathList); - } else { - if (SupportedBdsLoadOptionCount > 1) { - for (Index = 0; Index < SupportedBdsLoadOptionCount; Index++) { - Print (L"[%d] %s\n",Index + 1,SupportedBdsLoadOptions[Index]->Description); - } - - do { - Print (L"Update Boot Entry: "); - Status = GetHIInputInteger (&Choice); - if (Status == EFI_INVALID_PARAMETER) { - Print (L"\n"); - return Status; - } else if ((Choice < 1) && (Choice > SupportedBdsLoadOptionCount)) { - Print (L"Choose entry from 1 to %d\n",SupportedBdsLoadOptionCount); - Status = EFI_INVALID_PARAMETER; - } - } while (EFI_ERROR(Status)); - BdsLoadOption = SupportedBdsLoadOptions[Choice-1]; - } - StrnCpy (Description, BdsLoadOption->Description, MAX_STR_INPUT); - - LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)BdsLoadOption->OptionalData; - if (LinuxOptionalData->CmdLineLength > 0) { - CopyMem (CmdLine, (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA), LinuxOptionalData->CmdLineLength); - } else { - CmdLine[0] = '\0'; - } - - if (LinuxOptionalData->InitrdPathListLength > 0) { - CopyMem (Initrd, (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA) + LinuxOptionalData->CmdLineLength, LinuxOptionalData->InitrdPathListLength); - } else { - Initrd[0] = L'\0'; - } - DEBUG((EFI_D_ERROR,"L\n")); - } - - // Description - Print (L"Description: "); - Status = EditHIInputStr (Description, MAX_STR_INPUT); - if (EFI_ERROR(Status)) { - return Status; - } - if (StrLen (Description) == 0) { - StrnCpy (Description, DEFAULT_BOOT_ENTRY_DESCRIPTION, MAX_STR_INPUT); - } - BdsLoadOption->Description = Description; - - // CmdLine - Print (L"Command Line: "); - Status = EditHIInputAscii (CmdLine, MAX_ASCII_INPUT); - if (EFI_ERROR(Status)) { - return Status; - } - - // Initrd - Print (L"Initrd name: "); - Status = EditHIInputStr (Initrd, MAX_STR_INPUT); - if (EFI_ERROR(Status)) { - return Status; - } - - CmdLineLength = AsciiStrLen (CmdLine); - if (CmdLineLength > 0) { - CmdLineLength += sizeof(CHAR8); - } - - InitrdPathListLength = StrLen (Initrd) * sizeof(CHAR16); - if (InitrdPathListLength > 0) { - InitrdPathListLength += sizeof(CHAR16); - } - - BdsLoadOption->OptionalDataSize = sizeof(LINUX_LOADER_OPTIONAL_DATA) + CmdLineLength + InitrdPathListLength; - - LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)AllocatePool (BdsLoadOption->OptionalDataSize); - BdsLoadOption->OptionalData = LinuxOptionalData; - - LinuxOptionalData->Signature = LINUX_LOADER_SIGNATURE; - LinuxOptionalData->CmdLineLength = CmdLineLength; - LinuxOptionalData->InitrdPathListLength = InitrdPathListLength; - - if (CmdLineLength > 0) { - CopyMem (LinuxOptionalData + 1, CmdLine, CmdLineLength); - } - if (InitrdPathListLength > 0) { - CopyMem ((UINT8*)(LinuxOptionalData + 1) + CmdLineLength, Initrd, InitrdPathListLength); - } - - // Create or Update the boot entry - Status = BootOptionToLoadOptionVariable (BdsLoadOption); - - return Status; -} +/** @file
+*
+* Copyright (c) 2011-2012, 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"
+
+#define DEFAULT_BOOT_ENTRY_DESCRIPTION L"Linux"
+#define MAX_STR_INPUT 300
+#define MAX_ASCII_INPUT 300
+
+typedef enum {
+ LINUX_LOADER_NEW = 1,
+ LINUX_LOADER_UPDATE
+} LINUX_LOADER_ACTION;
+
+STATIC
+EFI_STATUS
+EditHIInputStr (
+ IN OUT CHAR16 *CmdLine,
+ IN UINTN MaxCmdLine
+ )
+{
+ UINTN CmdLineIndex;
+ UINTN WaitIndex;
+ CHAR8 Char;
+ EFI_INPUT_KEY Key;
+ EFI_STATUS Status;
+
+ Print (CmdLine);
+
+ for (CmdLineIndex = StrLen (CmdLine); CmdLineIndex < MaxCmdLine; ) {
+ Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ ASSERT_EFI_ERROR (Status);
+
+ // Unicode character is valid when Scancode is NUll
+ if (Key.ScanCode == SCAN_NULL) {
+ // Scan code is NUll, hence read Unicode character
+ Char = (CHAR8)Key.UnicodeChar;
+ } else {
+ Char = CHAR_NULL;
+ }
+
+ if ((Char == CHAR_LINEFEED) || (Char == CHAR_CARRIAGE_RETURN) || (Char == 0x7f)) {
+ CmdLine[CmdLineIndex] = '\0';
+ Print (L"\n\r");
+
+ return EFI_SUCCESS;
+ } else if ((Key.UnicodeChar == L'\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){
+ if (CmdLineIndex != 0) {
+ CmdLineIndex--;
+ Print (L"\b \b");
+ }
+ } else if ((Key.ScanCode == SCAN_ESC) || (Char == 0x1B) || (Char == 0x0)) {
+ return EFI_INVALID_PARAMETER;
+ } else {
+ CmdLine[CmdLineIndex++] = Key.UnicodeChar;
+ Print (L"%c", Key.UnicodeChar);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EditHIInputAscii (
+ IN OUT CHAR8 *CmdLine,
+ IN UINTN MaxCmdLine
+ )
+{
+ CHAR16* Str;
+ EFI_STATUS Status;
+
+ Str = (CHAR16*)AllocatePool (MaxCmdLine * sizeof(CHAR16));
+ AsciiStrToUnicodeStr (CmdLine, Str);
+
+ Status = EditHIInputStr (Str, MaxCmdLine);
+
+ UnicodeStrToAsciiStr (Str, CmdLine);
+ FreePool (Str);
+
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+GetHIInputInteger (
+ OUT UINTN *Integer
+ )
+{
+ CHAR16 CmdLine[255];
+ EFI_STATUS Status;
+
+ CmdLine[0] = '\0';
+ Status = EditHIInputStr (CmdLine, 255);
+ if (!EFI_ERROR(Status)) {
+ *Integer = StrDecimalToUintn (CmdLine);
+ }
+
+ return Status;
+}
+
+#if 0
+EFI_STATUS
+GenerateDeviceDescriptionName (
+ IN EFI_HANDLE Handle,
+ IN OUT CHAR16* Description
+ )
+{
+ EFI_STATUS Status;
+ EFI_COMPONENT_NAME_PROTOCOL* ComponentName2Protocol;
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
+ EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;
+ CHAR16* DriverName;
+ CHAR16* DevicePathTxt;
+ EFI_DEVICE_PATH* DevicePathNode;
+
+ ComponentName2Protocol = NULL;
+ Status = gBS->HandleProtocol (Handle, &gEfiComponentName2ProtocolGuid, (VOID **)&ComponentName2Protocol);
+ if (!EFI_ERROR(Status)) {
+ //TODO: Fixme. we must find the best langague
+ Status = ComponentName2Protocol->GetDriverName (ComponentName2Protocol,"en",&DriverName);
+ if (!EFI_ERROR(Status)) {
+ StrnCpy (Description,DriverName,BOOT_DEVICE_DESCRIPTION_MAX);
+ }
+ }
+
+ if (EFI_ERROR(Status)) {
+ // Use the lastest non null entry of the Device path as a description
+ Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ // Convert the last non end-type Device Path Node in text for the description
+ DevicePathNode = GetLastDevicePathNode (DevicePathProtocol);
+ Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
+ ASSERT_EFI_ERROR(Status);
+ DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText(DevicePathNode,TRUE,TRUE);
+ StrnCpy (Description, DevicePathTxt, BOOT_DEVICE_DESCRIPTION_MAX);
+ FreePool (DevicePathTxt);
+ }
+
+ return EFI_SUCCESS;
+}
+#endif
+
+EFI_STATUS
+LinuxLoaderConfig (
+ IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage
+ )
+{
+ EFI_STATUS Status;
+ LINUX_LOADER_ACTION Choice;
+ UINTN BootOrderSize;
+ UINT16* BootOrder;
+ UINTN BootOrderCount;
+ UINTN Index;
+ CHAR16 Description[MAX_ASCII_INPUT];
+ CHAR8 CmdLine[MAX_ASCII_INPUT];
+ CHAR16 Initrd[MAX_STR_INPUT];
+ UINT16 InitrdPathListLength;
+ UINT16 CmdLineLength;
+ BDS_LOAD_OPTION* BdsLoadOption;
+ BDS_LOAD_OPTION** SupportedBdsLoadOptions;
+ UINTN SupportedBdsLoadOptionCount;
+ LINUX_LOADER_OPTIONAL_DATA* LinuxOptionalData;
+ EFI_DEVICE_PATH* DevicePathRoot;
+
+ SupportedBdsLoadOptions = NULL;
+ SupportedBdsLoadOptionCount = 0;
+
+ do {
+ Print (L"[%d] Create new Linux Boot Entry\n",LINUX_LOADER_NEW);
+ Print (L"[%d] Update Linux Boot Entry\n",LINUX_LOADER_UPDATE);
+
+ Print (L"Option: ");
+ Status = GetHIInputInteger (&Choice);
+ if (Status == EFI_INVALID_PARAMETER) {
+ Print (L"\n");
+ return Status;
+ } else if ((Choice != LINUX_LOADER_NEW) && (Choice != LINUX_LOADER_UPDATE)) {
+ Print (L"Error: the option should be either '%d' or '%d'\n",LINUX_LOADER_NEW,LINUX_LOADER_UPDATE);
+ Status = EFI_INVALID_PARAMETER;
+ }
+ } while (EFI_ERROR(Status));
+
+ if (Choice == LINUX_LOADER_UPDATE) {
+ // If no compatible entry then we just create a new entry
+ Choice = LINUX_LOADER_NEW;
+
+ // Scan the OptionalData of every entry for the correct signature
+ Status = GetEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);
+ if (!EFI_ERROR(Status)) {
+ BootOrderCount = BootOrderSize / sizeof(UINT16);
+
+ // Allocate an array to handle maximum number of supported Boot Entry
+ SupportedBdsLoadOptions = (BDS_LOAD_OPTION**)AllocatePool(sizeof(BDS_LOAD_OPTION*) * BootOrderCount);
+
+ SupportedBdsLoadOptionCount = 0;
+
+ // Check if the signature is present in the list of the current Boot entries
+ for (Index = 0; Index < BootOrderCount; Index++) {
+ Status = BootOptionFromLoadOptionIndex (BootOrder[Index], &BdsLoadOption);
+ if (!EFI_ERROR(Status)) {
+ if ((BdsLoadOption->OptionalDataSize >= sizeof(UINT32)) &&
+ (*(UINT32*)BdsLoadOption->OptionalData == LINUX_LOADER_SIGNATURE)) {
+ SupportedBdsLoadOptions[SupportedBdsLoadOptionCount++] = BdsLoadOption;
+ Choice = LINUX_LOADER_UPDATE;
+ }
+ }
+ }
+ }
+ FreePool (BootOrder);
+ }
+
+ if (Choice == LINUX_LOADER_NEW) {
+ Description[0] = '\0';
+ CmdLine[0] = '\0';
+ Initrd[0] = '\0';
+
+ BdsLoadOption = (BDS_LOAD_OPTION*)AllocateZeroPool (sizeof(BDS_LOAD_OPTION));
+
+ DEBUG_CODE_BEGIN();
+ CHAR16* DevicePathTxt;
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
+
+ Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
+ ASSERT_EFI_ERROR(Status);
+ DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (LoadedImage->FilePath, TRUE, TRUE);
+
+ Print(L"EFI OS Loader: %s\n",DevicePathTxt);
+
+ FreePool(DevicePathTxt);
+ DEBUG_CODE_END();
+
+ //
+ // Fill the known fields of BdsLoadOption
+ //
+
+ BdsLoadOption->Attributes = LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT;
+
+ // Get the full Device Path for this file
+ Status = gBS->HandleProtocol (LoadedImage->DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathRoot);
+ ASSERT_EFI_ERROR(Status);
+
+ BdsLoadOption->FilePathList = AppendDevicePath (DevicePathRoot, LoadedImage->FilePath);
+ BdsLoadOption->FilePathListLength = GetDevicePathSize (BdsLoadOption->FilePathList);
+ } else {
+ if (SupportedBdsLoadOptionCount > 1) {
+ for (Index = 0; Index < SupportedBdsLoadOptionCount; Index++) {
+ Print (L"[%d] %s\n",Index + 1,SupportedBdsLoadOptions[Index]->Description);
+ }
+
+ do {
+ Print (L"Update Boot Entry: ");
+ Status = GetHIInputInteger (&Choice);
+ if (Status == EFI_INVALID_PARAMETER) {
+ Print (L"\n");
+ return Status;
+ } else if ((Choice < 1) && (Choice > SupportedBdsLoadOptionCount)) {
+ Print (L"Choose entry from 1 to %d\n",SupportedBdsLoadOptionCount);
+ Status = EFI_INVALID_PARAMETER;
+ }
+ } while (EFI_ERROR(Status));
+ BdsLoadOption = SupportedBdsLoadOptions[Choice-1];
+ }
+ StrnCpy (Description, BdsLoadOption->Description, MAX_STR_INPUT);
+
+ LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)BdsLoadOption->OptionalData;
+ if (LinuxOptionalData->CmdLineLength > 0) {
+ CopyMem (CmdLine, (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA), LinuxOptionalData->CmdLineLength);
+ } else {
+ CmdLine[0] = '\0';
+ }
+
+ if (LinuxOptionalData->InitrdPathListLength > 0) {
+ CopyMem (Initrd, (CHAR8*)LinuxOptionalData + sizeof(LINUX_LOADER_OPTIONAL_DATA) + LinuxOptionalData->CmdLineLength, LinuxOptionalData->InitrdPathListLength);
+ } else {
+ Initrd[0] = L'\0';
+ }
+ DEBUG((EFI_D_ERROR,"L\n"));
+ }
+
+ // Description
+ Print (L"Description: ");
+ Status = EditHIInputStr (Description, MAX_STR_INPUT);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ if (StrLen (Description) == 0) {
+ StrnCpy (Description, DEFAULT_BOOT_ENTRY_DESCRIPTION, MAX_STR_INPUT);
+ }
+ BdsLoadOption->Description = Description;
+
+ // CmdLine
+ Print (L"Command Line: ");
+ Status = EditHIInputAscii (CmdLine, MAX_ASCII_INPUT);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ // Initrd
+ Print (L"Initrd name: ");
+ Status = EditHIInputStr (Initrd, MAX_STR_INPUT);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ CmdLineLength = AsciiStrLen (CmdLine);
+ if (CmdLineLength > 0) {
+ CmdLineLength += sizeof(CHAR8);
+ }
+
+ InitrdPathListLength = StrLen (Initrd) * sizeof(CHAR16);
+ if (InitrdPathListLength > 0) {
+ InitrdPathListLength += sizeof(CHAR16);
+ }
+
+ BdsLoadOption->OptionalDataSize = sizeof(LINUX_LOADER_OPTIONAL_DATA) + CmdLineLength + InitrdPathListLength;
+
+ LinuxOptionalData = (LINUX_LOADER_OPTIONAL_DATA*)AllocatePool (BdsLoadOption->OptionalDataSize);
+ BdsLoadOption->OptionalData = LinuxOptionalData;
+
+ LinuxOptionalData->Signature = LINUX_LOADER_SIGNATURE;
+ LinuxOptionalData->CmdLineLength = CmdLineLength;
+ LinuxOptionalData->InitrdPathListLength = InitrdPathListLength;
+
+ if (CmdLineLength > 0) {
+ CopyMem (LinuxOptionalData + 1, CmdLine, CmdLineLength);
+ }
+ if (InitrdPathListLength > 0) {
+ CopyMem ((UINT8*)(LinuxOptionalData + 1) + CmdLineLength, Initrd, InitrdPathListLength);
+ }
+
+ // Create or Update the boot entry
+ Status = BootOptionToLoadOptionVariable (BdsLoadOption);
+
+ return Status;
+}
|