X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ArmPlatformPkg%2FBds%2FBootMenu.c;fp=ArmPlatformPkg%2FBds%2FBootMenu.c;h=8caa3ce5ced7bb4024ecbbb5e4dfa1799158212c;hp=af7f1f1ac402ba5cc384eed55eb44f63cf4b9e80;hb=5d9e9d1a1c0aac8d3a1f60be50b2f504dac8d761;hpb=a81ccae41acfb4905d9b06c1f3223d43226c0152 diff --git a/ArmPlatformPkg/Bds/BootMenu.c b/ArmPlatformPkg/Bds/BootMenu.c index af7f1f1ac4..8caa3ce5ce 100644 --- a/ArmPlatformPkg/Bds/BootMenu.c +++ b/ArmPlatformPkg/Bds/BootMenu.c @@ -269,6 +269,8 @@ BootMenuAddBootOption ( EFI_DEVICE_PATH_PROTOCOL *DevicePathNodes; UINT8* OptionalData; UINTN OptionalDataSize; + BOOLEAN EfiBinary; + CHAR16 *LinuxDevicePath; Attributes = 0; SupportedBootDevice = NULL; @@ -281,8 +283,12 @@ BootMenuAddBootOption ( } // Create the specific device path node - Status = SupportedBootDevice->Support->CreateDevicePathNode (L"EFI Application or the kernel", &DevicePathNodes); - if (EFI_ERROR(Status)) { + if (FeaturePcdGet (PcdBdsLinuxSupport) && mLinuxLoaderDevicePath) { + Status = SupportedBootDevice->Support->CreateDevicePathNode (L"EFI Application or the kernel", &DevicePathNodes); + } else { + Status = SupportedBootDevice->Support->CreateDevicePathNode (L"EFI Application", &DevicePathNodes); + } + if (EFI_ERROR (Status)) { Status = EFI_ABORTED; goto EXIT; } @@ -293,8 +299,39 @@ BootMenuAddBootOption ( goto EXIT; } + // Is it an EFI application? + if (FeaturePcdGet (PcdBdsLinuxSupport) && mLinuxLoaderDevicePath) { + Status = IsEfiBinary (DevicePath, &EfiBinary); + if (EFI_ERROR (Status)) { + Status = EFI_ABORTED; + goto EXIT; + } + + if (EfiBinary == FALSE) { + Print (L"It is assumed the binary is a Linux kernel and the embedded Linux Loader is going to be used.\n"); + Print (L"Supported command line formats by the embedded Linux Loader:\n"); + Print (L"- -c \"\"\n"); + Print (L"- -c \"\" -f \n"); + Print (L"- -c \"\" -a \n"); + + // Copy the Linux path into the command line + LinuxDevicePath = ConvertDevicePathToText (DevicePath, FALSE, FALSE); + CopyMem (CmdLine, LinuxDevicePath, MAX (sizeof (CmdLine), StrSize (LinuxDevicePath))); + FreePool (LinuxDevicePath); + + // Free the generated Device Path + FreePool (DevicePath); + // and use the embedded Linux Loader as the EFI application + DevicePath = mLinuxLoaderDevicePath; + } else { + CmdLine[0] = L'\0'; + } + } else { + CmdLine[0] = L'\0'; + } + Print (L"Arguments to pass to the EFI Application: "); - Status = GetHIInputStr (CmdLine, BOOT_DEVICE_OPTION_MAX); + Status = EditHIInputStr (CmdLine, BOOT_DEVICE_OPTION_MAX); if (EFI_ERROR (Status)) { Status = EFI_ABORTED; goto EXIT; @@ -366,11 +403,13 @@ BootMenuUpdateBootOption ( CHAR16 BootDescription[BOOT_DEVICE_DESCRIPTION_MAX]; CHAR8 CmdLine[BOOT_DEVICE_OPTION_MAX]; CHAR16 UnicodeCmdLine[BOOT_DEVICE_OPTION_MAX]; + CHAR16 *LinuxDevicePath; EFI_DEVICE_PATH *DevicePath; UINT8* OptionalData; UINTN OptionalDataSize; BOOLEAN IsPrintable; BOOLEAN IsUnicode; + BOOLEAN EfiBinary; DisplayBootOptions (BootOptionsList); Status = SelectBootOption (BootOptionsList, UPDATE_BOOT_ENTRY, &BootOptionEntry); @@ -386,46 +425,87 @@ BootMenuUpdateBootOption ( return EFI_UNSUPPORTED; } - Status = DeviceSupport->UpdateDevicePathNode (BootOption->FilePathList, L"EFI Application or the kernel", &DevicePath); - if (EFI_ERROR(Status)) { - Status = EFI_ABORTED; - goto EXIT; + EfiBinary = TRUE; + if (FeaturePcdGet (PcdBdsLinuxSupport) && mLinuxLoaderDevicePath) { + Status = DeviceSupport->UpdateDevicePathNode (BootOption->FilePathList, L"EFI Application or the kernel", &DevicePath); + if (EFI_ERROR (Status)) { + Status = EFI_ABORTED; + goto EXIT; + } + + // Is it an EFI application? + Status = IsEfiBinary (DevicePath, &EfiBinary); + if (EFI_ERROR (Status)) { + Status = EFI_ABORTED; + goto EXIT; + } + + if (EfiBinary == FALSE) { + Print (L"It is assumed the binary is a Linux kernel and the embedded Linux Loader is going to be used.\n"); + Print (L"Supported command line formats by the embedded Linux Loader:\n"); + Print (L"- -c \"\"\n"); + Print (L"- -c \"\" -f \n"); + Print (L"- -c \"\" -a \n"); + + // Copy the Linux path into the command line + LinuxDevicePath = ConvertDevicePathToText (DevicePath, FALSE, FALSE); + CopyMem (UnicodeCmdLine, LinuxDevicePath, MAX (sizeof (UnicodeCmdLine), StrSize (LinuxDevicePath))); + FreePool (LinuxDevicePath); + + // Free the generated Device Path + FreePool (DevicePath); + // and use the embedded Linux Loader as the EFI application + DevicePath = mLinuxLoaderDevicePath; + + // The command line is a unicode printable string + IsPrintable = TRUE; + IsUnicode = TRUE; + } + } else { + Status = DeviceSupport->UpdateDevicePathNode (BootOption->FilePathList, L"EFI Application", &DevicePath); + if (EFI_ERROR (Status)) { + Status = EFI_ABORTED; + goto EXIT; + } } Print (L"Arguments to pass to the EFI Application: "); - if (BootOption->OptionalDataSize > 0) { - IsPrintable = IsPrintableString (BootOption->OptionalData, &IsUnicode); - if (IsPrintable) { - // - // The size in bytes of the string, final zero included, should - // be equal to or at least lower than "BootOption->OptionalDataSize" - // and the "IsPrintableString()" has already tested that the length - // in number of characters is smaller than BOOT_DEVICE_OPTION_MAX, - // final '\0' included. We can thus copy the string for editing - // using "CopyMem()". Furthermore, note that in the case of an Unicode - // string "StrnCpy()" and "StrCpy()" can not be used to copy the - // string because the data pointed to by "BootOption->OptionalData" - // is not necessarily 2-byte aligned. - // - if (IsUnicode) { - CopyMem ( - UnicodeCmdLine, BootOption->OptionalData, - MIN (sizeof (UnicodeCmdLine), - BootOption->OptionalDataSize) - ); - } else { - CopyMem ( - CmdLine, BootOption->OptionalData, - MIN (sizeof (CmdLine), - BootOption->OptionalDataSize) - ); + // When the command line has not been initialized by the embedded Linux loader earlier + if (EfiBinary) { + if (BootOption->OptionalDataSize > 0) { + IsPrintable = IsPrintableString (BootOption->OptionalData, &IsUnicode); + if (IsPrintable) { + // + // The size in bytes of the string, final zero included, should + // be equal to or at least lower than "BootOption->OptionalDataSize" + // and the "IsPrintableString()" has already tested that the length + // in number of characters is smaller than BOOT_DEVICE_OPTION_MAX, + // final '\0' included. We can thus copy the string for editing + // using "CopyMem()". Furthermore, note that in the case of an Unicode + // string "StrnCpy()" and "StrCpy()" can not be used to copy the + // string because the data pointed to by "BootOption->OptionalData" + // is not necessarily 2-byte aligned. + // + if (IsUnicode) { + CopyMem ( + UnicodeCmdLine, BootOption->OptionalData, + MIN (sizeof (UnicodeCmdLine), + BootOption->OptionalDataSize) + ); + } else { + CopyMem ( + CmdLine, BootOption->OptionalData, + MIN (sizeof (CmdLine), + BootOption->OptionalDataSize) + ); + } } + } else { + UnicodeCmdLine[0] = L'\0'; + IsPrintable = TRUE; + IsUnicode = TRUE; } - } else { - UnicodeCmdLine[0] = L'\0'; - IsPrintable = TRUE; - IsUnicode = TRUE; } // We do not request arguments for OptionalData that cannot be printed @@ -909,7 +989,6 @@ struct BOOT_MAIN_ENTRY { { L"Boot Manager", BootMenuManager }, }; - EFI_STATUS BootMenuMain ( VOID @@ -929,6 +1008,12 @@ BootMenuMain ( BootOption = NULL; BootMainEntryCount = sizeof(BootMainEntries) / sizeof(struct BOOT_MAIN_ENTRY); + if (FeaturePcdGet (PcdBdsLinuxSupport)) { + // Check Linux Loader is present + Status = LocateEfiApplicationInFvByGuid (&mLinuxLoaderAppGuid, &mLinuxLoaderDevicePath); + ASSERT_EFI_ERROR (Status); + } + while (TRUE) { // Get Boot#### list BootOptionList (&BootOptionsList);