summaryrefslogtreecommitdiffstats
path: root/ArmPlatformPkg/Bds
diff options
context:
space:
mode:
authorOlivier Martin <olivier.martin@arm.com>2014-04-11 10:57:47 +0000
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2014-04-11 10:57:47 +0000
commit55a9f75d149ea53d1c8b3da197ec344c2aedb848 (patch)
tree4f92f10febc30c135440ec262c666274da7faf75 /ArmPlatformPkg/Bds
parent06044819bb273fd0db56a988ed307cd70fa34358 (diff)
downloadedk2-55a9f75d149ea53d1c8b3da197ec344c2aedb848.tar.gz
edk2-55a9f75d149ea53d1c8b3da197ec344c2aedb848.tar.bz2
edk2-55a9f75d149ea53d1c8b3da197ec344c2aedb848.zip
ArmPlatformPkg/Bds: Added support to detect if the binary is a EFI image
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin <olivier.martin@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15453 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPlatformPkg/Bds')
-rw-r--r--ArmPlatformPkg/Bds/BdsInternal.h11
-rw-r--r--ArmPlatformPkg/Bds/BootMenu.c34
-rw-r--r--ArmPlatformPkg/Bds/BootOptionSupport.c174
3 files changed, 130 insertions, 89 deletions
diff --git a/ArmPlatformPkg/Bds/BdsInternal.h b/ArmPlatformPkg/Bds/BdsInternal.h
index 085a5a49ef..da7b8ca704 100644
--- a/ArmPlatformPkg/Bds/BdsInternal.h
+++ b/ArmPlatformPkg/Bds/BdsInternal.h
@@ -102,8 +102,8 @@ typedef struct _BDS_LOAD_OPTION_SUPPORT {
BDS_SUPPORTED_DEVICE_TYPE Type;
EFI_STATUS (*ListDevices)(IN OUT LIST_ENTRY* BdsLoadOptionList);
BOOLEAN (*IsSupported)(IN EFI_DEVICE_PATH *DevicePath);
- EFI_STATUS (*CreateDevicePathNode)(IN CHAR16* FileName, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes, OUT ARM_BDS_LOADER_TYPE *BootType, OUT UINT32 *Attributes);
- EFI_STATUS (*UpdateDevicePathNode)(IN EFI_DEVICE_PATH *OldDevicePath, IN CHAR16* FileName, OUT EFI_DEVICE_PATH_PROTOCOL** NewDevicePath, OUT ARM_BDS_LOADER_TYPE *BootType, OUT UINT32 *Attributes);
+ EFI_STATUS (*CreateDevicePathNode)(IN CHAR16* FileName, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes, OUT BOOLEAN *RequestBootType);
+ EFI_STATUS (*UpdateDevicePathNode)(IN EFI_DEVICE_PATH *OldDevicePath, IN CHAR16* FileName, OUT EFI_DEVICE_PATH_PROTOCOL** NewDevicePath, OUT BOOLEAN *RequestBootType);
} BDS_LOAD_OPTION_SUPPORT;
#define LOAD_OPTION_ENTRY_FROM_LINK(a) BASE_CR(a, BDS_LOAD_OPTION_ENTRY, Link)
@@ -241,6 +241,13 @@ BootOptionDelete (
);
EFI_STATUS
+BootDeviceGetType (
+ IN EFI_DEVICE_PATH* DevicePath,
+ OUT ARM_BDS_LOADER_TYPE *BootType,
+ OUT UINT32 *Attributes
+ );
+
+EFI_STATUS
BootMenuMain (
VOID
);
diff --git a/ArmPlatformPkg/Bds/BootMenu.c b/ArmPlatformPkg/Bds/BootMenu.c
index 9ca703842f..e00d06e394 100644
--- a/ArmPlatformPkg/Bds/BootMenu.c
+++ b/ArmPlatformPkg/Bds/BootMenu.c
@@ -134,6 +134,7 @@ BootMenuAddBootOption (
UINTN InitrdSize;
UINT8* OptionalData;
UINTN OptionalDataSize;
+ BOOLEAN RequestBootType;
Attributes = 0;
SupportedBootDevice = NULL;
@@ -146,7 +147,8 @@ BootMenuAddBootOption (
}
// Create the specific device path node
- Status = SupportedBootDevice->Support->CreateDevicePathNode (L"EFI Application or the kernel", &DevicePathNodes, &BootType, &Attributes);
+ RequestBootType = TRUE;
+ Status = SupportedBootDevice->Support->CreateDevicePathNode (L"EFI Application or the kernel", &DevicePathNodes, &RequestBootType);
if (EFI_ERROR(Status)) {
Status = EFI_ABORTED;
goto EXIT;
@@ -158,6 +160,16 @@ BootMenuAddBootOption (
goto EXIT;
}
+ if (RequestBootType) {
+ Status = BootDeviceGetType (DevicePath, &BootType, &Attributes);
+ if (EFI_ERROR(Status)) {
+ Status = EFI_ABORTED;
+ goto EXIT;
+ }
+ } else {
+ BootType = BDS_LOADER_EFI_APPLICATION;
+ }
+
if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {
Print(L"Add an initrd: ");
Status = GetHIInputBoolean (&InitrdSupport);
@@ -168,7 +180,7 @@ BootMenuAddBootOption (
if (InitrdSupport) {
// Create the specific device path node
- Status = SupportedBootDevice->Support->CreateDevicePathNode (L"initrd", &InitrdPathNodes, NULL, NULL);
+ Status = SupportedBootDevice->Support->CreateDevicePathNode (L"initrd", &InitrdPathNodes, NULL);
if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) { // EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd
Status = EFI_ABORTED;
goto EXIT;
@@ -390,6 +402,7 @@ BootMenuUpdateBootOption (
BOOLEAN InitrdSupport;
UINT8* OptionalData;
UINTN OptionalDataSize;
+ BOOLEAN RequestBootType;
Status = BootMenuSelectBootOption (BootOptionsList, UPDATE_BOOT_ENTRY, TRUE, &BootOptionEntry);
if (EFI_ERROR(Status)) {
@@ -404,12 +417,21 @@ BootMenuUpdateBootOption (
return EFI_UNSUPPORTED;
}
- Status = DeviceSupport->UpdateDevicePathNode (BootOption->FilePathList, L"EFI Application or the kernel", &DevicePath, NULL, NULL);
+ RequestBootType = TRUE;
+ Status = DeviceSupport->UpdateDevicePathNode (BootOption->FilePathList, L"EFI Application or the kernel", &DevicePath, &RequestBootType);
if (EFI_ERROR(Status)) {
Status = EFI_ABORTED;
goto EXIT;
}
+ if (RequestBootType) {
+ Status = BootDeviceGetType (DevicePath, &BootType, &BootOption->Attributes);
+ if (EFI_ERROR(Status)) {
+ Status = EFI_ABORTED;
+ goto EXIT;
+ }
+ }
+
LoaderOptionalData = BootOption->OptionalData;
BootType = (ARM_BDS_LOADER_TYPE)ReadUnaligned32 ((UINT32 *)(&LoaderOptionalData->Header.LoaderType));
@@ -433,7 +455,7 @@ BootMenuUpdateBootOption (
if (InitrdSupport) {
if (InitrdSize > 0) {
// Case we update the initrd device path
- Status = DeviceSupport->UpdateDevicePathNode ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize), L"initrd", &InitrdPath, NULL, NULL);
+ Status = DeviceSupport->UpdateDevicePathNode ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize), L"initrd", &InitrdPath, NULL);
if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {// EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd
Status = EFI_ABORTED;
goto EXIT;
@@ -442,7 +464,7 @@ BootMenuUpdateBootOption (
} else {
// Case we create the initrd device path
- Status = DeviceSupport->CreateDevicePathNode (L"initrd", &InitrdPathNodes, NULL, NULL);
+ Status = DeviceSupport->CreateDevicePathNode (L"initrd", &InitrdPathNodes, NULL);
if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) { // EFI_NOT_FOUND is returned on empty input string, but we can boot without an initrd
Status = EFI_ABORTED;
goto EXIT;
@@ -535,7 +557,7 @@ UpdateFdtPath (
}
// Create the specific device path node
- Status = SupportedBootDevice->Support->CreateDevicePathNode (L"FDT blob", &FdtDevicePathNodes, NULL, NULL);
+ Status = SupportedBootDevice->Support->CreateDevicePathNode (L"FDT blob", &FdtDevicePathNodes, NULL);
if (EFI_ERROR(Status)) {
Status = EFI_ABORTED;
goto EXIT;
diff --git a/ArmPlatformPkg/Bds/BootOptionSupport.c b/ArmPlatformPkg/Bds/BootOptionSupport.c
index 190169a304..dc70dc4a1e 100644
--- a/ArmPlatformPkg/Bds/BootOptionSupport.c
+++ b/ArmPlatformPkg/Bds/BootOptionSupport.c
@@ -1,6 +1,6 @@
/** @file
*
-* Copyright (c) 2011, ARM Limited. All rights reserved.
+* Copyright (c) 2011-2014, ARM Limited. All rights reserved.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
@@ -35,8 +35,7 @@ EFI_STATUS
BdsLoadOptionFileSystemCreateDevicePath (
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
);
EFI_STATUS
@@ -44,8 +43,7 @@ BdsLoadOptionFileSystemUpdateDevicePath (
IN EFI_DEVICE_PATH *OldDevicePath,
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
);
BOOLEAN
@@ -62,8 +60,7 @@ EFI_STATUS
BdsLoadOptionMemMapCreateDevicePath (
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
);
EFI_STATUS
@@ -71,8 +68,7 @@ BdsLoadOptionMemMapUpdateDevicePath (
IN EFI_DEVICE_PATH *OldDevicePath,
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
);
BOOLEAN
@@ -89,8 +85,7 @@ EFI_STATUS
BdsLoadOptionPxeCreateDevicePath (
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
);
EFI_STATUS
@@ -98,8 +93,7 @@ BdsLoadOptionPxeUpdateDevicePath (
IN EFI_DEVICE_PATH *OldDevicePath,
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
);
BOOLEAN
@@ -116,8 +110,7 @@ EFI_STATUS
BdsLoadOptionTftpCreateDevicePath (
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
);
EFI_STATUS
@@ -125,8 +118,7 @@ BdsLoadOptionTftpUpdateDevicePath (
IN EFI_DEVICE_PATH *OldDevicePath,
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
);
BOOLEAN
@@ -222,18 +214,44 @@ BootDeviceGetDeviceSupport (
return EFI_UNSUPPORTED;
}
-STATIC
EFI_STATUS
BootDeviceGetType (
- IN CHAR16* FileName,
+ IN EFI_DEVICE_PATH* DevicePath,
OUT ARM_BDS_LOADER_TYPE *BootType,
OUT UINT32 *Attributes
)
{
- EFI_STATUS Status;
- BOOLEAN IsEfiApp;
- BOOLEAN IsBootLoader;
- BOOLEAN HasFDTSupport;
+ 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? ");
@@ -244,7 +262,41 @@ BootDeviceGetType (
} else if (HasFilePathEfiExtension(FileName)) {
IsEfiApp = TRUE;
} else {
- IsEfiApp = FALSE;
+ // 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) {
@@ -333,8 +385,7 @@ EFI_STATUS
BdsLoadOptionFileSystemCreateDevicePath (
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
)
{
EFI_STATUS Status;
@@ -361,16 +412,7 @@ BdsLoadOptionFileSystemCreateDevicePath (
SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);
CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize);
SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize));
-
- if (BootType != NULL || Attributes != NULL) {
- Status = BootDeviceGetType (FilePathDevicePath->PathName, BootType, Attributes);
- }
-
- if (EFI_ERROR(Status)) {
- FreePool (FilePathDevicePath);
- } else {
- *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)FilePathDevicePath;
- }
+ *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)FilePathDevicePath;
return Status;
}
@@ -380,8 +422,7 @@ BdsLoadOptionFileSystemUpdateDevicePath (
IN EFI_DEVICE_PATH *OldDevicePath,
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
)
{
EFI_STATUS Status;
@@ -420,10 +461,6 @@ BdsLoadOptionFileSystemUpdateDevicePath (
*NewDevicePath = AppendDevicePathNode (DevicePath, (CONST EFI_DEVICE_PATH_PROTOCOL *)FilePathDevicePath);
FreePool(DevicePath);
- if (BootType != NULL || Attributes != NULL) {
- return BootDeviceGetType (FilePathDevicePath->PathName, BootType, Attributes);
- }
-
return EFI_SUCCESS;
}
@@ -535,8 +572,7 @@ EFI_STATUS
BdsLoadOptionMemMapCreateDevicePath (
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
)
{
EFI_STATUS Status;
@@ -567,16 +603,7 @@ BdsLoadOptionMemMapCreateDevicePath (
// Set a Device Path End Node after the Memory Map Device Path Node
SetDevicePathEndNode (MemMapDevicePath + 1);
-
- if (BootType != NULL || Attributes != NULL) {
- Status = BootDeviceGetType (NULL, BootType, Attributes);
- }
-
- if (EFI_ERROR(Status)) {
- FreePool (MemMapDevicePath);
- } else {
- *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)MemMapDevicePath;
- }
+ *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)MemMapDevicePath;
return Status;
}
@@ -586,8 +613,7 @@ BdsLoadOptionMemMapUpdateDevicePath (
IN EFI_DEVICE_PATH *OldDevicePath,
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
)
{
EFI_STATUS Status;
@@ -616,10 +642,6 @@ BdsLoadOptionMemMapUpdateDevicePath (
EndingDevicePath->StartingAddress = StrHexToUint64 (StrStartingAddress);
EndingDevicePath->EndingAddress = StrHexToUint64 (StrEndingAddress);
- if (BootType != NULL || Attributes != NULL) {
- Status = BootDeviceGetType (NULL, BootType, Attributes);
- }
-
if (EFI_ERROR(Status)) {
FreePool(DevicePath);
} else {
@@ -693,13 +715,15 @@ EFI_STATUS
BdsLoadOptionPxeCreateDevicePath (
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
)
{
*DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
SetDevicePathEndNode (*DevicePathNodes);
- *BootType = BDS_LOADER_EFI_APPLICATION;
+
+ if (RequestBootType) {
+ *RequestBootType = FALSE;
+ }
return EFI_SUCCESS;
}
@@ -708,12 +732,11 @@ BdsLoadOptionPxeUpdateDevicePath (
IN EFI_DEVICE_PATH *OldDevicePath,
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
)
{
ASSERT (0);
- return EFI_SUCCESS;
+ return EFI_UNSUPPORTED;
}
BOOLEAN
@@ -795,8 +818,7 @@ EFI_STATUS
BdsLoadOptionTftpCreateDevicePath (
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathNodes,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
)
{
EFI_STATUS Status;
@@ -862,16 +884,7 @@ BdsLoadOptionTftpCreateDevicePath (
// Set the End Device Path Node
SetDevicePathEndNode ((VOID*)((UINTN)FilePathDevicePath + SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize));
-
- if (BootType != NULL || Attributes != NULL) {
- Status = BootDeviceGetType (NULL, BootType, Attributes);
- }
-
- if (EFI_ERROR(Status)) {
- FreePool (IPv4DevicePathNode);
- } else {
- *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)IPv4DevicePathNode;
- }
+ *DevicePathNodes = (EFI_DEVICE_PATH_PROTOCOL*)IPv4DevicePathNode;
return Status;
}
@@ -881,12 +894,11 @@ BdsLoadOptionTftpUpdateDevicePath (
IN EFI_DEVICE_PATH *OldDevicePath,
IN CHAR16* FileName,
OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath,
- OUT ARM_BDS_LOADER_TYPE *BootType,
- OUT UINT32 *Attributes
+ OUT BOOLEAN *RequestBootType
)
{
ASSERT (0);
- return EFI_SUCCESS;
+ return EFI_UNSUPPORTED;
}
BOOLEAN