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; }
/** * 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; }