Пример #1
0
EFI_STATUS
BootDeviceGetType (
  IN  EFI_DEVICE_PATH* DevicePath,
  OUT ARM_BDS_LOADER_TYPE *BootType,
  OUT UINT32 *Attributes
  )
{
  EFI_STATUS              Status;
  BOOLEAN                 IsEfiApp;
  BOOLEAN                 IsBootLoader;
  BOOLEAN                 HasFDTSupport;
  CHAR16*                 FileName;
  EFI_DEVICE_PATH*        PrevDevicePathNode;
  EFI_DEVICE_PATH*        DevicePathNode;
  EFI_PHYSICAL_ADDRESS    Image;
  UINTN                   FileSize;
  EFI_IMAGE_DOS_HEADER*   DosHeader;
  UINTN                   PeCoffHeaderOffset;
  EFI_IMAGE_NT_HEADERS32* NtHeader;

  //
  // Check if the last node of the device path is a FilePath node
  //
  PrevDevicePathNode = NULL;
  DevicePathNode = DevicePath;
  while ((DevicePathNode != NULL) && !IsDevicePathEnd (DevicePathNode)) {
    PrevDevicePathNode = DevicePathNode;
    DevicePathNode = NextDevicePathNode (DevicePathNode);
  }

  if ((PrevDevicePathNode != NULL) &&
      (PrevDevicePathNode->Type == MEDIA_DEVICE_PATH) &&
      (PrevDevicePathNode->SubType == MEDIA_FILEPATH_DP))
  {
    FileName = ((FILEPATH_DEVICE_PATH*)PrevDevicePathNode)->PathName;
  } else {
    FileName = NULL;
  }

  if (FileName == NULL) {
    Print(L"Is an EFI Application? ");
    Status = GetHIInputBoolean (&IsEfiApp);
    if (EFI_ERROR(Status)) {
      return EFI_ABORTED;
    }
  } else if (HasFilePathEfiExtension(FileName)) {
    IsEfiApp = TRUE;
  } else {
    // Check if the file exist
    Status = BdsLoadImage (DevicePath, AllocateAnyPages, &Image, &FileSize);
    if (!EFI_ERROR (Status)) {

      DosHeader = (EFI_IMAGE_DOS_HEADER *)(UINTN) Image;
      if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
        //
        // DOS image header is present,
        // so read the PE header after the DOS image header.
        //
        PeCoffHeaderOffset = DosHeader->e_lfanew;
      } else {
        PeCoffHeaderOffset = 0;
      }

      //
      // Check PE/COFF image.
      //
      NtHeader = (EFI_IMAGE_NT_HEADERS32 *)(UINTN) (Image + PeCoffHeaderOffset);
      if (NtHeader->Signature != EFI_IMAGE_NT_SIGNATURE) {
        IsEfiApp = FALSE;
      } else {
        IsEfiApp = TRUE;
      }

      // Free memory
      gBS->FreePages (Image, EFI_SIZE_TO_PAGES(FileSize));
    } else {
      // If we did not manage to open it then ask for the type
      Print(L"Is an EFI Application? ");
      Status = GetHIInputBoolean (&IsEfiApp);
      if (EFI_ERROR(Status)) {
        return EFI_ABORTED;
      }
    }
  }

  if (IsEfiApp) {
    Print(L"Is your application an OS loader? ");
    Status = GetHIInputBoolean (&IsBootLoader);
    if (EFI_ERROR(Status)) {
      return EFI_ABORTED;
    }
    if (!IsBootLoader) {
      *Attributes |= LOAD_OPTION_CATEGORY_APP;
    }
    *BootType = BDS_LOADER_EFI_APPLICATION;
  } else {
    Print(L"Has FDT support? ");
    Status = GetHIInputBoolean (&HasFDTSupport);
    if (EFI_ERROR(Status)) {
      return EFI_ABORTED;
    }
    if (HasFDTSupport) {
      *BootType = BDS_LOADER_KERNEL_LINUX_FDT;
    } else {
      *BootType = BDS_LOADER_KERNEL_LINUX_ATAG;
    }
  }

  return EFI_SUCCESS;
}
Пример #2
0
/**
 * This function check if the DevicePath defines an EFI binary
 *
 * This function is used when the BDS support Linux loader to
 * detect if the binary is an EFI application or potentially a
 * Linux kernel.
 */
EFI_STATUS
IsEfiBinary (
  IN  EFI_DEVICE_PATH* DevicePath,
  OUT BOOLEAN          *EfiBinary
  )
{
  EFI_STATUS              Status;
  CHAR16*                 FileName;
  EFI_DEVICE_PATH*        PrevDevicePathNode;
  EFI_DEVICE_PATH*        DevicePathNode;
  EFI_PHYSICAL_ADDRESS    Image;
  UINTN                   FileSize;
  EFI_IMAGE_DOS_HEADER*   DosHeader;
  UINTN                   PeCoffHeaderOffset;
  EFI_IMAGE_NT_HEADERS32* NtHeader;

  ASSERT (EfiBinary != NULL);

  //
  // Check if the last node of the device path is a FilePath node
  //
  PrevDevicePathNode = NULL;
  DevicePathNode = DevicePath;
  while ((DevicePathNode != NULL) && !IsDevicePathEnd (DevicePathNode)) {
    PrevDevicePathNode = DevicePathNode;
    DevicePathNode     = NextDevicePathNode (DevicePathNode);
  }

  if ((PrevDevicePathNode != NULL) &&
      (PrevDevicePathNode->Type == MEDIA_DEVICE_PATH) &&
      (PrevDevicePathNode->SubType == MEDIA_FILEPATH_DP))
  {
    FileName = ((FILEPATH_DEVICE_PATH*)PrevDevicePathNode)->PathName;
  } else {
    FileName = NULL;
  }

  if (FileName == NULL) {
    Print (L"Is an EFI Application? ");
    Status = GetHIInputBoolean (EfiBinary);
    if (EFI_ERROR (Status)) {
      return EFI_ABORTED;
    }
  } else if (HasFilePathEfiExtension (FileName)) {
    *EfiBinary = TRUE;
  } else {
    // Check if the file exist
    Status = BdsLoadImage (DevicePath, AllocateAnyPages, &Image, &FileSize);
    if (!EFI_ERROR (Status)) {

      DosHeader = (EFI_IMAGE_DOS_HEADER *)(UINTN) Image;
      if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
        //
        // DOS image header is present,
        // so read the PE header after the DOS image header.
        //
        PeCoffHeaderOffset = DosHeader->e_lfanew;
      } else {
        PeCoffHeaderOffset = 0;
      }

      //
      // Check PE/COFF image.
      //
      NtHeader = (EFI_IMAGE_NT_HEADERS32 *)(UINTN) (Image + PeCoffHeaderOffset);
      if (NtHeader->Signature != EFI_IMAGE_NT_SIGNATURE) {
        *EfiBinary = FALSE;
      } else {
        *EfiBinary = TRUE;
      }

      // Free memory
      gBS->FreePages (Image, EFI_SIZE_TO_PAGES (FileSize));
    } else {
      // If we did not manage to open it then ask for the type
      Print (L"Is an EFI Application? ");
      Status = GetHIInputBoolean (EfiBinary);
      if (EFI_ERROR (Status)) {
        return EFI_ABORTED;
      }
    }
  }

  return EFI_SUCCESS;
}