Пример #1
0
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;
}
Пример #2
0
EFI_STATUS
BootAndroidBootImg (
  IN UINTN    BufferSize,
  IN VOID    *Buffer
  )
{
  EFI_STATUS                          Status;
  CHAR8                               KernelArgs[BOOTIMG_KERNEL_ARGS_SIZE];
  VOID                               *Kernel;
  UINTN                               KernelSize;
  VOID                               *Ramdisk;
  UINTN                               RamdiskSize;
  MEMORY_DEVICE_PATH                  KernelDevicePath;
  MEMORY_DEVICE_PATH*                 RamdiskDevicePath;

  Status = ParseAndroidBootImg (
            Buffer,
            &Kernel,
            &KernelSize,
            &Ramdisk,
            &RamdiskSize,
            KernelArgs
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  KernelDevicePath = MemoryDevicePathTemplate;

  // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order to
  // appease GCC.
  KernelDevicePath.Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel;
  KernelDevicePath.Node1.EndingAddress   = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel + KernelSize;

  RamdiskDevicePath = NULL;
  if (RamdiskSize != 0) {
    RamdiskDevicePath = (MEMORY_DEVICE_PATH*)DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*) &MemoryDevicePathTemplate);

    RamdiskDevicePath->Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Ramdisk;
    RamdiskDevicePath->Node1.EndingAddress   = ((EFI_PHYSICAL_ADDRESS)(UINTN) Ramdisk) + RamdiskSize;
  }

  Status = BdsBootLinuxFdt (
              (EFI_DEVICE_PATH_PROTOCOL *) &KernelDevicePath,
              (EFI_DEVICE_PATH_PROTOCOL *) RamdiskDevicePath,
              KernelArgs
              );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Couldn't Boot Linux: %d\n", Status));
    return EFI_DEVICE_ERROR;
  }

  if (RamdiskDevicePath) {
    FreePool (RamdiskDevicePath);
  }

  // If we got here we do a confused face because BootLinuxFdt returned,
  // reporting success.
  DEBUG ((EFI_D_ERROR, "WARNING: BdsBootLinuxFdt returned EFI_SUCCESS.\n"));
  return EFI_SUCCESS;
}
Пример #3
0
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;
}