]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/Bds/BootMenu.c
AppPkg: Update email and URL.
[mirror_edk2.git] / ArmPlatformPkg / Bds / BootMenu.c
index d2dccbc9f274782719efdef8b8e29823967cabdc..5cbac1d2dc1ab91be8ae402bb0e41e888d95aa38 100644 (file)
@@ -14,8 +14,6 @@
 \r
 #include "BdsInternal.h"\r
 \r
-#include <Guid/ArmGlobalVariableHob.h>\r
-\r
 #include <libfdt.h>\r
 \r
 /**\r
@@ -54,8 +52,6 @@ DisplayBootOptions (
     DEBUG_CODE_BEGIN ();\r
       CHAR16*                           DevicePathTxt;\r
       EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;\r
-      ARM_BDS_LOADER_TYPE               LoaderType;\r
-      ARM_BDS_LOADER_OPTIONAL_DATA*     OptionalData;\r
 \r
       Status = gBS->LocateProtocol (\r
                      &gEfiDevicePathToTextProtocolGuid,\r
@@ -70,20 +66,11 @@ DisplayBootOptions (
                                                   );\r
       Print (L"\t- %s\n", DevicePathTxt);\r
 \r
-      OptionalData = BdsLoadOption->OptionalData;\r
-      if (IS_ARM_BDS_BOOTENTRY (BdsLoadOption)) {\r
-        LoaderType = (ARM_BDS_LOADER_TYPE)ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);\r
-        if ((LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) ||\r
-            (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT )   ) {\r
-          Print (L"\t- Arguments: %a\n", &OptionalData->Arguments.LinuxArguments + 1);\r
-        }\r
-      } else if (OptionalData != NULL) {\r
-        if (IsPrintableString (OptionalData, &IsUnicode)) {\r
-          if (IsUnicode) {\r
-            Print (L"\t- Arguments: %s\n", OptionalData);\r
-          } else {\r
-            AsciiPrint ("\t- Arguments: %a\n", OptionalData);\r
-          }\r
+      if (IsPrintableString (BdsLoadOption->OptionalData, &IsUnicode)) {\r
+        if (IsUnicode) {\r
+          Print (L"\t- Arguments: %s\n", BdsLoadOption->OptionalData);\r
+        } else {\r
+          AsciiPrint ("\t- Arguments: %a\n", BdsLoadOption->OptionalData);\r
         }\r
       }\r
 \r
@@ -272,22 +259,16 @@ BootMenuAddBootOption (
 {\r
   EFI_STATUS                Status;\r
   BDS_SUPPORTED_DEVICE*     SupportedBootDevice;\r
-  ARM_BDS_LOADER_ARGUMENTS* BootArguments;\r
   CHAR16                    BootDescription[BOOT_DEVICE_DESCRIPTION_MAX];\r
-  CHAR8                     AsciiCmdLine[BOOT_DEVICE_OPTION_MAX];\r
   CHAR16                    CmdLine[BOOT_DEVICE_OPTION_MAX];\r
   UINT32                    Attributes;\r
-  ARM_BDS_LOADER_TYPE       BootType;\r
   BDS_LOAD_OPTION_ENTRY     *BdsLoadOptionEntry;\r
   EFI_DEVICE_PATH           *DevicePath;\r
   EFI_DEVICE_PATH_PROTOCOL  *DevicePathNodes;\r
-  EFI_DEVICE_PATH_PROTOCOL  *InitrdPathNodes;\r
-  EFI_DEVICE_PATH_PROTOCOL  *InitrdPath;\r
-  UINTN                     CmdLineSize;\r
-  BOOLEAN                   InitrdSupport;\r
-  UINTN                     InitrdSize;\r
   UINT8*                    OptionalData;\r
   UINTN                     OptionalDataSize;\r
+  BOOLEAN                   EfiBinary;\r
+  CHAR16                    *LinuxDevicePath;\r
 \r
   Attributes                = 0;\r
   SupportedBootDevice = NULL;\r
@@ -300,8 +281,12 @@ BootMenuAddBootOption (
   }\r
 \r
   // Create the specific device path node\r
-  Status = SupportedBootDevice->Support->CreateDevicePathNode (L"EFI Application or the kernel", &DevicePathNodes);\r
-  if (EFI_ERROR(Status)) {\r
+  if (FeaturePcdGet (PcdBdsLinuxSupport) && mLinuxLoaderDevicePath) {\r
+    Status = SupportedBootDevice->Support->CreateDevicePathNode (L"EFI Application or the kernel", &DevicePathNodes);\r
+  } else {\r
+    Status = SupportedBootDevice->Support->CreateDevicePathNode (L"EFI Application", &DevicePathNodes);\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
     Status = EFI_ABORTED;\r
     goto EXIT;\r
   }\r
@@ -312,80 +297,47 @@ BootMenuAddBootOption (
     goto EXIT;\r
   }\r
 \r
-  if (SupportedBootDevice->Support->RequestBootType) {\r
-    Status = BootDeviceGetType (DevicePath, &BootType, &Attributes);\r
-    if (EFI_ERROR(Status)) {\r
-      Status = EFI_ABORTED;\r
-      goto EXIT;\r
-    }\r
-  } else {\r
-    BootType = BDS_LOADER_EFI_APPLICATION;\r
-  }\r
-\r
-  if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {\r
-    Print(L"Add an initrd: ");\r
-    Status = GetHIInputBoolean (&InitrdSupport);\r
-    if (EFI_ERROR(Status)) {\r
+  // Is it an EFI application?\r
+  if (FeaturePcdGet (PcdBdsLinuxSupport) && mLinuxLoaderDevicePath) {\r
+    Status = IsEfiBinary (DevicePath, &EfiBinary);\r
+    if (EFI_ERROR (Status)) {\r
       Status = EFI_ABORTED;\r
       goto EXIT;\r
     }\r
 \r
-    if (InitrdSupport) {\r
-      // Create the specific device path node\r
-      Status = SupportedBootDevice->Support->CreateDevicePathNode (L"initrd", &InitrdPathNodes);\r
-      if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) { // EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd\r
-        Status = EFI_ABORTED;\r
-        goto EXIT;\r
-      }\r
-\r
-      if (InitrdPathNodes != NULL) {\r
-        // Append the Device Path to the selected device path\r
-        InitrdPath = AppendDevicePath (SupportedBootDevice->DevicePathProtocol, (CONST EFI_DEVICE_PATH_PROTOCOL *)InitrdPathNodes);\r
-        // Free the InitrdPathNodes created by Support->CreateDevicePathNode()\r
-        FreePool (InitrdPathNodes);\r
-\r
-        if (InitrdPath == NULL) {\r
-          Status = EFI_OUT_OF_RESOURCES;\r
-          goto EXIT;\r
-        }\r
-      } else {\r
-        InitrdPath = NULL;\r
-      }\r
+    if (EfiBinary == FALSE) {\r
+      Print (L"It is assumed the binary is a Linux kernel and the embedded Linux Loader is going to be used.\n");\r
+      Print (L"Supported command line formats by the embedded Linux Loader:\n");\r
+      Print (L"- <EFI device path of the Linux kernel> -c \"<Linux kernel command line>\"\n");\r
+      Print (L"- <EFI device path of the Linux kernel> -c \"<Linux kernel command line>\" -f <EFI Device Path of the Linux initrd>\n");\r
+      Print (L"- <EFI device path of the Linux kernel> -c \"<Linux kernel command line>\" -a <Machine Type for ATAG Linux kernel>\n");\r
+\r
+      // Copy the Linux path into the command line\r
+      LinuxDevicePath = ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
+      CopyMem (CmdLine, LinuxDevicePath, MAX (sizeof (CmdLine), StrSize (LinuxDevicePath)));\r
+      FreePool (LinuxDevicePath);\r
+\r
+      // Free the generated Device Path\r
+      FreePool (DevicePath);\r
+      // and use the embedded Linux Loader as the EFI application\r
+      DevicePath = mLinuxLoaderDevicePath;\r
     } else {\r
-      InitrdPath = NULL;\r
-    }\r
-\r
-    Print(L"Arguments to pass to the binary: ");\r
-    Status = GetHIInputAscii (AsciiCmdLine, BOOT_DEVICE_OPTION_MAX);\r
-    if (EFI_ERROR(Status)) {\r
-      Status = EFI_ABORTED;\r
-      goto FREE_DEVICE_PATH;\r
+      CmdLine[0] = L'\0';\r
     }\r
-\r
-    CmdLineSize = AsciiStrSize (AsciiCmdLine);\r
-    InitrdSize = GetDevicePathSize (InitrdPath);\r
-\r
-    OptionalDataSize = sizeof(ARM_BDS_LOADER_ARGUMENTS) + CmdLineSize + InitrdSize;\r
-    BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)AllocatePool (OptionalDataSize);\r
-\r
-    BootArguments->LinuxArguments.CmdLineSize = CmdLineSize;\r
-    BootArguments->LinuxArguments.InitrdSize = InitrdSize;\r
-    CopyMem ((VOID*)(&BootArguments->LinuxArguments + 1), AsciiCmdLine, CmdLineSize);\r
-    CopyMem ((VOID*)((UINTN)(&BootArguments->LinuxArguments + 1) + CmdLineSize), InitrdPath, InitrdSize);\r
-\r
-    OptionalData = (UINT8*)BootArguments;\r
   } else {\r
-    Print (L"Arguments to pass to the EFI Application: ");\r
-    Status = GetHIInputStr (CmdLine, BOOT_DEVICE_OPTION_MAX);\r
-    if (EFI_ERROR (Status)) {\r
-      Status = EFI_ABORTED;\r
-      goto EXIT;\r
-    }\r
+    CmdLine[0] = L'\0';\r
+  }\r
 \r
-    OptionalData = (UINT8*)CmdLine;\r
-    OptionalDataSize = StrSize (CmdLine);\r
+  Print (L"Arguments to pass to the EFI Application: ");\r
+  Status = EditHIInputStr (CmdLine, BOOT_DEVICE_OPTION_MAX);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_ABORTED;\r
+    goto EXIT;\r
   }\r
 \r
+  OptionalData = (UINT8*)CmdLine;\r
+  OptionalDataSize = StrSize (CmdLine);\r
+\r
   Print(L"Description for this new Entry: ");\r
   Status = GetHIInputStr (BootDescription, BOOT_DEVICE_DESCRIPTION_MAX);\r
   if (EFI_ERROR(Status)) {\r
@@ -395,7 +347,7 @@ BootMenuAddBootOption (
 \r
   // Create new entry\r
   BdsLoadOptionEntry = (BDS_LOAD_OPTION_ENTRY*)AllocatePool (sizeof(BDS_LOAD_OPTION_ENTRY));\r
-  Status = BootOptionCreate (Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize, &BdsLoadOptionEntry->BdsLoadOption);\r
+  Status = BootOptionCreate (Attributes, BootDescription, DevicePath, OptionalData, OptionalDataSize, &BdsLoadOptionEntry->BdsLoadOption);\r
   if (!EFI_ERROR(Status)) {\r
     InsertTailList (BootOptionsList, &BdsLoadOptionEntry->Link);\r
   }\r
@@ -446,24 +398,16 @@ BootMenuUpdateBootOption (
   BDS_LOAD_OPTION_ENTRY         *BootOptionEntry;\r
   BDS_LOAD_OPTION               *BootOption;\r
   BDS_LOAD_OPTION_SUPPORT*      DeviceSupport;\r
-  ARM_BDS_LOADER_ARGUMENTS*     BootArguments;\r
   CHAR16                        BootDescription[BOOT_DEVICE_DESCRIPTION_MAX];\r
   CHAR8                         CmdLine[BOOT_DEVICE_OPTION_MAX];\r
   CHAR16                        UnicodeCmdLine[BOOT_DEVICE_OPTION_MAX];\r
+  CHAR16                        *LinuxDevicePath;\r
   EFI_DEVICE_PATH               *DevicePath;\r
-  EFI_DEVICE_PATH               *TempInitrdPath;\r
-  ARM_BDS_LOADER_TYPE           BootType;\r
-  ARM_BDS_LOADER_OPTIONAL_DATA* LoaderOptionalData;\r
-  ARM_BDS_LINUX_ARGUMENTS*      LinuxArguments;\r
-  EFI_DEVICE_PATH               *InitrdPathNodes;\r
-  EFI_DEVICE_PATH               *InitrdPath;\r
-  UINTN                         InitrdSize;\r
-  UINTN                         CmdLineSize;\r
-  BOOLEAN                       InitrdSupport;\r
   UINT8*                        OptionalData;\r
   UINTN                         OptionalDataSize;\r
   BOOLEAN                       IsPrintable;\r
   BOOLEAN                       IsUnicode;\r
+  BOOLEAN                       EfiBinary;\r
 \r
   DisplayBootOptions (BootOptionsList);\r
   Status = SelectBootOption (BootOptionsList, UPDATE_BOOT_ENTRY, &BootOptionEntry);\r
@@ -479,111 +423,54 @@ BootMenuUpdateBootOption (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  Status = DeviceSupport->UpdateDevicePathNode (BootOption->FilePathList, L"EFI Application or the kernel", &DevicePath);\r
-  if (EFI_ERROR(Status)) {\r
-    Status = EFI_ABORTED;\r
-    goto EXIT;\r
-  }\r
-\r
-  if (DeviceSupport->RequestBootType) {\r
-    Status = BootDeviceGetType (DevicePath, &BootType, &BootOption->Attributes);\r
-    if (EFI_ERROR(Status)) {\r
+  EfiBinary = TRUE;\r
+  if (FeaturePcdGet (PcdBdsLinuxSupport) && mLinuxLoaderDevicePath) {\r
+    Status = DeviceSupport->UpdateDevicePathNode (BootOption->FilePathList, L"EFI Application or the kernel", &DevicePath);\r
+    if (EFI_ERROR (Status)) {\r
       Status = EFI_ABORTED;\r
       goto EXIT;\r
     }\r
-  }\r
 \r
-  LoaderOptionalData = BootOption->OptionalData;\r
-  if (LoaderOptionalData != NULL) {\r
-    BootType = (ARM_BDS_LOADER_TYPE)ReadUnaligned32 ((UINT32 *)(&LoaderOptionalData->Header.LoaderType));\r
-  } else {\r
-    BootType = BDS_LOADER_EFI_APPLICATION;\r
-  }\r
-\r
-  if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {\r
-    LinuxArguments = &LoaderOptionalData->Arguments.LinuxArguments;\r
-\r
-    CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);\r
-\r
-    InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);\r
-    if (InitrdSize > 0) {\r
-      Print(L"Keep the initrd: ");\r
-    } else {\r
-      Print(L"Add an initrd: ");\r
-    }\r
-    Status = GetHIInputBoolean (&InitrdSupport);\r
-    if (EFI_ERROR(Status)) {\r
+    // Is it an EFI application?\r
+    Status = IsEfiBinary (DevicePath, &EfiBinary);\r
+    if (EFI_ERROR (Status)) {\r
       Status = EFI_ABORTED;\r
       goto EXIT;\r
     }\r
 \r
-    if (InitrdSupport) {\r
-      if (InitrdSize > 0) {\r
-        // Case we update the initrd device path\r
-        Status = DeviceSupport->UpdateDevicePathNode ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize), L"initrd", &InitrdPath);\r
-        if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {// EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd\r
-          Status = EFI_ABORTED;\r
-          goto EXIT;\r
-        }\r
-        InitrdSize = GetDevicePathSize (InitrdPath);\r
-      } else {\r
-        // Case we create the initrd device path\r
+    if (EfiBinary == FALSE) {\r
+      Print (L"It is assumed the binary is a Linux kernel and the embedded Linux Loader is going to be used.\n");\r
+      Print (L"Supported command line formats by the embedded Linux Loader:\n");\r
+      Print (L"- <EFI device path of the Linux kernel> -c \"<Linux kernel command line>\"\n");\r
+      Print (L"- <EFI device path of the Linux kernel> -c \"<Linux kernel command line>\" -f <EFI Device Path of the Linux initrd>\n");\r
+      Print (L"- <EFI device path of the Linux kernel> -c \"<Linux kernel command line>\" -a <Machine Type for ATAG Linux kernel>\n");\r
 \r
-        Status = DeviceSupport->CreateDevicePathNode (L"initrd", &InitrdPathNodes);\r
-        if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) { // EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd\r
-          Status = EFI_ABORTED;\r
-          goto EXIT;\r
-        }\r
+      // Copy the Linux path into the command line\r
+      LinuxDevicePath = ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
+      CopyMem (UnicodeCmdLine, LinuxDevicePath, MAX (sizeof (UnicodeCmdLine), StrSize (LinuxDevicePath)));\r
+      FreePool (LinuxDevicePath);\r
 \r
-        if (InitrdPathNodes != NULL) {\r
-          // Duplicate Linux kernel Device Path\r
-          TempInitrdPath = DuplicateDevicePath (BootOption->FilePathList);\r
-          // Replace Linux kernel Node by EndNode\r
-          SetDevicePathEndNode (GetLastDevicePathNode (TempInitrdPath));\r
-          // Append the Device Path to the selected device path\r
-          InitrdPath = AppendDevicePath (TempInitrdPath, (CONST EFI_DEVICE_PATH_PROTOCOL *)InitrdPathNodes);\r
-          FreePool (TempInitrdPath);\r
-          // Free the InitrdPathNodes created by Support->CreateDevicePathNode()\r
-          FreePool (InitrdPathNodes);\r
-          if (InitrdPath == NULL) {\r
-            Status = EFI_OUT_OF_RESOURCES;\r
-            goto EXIT;\r
-          }\r
-          InitrdSize = GetDevicePathSize (InitrdPath);\r
-        } else {\r
-          InitrdPath = NULL;\r
-        }\r
-      }\r
-    } else {\r
-      InitrdSize = 0;\r
-    }\r
+      // Free the generated Device Path\r
+      FreePool (DevicePath);\r
+      // and use the embedded Linux Loader as the EFI application\r
+      DevicePath = mLinuxLoaderDevicePath;\r
 \r
-    Print(L"Arguments to pass to the binary: ");\r
-    if (CmdLineSize > 0) {\r
-      AsciiStrnCpy (CmdLine, (CONST CHAR8*)(LinuxArguments + 1), sizeof (CmdLine));\r
-      CmdLine[sizeof (CmdLine) - 1] = '\0';\r
-    } else {\r
-      CmdLine[0] = '\0';\r
+      // The command line is a unicode printable string\r
+      IsPrintable = TRUE;\r
+      IsUnicode = TRUE;\r
     }\r
-    Status = EditHIInputAscii (CmdLine, BOOT_DEVICE_OPTION_MAX);\r
-    if (EFI_ERROR(Status)) {\r
+  } else {\r
+    Status = DeviceSupport->UpdateDevicePathNode (BootOption->FilePathList, L"EFI Application", &DevicePath);\r
+    if (EFI_ERROR (Status)) {\r
       Status = EFI_ABORTED;\r
-      goto FREE_DEVICE_PATH;\r
+      goto EXIT;\r
     }\r
+  }\r
 \r
-    CmdLineSize = AsciiStrSize (CmdLine);\r
-\r
-    OptionalDataSize = sizeof(ARM_BDS_LOADER_ARGUMENTS) + CmdLineSize + InitrdSize;\r
-    BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)AllocatePool (OptionalDataSize);\r
-    BootArguments->LinuxArguments.CmdLineSize = CmdLineSize;\r
-    BootArguments->LinuxArguments.InitrdSize = InitrdSize;\r
-    CopyMem (&BootArguments->LinuxArguments + 1, CmdLine, CmdLineSize);\r
-    CopyMem ((VOID*)((UINTN)(&BootArguments->LinuxArguments + 1) + CmdLineSize), InitrdPath, InitrdSize);\r
-\r
-    OptionalData = (UINT8*)BootArguments;\r
-  } else {\r
-    Print (L"Arguments to pass to the EFI Application: ");\r
+  Print (L"Arguments to pass to the EFI Application: ");\r
 \r
+  // When the command line has not been initialized by the embedded Linux loader earlier\r
+  if (EfiBinary) {\r
     if (BootOption->OptionalDataSize > 0) {\r
       IsPrintable = IsPrintableString (BootOption->OptionalData, &IsUnicode);\r
       if (IsPrintable) {\r
@@ -617,33 +504,33 @@ BootMenuUpdateBootOption (
       IsPrintable = TRUE;\r
       IsUnicode = TRUE;\r
     }\r
+  }\r
 \r
-    // We do not request arguments for OptionalData that cannot be printed\r
-    if (IsPrintable) {\r
-      if (IsUnicode) {\r
-        Status = EditHIInputStr (UnicodeCmdLine, BOOT_DEVICE_OPTION_MAX);\r
-        if (EFI_ERROR (Status)) {\r
-          Status = EFI_ABORTED;\r
-          goto FREE_DEVICE_PATH;\r
-        }\r
-\r
-        OptionalData = (UINT8*)UnicodeCmdLine;\r
-        OptionalDataSize = StrSize (UnicodeCmdLine);\r
-      } else {\r
-        Status = EditHIInputAscii (CmdLine, BOOT_DEVICE_OPTION_MAX);\r
-        if (EFI_ERROR (Status)) {\r
-          Status = EFI_ABORTED;\r
-          goto FREE_DEVICE_PATH;\r
-        }\r
-\r
-        OptionalData = (UINT8*)CmdLine;\r
-        OptionalDataSize = AsciiStrSize (CmdLine);\r
+  // We do not request arguments for OptionalData that cannot be printed\r
+  if (IsPrintable) {\r
+    if (IsUnicode) {\r
+      Status = EditHIInputStr (UnicodeCmdLine, BOOT_DEVICE_OPTION_MAX);\r
+      if (EFI_ERROR (Status)) {\r
+        Status = EFI_ABORTED;\r
+        goto FREE_DEVICE_PATH;\r
       }\r
+\r
+      OptionalData = (UINT8*)UnicodeCmdLine;\r
+      OptionalDataSize = StrSize (UnicodeCmdLine);\r
     } else {\r
-      // We keep the former OptionalData\r
-      OptionalData = BootOption->OptionalData;\r
-      OptionalDataSize = BootOption->OptionalDataSize;\r
+      Status = EditHIInputAscii (CmdLine, BOOT_DEVICE_OPTION_MAX);\r
+      if (EFI_ERROR (Status)) {\r
+        Status = EFI_ABORTED;\r
+        goto FREE_DEVICE_PATH;\r
+      }\r
+\r
+      OptionalData = (UINT8*)CmdLine;\r
+      OptionalDataSize = AsciiStrSize (CmdLine);\r
     }\r
+  } else {\r
+    // We keep the former OptionalData\r
+    OptionalData = BootOption->OptionalData;\r
+    OptionalDataSize = BootOption->OptionalDataSize;\r
   }\r
 \r
   Print(L"Description for this new Entry: ");\r
@@ -655,7 +542,7 @@ BootMenuUpdateBootOption (
   }\r
 \r
   // Update the entry\r
-  Status = BootOptionUpdate (BootOption, BootOption->Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize);\r
+  Status = BootOptionUpdate (BootOption, BootOption->Attributes, BootDescription, DevicePath, OptionalData, OptionalDataSize);\r
 \r
 FREE_DEVICE_PATH:\r
   FreePool (DevicePath);\r
@@ -1069,17 +956,27 @@ BootShell (
   IN LIST_ENTRY *BootOptionsList\r
   )\r
 {\r
-  EFI_STATUS Status;\r
+  EFI_STATUS       Status;\r
+  EFI_DEVICE_PATH* EfiShellDevicePath;\r
 \r
-  // Start EFI Shell\r
-  Status = BdsLoadApplication (gImageHandle, L"Shell", 0, NULL);\r
+  // Find the EFI Shell\r
+  Status = LocateEfiApplicationInFvByName (L"Shell", &EfiShellDevicePath);\r
   if (Status == EFI_NOT_FOUND) {\r
     Print (L"Error: EFI Application not found.\n");\r
-  } else if (EFI_ERROR(Status)) {\r
-    Print (L"Error: Status Code: 0x%X\n",(UINT32)Status);\r
-  }\r
+    return Status;\r
+  } else if (EFI_ERROR (Status)) {\r
+    Print (L"Error: Status Code: 0x%X\n", (UINT32)Status);\r
+    return Status;\r
+  } else {\r
+    // Need to connect every drivers to ensure no dependencies are missing for the application\r
+    Status = BdsConnectAllDrivers ();\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));\r
+      return Status;\r
+    }\r
 \r
-  return Status;\r
+    return BdsStartEfiApplication (gImageHandle, EfiShellDevicePath, 0, NULL);\r
+  }\r
 }\r
 \r
 struct BOOT_MAIN_ENTRY {\r
@@ -1090,7 +987,6 @@ struct BOOT_MAIN_ENTRY {
     { L"Boot Manager", BootMenuManager },\r
 };\r
 \r
-\r
 EFI_STATUS\r
 BootMenuMain (\r
   VOID\r
@@ -1110,6 +1006,12 @@ BootMenuMain (
   BootOption         = NULL;\r
   BootMainEntryCount = sizeof(BootMainEntries) / sizeof(struct BOOT_MAIN_ENTRY);\r
 \r
+  if (FeaturePcdGet (PcdBdsLinuxSupport)) {\r
+    // Check Linux Loader is present\r
+    Status = LocateEfiApplicationInFvByGuid (&mLinuxLoaderAppGuid, &mLinuxLoaderDevicePath);\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
   while (TRUE) {\r
     // Get Boot#### list\r
     BootOptionList (&BootOptionsList);\r
@@ -1129,9 +1031,6 @@ BootMenuMain (
       DEBUG_CODE_BEGIN();\r
         CHAR16*                           DevicePathTxt;\r
         EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;\r
-        ARM_BDS_LOADER_OPTIONAL_DATA*     OptionalData;\r
-        UINTN                             CmdLineSize;\r
-        ARM_BDS_LOADER_TYPE               LoaderType;\r
 \r
         Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);\r
         if (EFI_ERROR(Status)) {\r
@@ -1143,39 +1042,7 @@ BootMenuMain (
 \r
         Print(L"\t- %s\n",DevicePathTxt);\r
 \r
-        // If it is a supported BootEntry then print its details\r
-        if (IS_ARM_BDS_BOOTENTRY (BootOption)) {\r
-          OptionalData = BootOption->OptionalData;\r
-          LoaderType = (ARM_BDS_LOADER_TYPE)ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);\r
-          if ((LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) || (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT)) {\r
-            if (ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.InitrdSize) > 0) {\r
-              CmdLineSize = ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.CmdLineSize);\r
-              DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (\r
-                  GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(&OptionalData->Arguments.LinuxArguments + 1) + CmdLineSize)), TRUE, TRUE);\r
-              Print(L"\t- Initrd: %s\n", DevicePathTxt);\r
-            }\r
-            if (ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.CmdLineSize) > 0) {\r
-              Print(L"\t- Arguments: %a\n", (&OptionalData->Arguments.LinuxArguments + 1));\r
-            }\r
-          }\r
-\r
-          switch (LoaderType) {\r
-            case BDS_LOADER_EFI_APPLICATION:\r
-              Print(L"\t- LoaderType: EFI Application\n");\r
-              break;\r
-\r
-            case BDS_LOADER_KERNEL_LINUX_ATAG:\r
-              Print(L"\t- LoaderType: Linux kernel with ATAG support\n");\r
-              break;\r
-\r
-            case BDS_LOADER_KERNEL_LINUX_FDT:\r
-              Print(L"\t- LoaderType: Linux kernel with FDT support\n");\r
-              break;\r
-\r
-            default:\r
-              Print(L"\t- LoaderType: Not recognized (%d)\n", LoaderType);\r
-          }\r
-        } else if (BootOption->OptionalData != NULL) {\r
+        if (BootOption->OptionalData != NULL) {\r
           if (IsPrintableString (BootOption->OptionalData, &IsUnicode)) {\r
             if (IsUnicode) {\r
               Print (L"\t- Arguments: %s\n", BootOption->OptionalData);\r