コード例 #1
0
ファイル: BootMenu.c プロジェクト: FishYu1222/edk2
EFI_STATUS
BootMenuMain (
  VOID
  )
{
  LIST_ENTRY                    BootOptionsList;
  UINTN                         OptionCount;
  UINTN                         BootOptionCount;
  EFI_STATUS                    Status;
  LIST_ENTRY*                   Entry;
  BDS_LOAD_OPTION*              BootOption;
  UINTN                         BootOptionSelected;
  UINTN                         Index;
  UINTN                         BootMainEntryCount;
  BOOLEAN                       IsUnicode;

  BootOption         = NULL;
  BootMainEntryCount = sizeof(BootMainEntries) / sizeof(struct BOOT_MAIN_ENTRY);

  while (TRUE) {
    // Get Boot#### list
    BootOptionList (&BootOptionsList);

    OptionCount = 1;

    // Display the Boot options
    for (Entry = GetFirstNode (&BootOptionsList);
         !IsNull (&BootOptionsList,Entry);
         Entry = GetNextNode (&BootOptionsList,Entry)
         )
    {
      BootOption = LOAD_OPTION_FROM_LINK(Entry);

      Print(L"[%d] %s\n", OptionCount, BootOption->Description);

      DEBUG_CODE_BEGIN();
        CHAR16*                           DevicePathTxt;
        EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
        ARM_BDS_LOADER_OPTIONAL_DATA*     OptionalData;
        UINTN                             CmdLineSize;
        ARM_BDS_LOADER_TYPE               LoaderType;

        Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
        if (EFI_ERROR(Status)) {
          // You must provide an implementation of DevicePathToTextProtocol in your firmware (eg: DevicePathDxe)
          DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathToTextProtocol\n"));
          return Status;
        }
        DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootOption->FilePathList, TRUE, TRUE);

        Print(L"\t- %s\n",DevicePathTxt);

        // If it is a supported BootEntry then print its details
        if (IS_ARM_BDS_BOOTENTRY (BootOption)) {
          OptionalData = BootOption->OptionalData;
          LoaderType = (ARM_BDS_LOADER_TYPE)ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);
          if ((LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) || (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT)) {
            if (ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.InitrdSize) > 0) {
              CmdLineSize = ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.CmdLineSize);
              DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (
                  GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(&OptionalData->Arguments.LinuxArguments + 1) + CmdLineSize)), TRUE, TRUE);
              Print(L"\t- Initrd: %s\n", DevicePathTxt);
            }
            if (ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.CmdLineSize) > 0) {
              Print(L"\t- Arguments: %a\n", (&OptionalData->Arguments.LinuxArguments + 1));
            }
          }

          switch (LoaderType) {
            case BDS_LOADER_EFI_APPLICATION:
              Print(L"\t- LoaderType: EFI Application\n");
              break;

            case BDS_LOADER_KERNEL_LINUX_ATAG:
              Print(L"\t- LoaderType: Linux kernel with ATAG support\n");
              break;

            case BDS_LOADER_KERNEL_LINUX_FDT:
              Print(L"\t- LoaderType: Linux kernel with FDT support\n");
              break;

            default:
              Print(L"\t- LoaderType: Not recognized (%d)\n", LoaderType);
          }
        } else if (BootOption->OptionalData != NULL) {
          if (IsPrintableString (BootOption->OptionalData, &IsUnicode)) {
            if (IsUnicode) {
              Print (L"\t- Arguments: %s\n", BootOption->OptionalData);
            } else {
              AsciiPrint ("\t- Arguments: %a\n", BootOption->OptionalData);
            }
          }
        }
        FreePool(DevicePathTxt);
      DEBUG_CODE_END();

      OptionCount++;
    }
    BootOptionCount = OptionCount-1;

    // Display the hardcoded Boot entries
    for (Index = 0; Index < BootMainEntryCount; Index++) {
      Print(L"[%d] %s\n",OptionCount,BootMainEntries[Index]);
      OptionCount++;
    }

    // Request the boot entry from the user
    BootOptionSelected = 0;
    while (BootOptionSelected == 0) {
      Print(L"Start: ");
      Status = GetHIInputInteger (&BootOptionSelected);
      if (EFI_ERROR(Status) || (BootOptionSelected == 0) || (BootOptionSelected > OptionCount)) {
        Print(L"Invalid input (max %d)\n",(OptionCount-1));
        BootOptionSelected = 0;
      }
    }

    // Start the selected entry
    if (BootOptionSelected > BootOptionCount) {
      // Start the hardcoded entry
      Status = BootMainEntries[BootOptionSelected - BootOptionCount - 1].Callback (&BootOptionsList);
    } else {
      // Find the selected entry from the Boot#### list
      Index = 1;
      for (Entry = GetFirstNode (&BootOptionsList);
           !IsNull (&BootOptionsList,Entry);
           Entry = GetNextNode (&BootOptionsList,Entry)
           )
      {
        if (Index == BootOptionSelected) {
          BootOption = LOAD_OPTION_FROM_LINK(Entry);
          break;
        }
        Index++;
      }

      Status = BootOptionStart (BootOption);
    }
  }
  // Should never go here
}
コード例 #2
0
ファイル: BootOption.c プロジェクト: vchong/edk2
EFI_STATUS
BootOptionStart (
  IN BDS_LOAD_OPTION *BootOption
  )
{
  EFI_STATUS                            Status;
  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL*   EfiDevicePathFromTextProtocol;
  UINT32                                LoaderType;
  ARM_BDS_LOADER_OPTIONAL_DATA*         OptionalData;
  ARM_BDS_LINUX_ARGUMENTS*              LinuxArguments;
  EFI_DEVICE_PATH_PROTOCOL*             FdtDevicePath;
  EFI_DEVICE_PATH_PROTOCOL*             DefaultFdtDevicePath;
  UINTN                                 FdtDevicePathSize;
  UINTN                                 CmdLineSize;
  UINTN                                 InitrdSize;
  EFI_DEVICE_PATH*                      Initrd;
  UINT16                                LoadOptionIndexSize;

  if (IS_ARM_BDS_BOOTENTRY (BootOption)) {
    Status = EFI_UNSUPPORTED;
    OptionalData = BootOption->OptionalData;
    LoaderType = ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);

    if (LoaderType == BDS_LOADER_EFI_APPLICATION) {
      if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) {
        // Need to connect every drivers to ensure no dependencies are missing for the application
        BdsConnectAllDrivers ();
      }

      Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, 0, NULL);
    } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) {
      LinuxArguments = &(OptionalData->Arguments.LinuxArguments);
      CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);
      InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);

      if (InitrdSize > 0) {
        Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize));
      } else {
        Initrd = NULL;
      }

      Status = BdsBootLinuxAtag (BootOption->FilePathList,
                                 Initrd, // Initrd
                                 (CHAR8*)(LinuxArguments + 1)); // CmdLine
    } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) {
      LinuxArguments = &(OptionalData->Arguments.LinuxArguments);
      CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);
      InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);

      if (InitrdSize > 0) {
        Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize));
      } else {
        Initrd = NULL;
      }

      // Get the default FDT device path
      Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
      ASSERT_EFI_ERROR(Status);
      DefaultFdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath));

      // Get the FDT device path
      FdtDevicePathSize = GetDevicePathSize (DefaultFdtDevicePath);
      Status = GetEnvironmentVariable ((CHAR16 *)L"Fdt", &gArmGlobalVariableGuid,
                 DefaultFdtDevicePath, &FdtDevicePathSize, (VOID **)&FdtDevicePath);
      ASSERT_EFI_ERROR(Status);

      Status = BdsBootLinuxFdt (BootOption->FilePathList,
                                Initrd, // Initrd
                                (CHAR8*)(LinuxArguments + 1),
                                FdtDevicePath);

      FreePool (DefaultFdtDevicePath);
      FreePool (FdtDevicePath);
    }
  } else {
    // Connect all the drivers if the EFI Application is not a EFI OS Loader
    if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) {
      BdsConnectAllDrivers ();
    }

    // Set BootCurrent variable
    LoadOptionIndexSize = sizeof(UINT16);
    gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid,
              EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
              LoadOptionIndexSize, &(BootOption->LoadOptionIndex));

    Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, BootOption->OptionalDataSize, BootOption->OptionalData);

    // Clear BootCurrent variable
    LoadOptionIndexSize = sizeof(UINT16);
    gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid,
              EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
              0, NULL);
  }

  return Status;
}
コード例 #3
0
ファイル: BootMenu.c プロジェクト: FishYu1222/edk2
/**
  Worker function that displays the list of boot options that is passed in.

  The function loops over the entries of the list of boot options that is passed
  in. For each entry, the boot option description is displayed on a single line
  along with the position of the option in the list. In debug mode, the UEFI
  device path and the arguments of the boot option are displayed as well in
  subsequent lines.

  @param[in]  BootOptionsList  List of the boot options

**/
STATIC
VOID
DisplayBootOptions (
  IN  LIST_ENTRY*   BootOptionsList
  )
{
  EFI_STATUS        Status;
  UINTN             BootOptionCount;
  LIST_ENTRY       *Entry;
  BDS_LOAD_OPTION  *BdsLoadOption;
  BOOLEAN           IsUnicode;

  BootOptionCount = 0 ;
  for (Entry = GetFirstNode (BootOptionsList);
       !IsNull (BootOptionsList, Entry);
       Entry = GetNextNode (BootOptionsList, Entry)
      ) {

    BdsLoadOption = LOAD_OPTION_FROM_LINK (Entry);
    Print (L"[%d] %s\n", ++BootOptionCount, BdsLoadOption->Description);

    DEBUG_CODE_BEGIN ();
      CHAR16*                           DevicePathTxt;
      EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
      ARM_BDS_LOADER_TYPE               LoaderType;
      ARM_BDS_LOADER_OPTIONAL_DATA*     OptionalData;

      Status = gBS->LocateProtocol (
                     &gEfiDevicePathToTextProtocolGuid,
                     NULL,
                     (VOID **)&DevicePathToTextProtocol
                     );
      ASSERT_EFI_ERROR (Status);
      DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (
                                                  BdsLoadOption->FilePathList,
                                                  TRUE,
                                                  TRUE
                                                  );
      Print (L"\t- %s\n", DevicePathTxt);

      OptionalData = BdsLoadOption->OptionalData;
      if (IS_ARM_BDS_BOOTENTRY (BdsLoadOption)) {
        LoaderType = (ARM_BDS_LOADER_TYPE)ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);
        if ((LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) ||
            (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT )   ) {
          Print (L"\t- Arguments: %a\n", &OptionalData->Arguments.LinuxArguments + 1);
        }
      } else if (OptionalData != NULL) {
        if (IsPrintableString (OptionalData, &IsUnicode)) {
          if (IsUnicode) {
            Print (L"\t- Arguments: %s\n", OptionalData);
          } else {
            AsciiPrint ("\t- Arguments: %a\n", OptionalData);
          }
        }
      }

      FreePool (DevicePathTxt);
    DEBUG_CODE_END ();
  }
}
コード例 #4
0
ファイル: BootOption.c プロジェクト: FishYu1222/edk2
EFI_STATUS
BootOptionStart (
  IN BDS_LOAD_OPTION *BootOption
  )
{
  EFI_STATUS                            Status;
  UINT32                                LoaderType;
  ARM_BDS_LOADER_OPTIONAL_DATA*         OptionalData;
  ARM_BDS_LINUX_ARGUMENTS*              LinuxArguments;
  UINTN                                 CmdLineSize;
  UINTN                                 InitrdSize;
  EFI_DEVICE_PATH*                      Initrd;
  UINT16                                LoadOptionIndexSize;

  if (IS_ARM_BDS_BOOTENTRY (BootOption)) {
    Status = EFI_UNSUPPORTED;
    OptionalData = BootOption->OptionalData;
    LoaderType = ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);

    if (LoaderType == BDS_LOADER_EFI_APPLICATION) {
      if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) {
        // Need to connect every drivers to ensure no dependencies are missing for the application
        BdsConnectAllDrivers ();
      }

      Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, 0, NULL);
    } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) {
      LinuxArguments = &(OptionalData->Arguments.LinuxArguments);
      CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);
      InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);

      if (InitrdSize > 0) {
        Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize));
      } else {
        Initrd = NULL;
      }

      Status = BdsBootLinuxAtag (BootOption->FilePathList,
                                 Initrd, // Initrd
                                 (CHAR8*)(LinuxArguments + 1)); // CmdLine
    } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) {
      LinuxArguments = &(OptionalData->Arguments.LinuxArguments);
      CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);
      InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize);

      if (InitrdSize > 0) {
        Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize));
      } else {
        Initrd = NULL;
      }
      Status = BdsBootLinuxFdt (
                 BootOption->FilePathList,
                 Initrd,
                 (CHAR8*)(LinuxArguments + 1)
                 );
    }
  } else {
    // Connect all the drivers if the EFI Application is not a EFI OS Loader
    if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) {
      BdsConnectAllDrivers ();
    }

    // Set BootCurrent variable
    LoadOptionIndexSize = sizeof(UINT16);
    gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid,
              EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
              LoadOptionIndexSize, &(BootOption->LoadOptionIndex));

    Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, BootOption->OptionalDataSize, BootOption->OptionalData);

    // Clear BootCurrent variable
    LoadOptionIndexSize = sizeof(UINT16);
    gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid,
              EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
              0, NULL);
  }

  return Status;
}