3 * Copyright (c) 2011 - 2015, ARM Limited. All rights reserved.
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "BdsInternal.h"
17 // This GUID is defined in the INGF file of ArmPkg/Application/LinuxLoader
18 CONST EFI_GUID mLinuxLoaderAppGuid
= { 0x701f54f2, 0x0d70, 0x4b89, { 0xbc, 0x0a, 0xd9, 0xca, 0x25, 0x37, 0x90, 0x59 }};
20 // Device path of the EFI Linux Loader in the Firmware Volume
21 EFI_DEVICE_PATH
* mLinuxLoaderDevicePath
= NULL
;
25 HasFilePathEfiExtension (
29 return (StrCmp (FilePath
+ (StrSize (FilePath
) / sizeof (CHAR16
)) - 5, L
".EFI") == 0) ||
30 (StrCmp (FilePath
+ (StrSize (FilePath
) / sizeof (CHAR16
)) - 5, L
".efi") == 0);
34 * This function check if the DevicePath defines an EFI binary
36 * This function is used when the BDS support Linux loader to
37 * detect if the binary is an EFI application or potentially a
42 IN EFI_DEVICE_PATH
* DevicePath
,
43 OUT BOOLEAN
*EfiBinary
48 EFI_DEVICE_PATH
* PrevDevicePathNode
;
49 EFI_DEVICE_PATH
* DevicePathNode
;
50 EFI_PHYSICAL_ADDRESS Image
;
52 EFI_IMAGE_DOS_HEADER
* DosHeader
;
53 UINTN PeCoffHeaderOffset
;
54 EFI_IMAGE_NT_HEADERS32
* NtHeader
;
56 ASSERT (EfiBinary
!= NULL
);
59 // Check if the last node of the device path is a FilePath node
61 PrevDevicePathNode
= NULL
;
62 DevicePathNode
= DevicePath
;
63 while ((DevicePathNode
!= NULL
) && !IsDevicePathEnd (DevicePathNode
)) {
64 PrevDevicePathNode
= DevicePathNode
;
65 DevicePathNode
= NextDevicePathNode (DevicePathNode
);
68 if ((PrevDevicePathNode
!= NULL
) &&
69 (PrevDevicePathNode
->Type
== MEDIA_DEVICE_PATH
) &&
70 (PrevDevicePathNode
->SubType
== MEDIA_FILEPATH_DP
))
72 FileName
= ((FILEPATH_DEVICE_PATH
*)PrevDevicePathNode
)->PathName
;
77 if (FileName
== NULL
) {
78 Print (L
"Is an EFI Application? ");
79 Status
= GetHIInputBoolean (EfiBinary
);
80 if (EFI_ERROR (Status
)) {
83 } else if (HasFilePathEfiExtension (FileName
)) {
86 // Check if the file exist
87 Status
= BdsLoadImage (DevicePath
, AllocateAnyPages
, &Image
, &FileSize
);
88 if (!EFI_ERROR (Status
)) {
90 DosHeader
= (EFI_IMAGE_DOS_HEADER
*)(UINTN
) Image
;
91 if (DosHeader
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
93 // DOS image header is present,
94 // so read the PE header after the DOS image header.
96 PeCoffHeaderOffset
= DosHeader
->e_lfanew
;
98 PeCoffHeaderOffset
= 0;
102 // Check PE/COFF image.
104 NtHeader
= (EFI_IMAGE_NT_HEADERS32
*)(UINTN
) (Image
+ PeCoffHeaderOffset
);
105 if (NtHeader
->Signature
!= EFI_IMAGE_NT_SIGNATURE
) {
112 gBS
->FreePages (Image
, EFI_SIZE_TO_PAGES (FileSize
));
114 // If we did not manage to open it then ask for the type
115 Print (L
"Is an EFI Application? ");
116 Status
= GetHIInputBoolean (EfiBinary
);
117 if (EFI_ERROR (Status
)) {