Change-Id: I34777219b14393759f57dc660bd386da0542376a
---
ArmPkg/Include/Library/BdsLib.h | 52 ++++---
ArmPkg/Library/BdsLib/BdsAppLoader.c | 283 ++++++++++++++++++++++++-----------
ArmPlatformPkg/Bds/Bds.inf | 3 +
ArmPlatformPkg/Bds/BootMenu.c | 24 ++-
4 files changed, 250 insertions(+), 112 deletions(-)
diff --git a/ArmPkg/Include/Library/BdsLib.h b/ArmPkg/Include/Library/BdsLib.h
index c6416db..3d9e195 100644
--- a/ArmPkg/Include/Library/BdsLib.h
+++ b/ArmPkg/Include/Library/BdsLib.h
@@ -193,24 +193,6 @@ BdsStartEfiApplication (
IN VOID* LoadOptions
);
-/**
- Start an EFI Application from any Firmware Volume
-
- @param EfiApp EFI Application Name
-
- @retval EFI_SUCCESS All drivers have been connected
- @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
- @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store
the matching results.
-
-**/
-EFI_STATUS
-BdsLoadApplication (
- IN EFI_HANDLE ParentImageHandle,
- IN CHAR16* EfiApp,
- IN UINTN LoadOptionsSize,
- IN VOID* LoadOptions
- );
-
EFI_STATUS
BdsLoadImage (
IN EFI_DEVICE_PATH *DevicePath,
@@ -227,4 +209,38 @@ ShutdownUefiBootServices (
VOID
);
+/**
+ Locate an EFI application in a the Firmware Volumes by its name
+
+ @param EfiAppGuid Guid of the EFI Application into the Firmware
Volume
+ @param DevicePath EFI Device Path of the EFI application
+
+ @return EFI_SUCCESS The function completed successfully.
+ @return EFI_NOT_FOUND The protocol could not be located.
+ @return EFI_OUT_OF_RESOURCES There are not enough resources to find the
protocol.
+
+**/
+EFI_STATUS
+LocateEfiApplicationInFvByName (
+ IN CONST CHAR16* EfiAppName,
+ OUT EFI_DEVICE_PATH **DevicePath
+ );
+
+/**
+ Locate an EFI application in a the Firmware Volumes by its GUID
+
+ @param EfiAppGuid Guid of the EFI Application into the Firmware
Volume
+ @param DevicePath EFI Device Path of the EFI application
+
+ @return EFI_SUCCESS The function completed successfully.
+ @return EFI_NOT_FOUND The protocol could not be located.
+ @return EFI_OUT_OF_RESOURCES There are not enough resources to find the
protocol.
+
+**/
+EFI_STATUS
+LocateEfiApplicationInFvByGuid (
+ IN CONST EFI_GUID *EfiAppGuid,
+ OUT EFI_DEVICE_PATH **DevicePath
+ );
+
#endif
diff --git a/ArmPkg/Library/BdsLib/BdsAppLoader.c
b/ArmPkg/Library/BdsLib/BdsAppLoader.c
index 2b88bf1..1f208f8 100644
--- a/ArmPkg/Library/BdsLib/BdsAppLoader.c
+++ b/ArmPkg/Library/BdsLib/BdsAppLoader.c
@@ -1,6 +1,6 @@
/** @file
*
-* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+* Copyright (c) 2011-2015, 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
@@ -14,18 +14,23 @@
#include "BdsInternal.h"
-//#include <Library/DxeServicesLib.h>
+/**
+ Locate an EFI application in a the Firmware Volumes by its Name
+
+ @param EfiAppGuid Guid of the EFI Application into the Firmware
Volume
+ @param DevicePath EFI Device Path of the EFI application
+
+ @return EFI_SUCCESS The function completed successfully.
+ @return EFI_NOT_FOUND The protocol could not be located.
+ @return EFI_OUT_OF_RESOURCES There are not enough resources to find the
protocol.
-STATIC
+**/
EFI_STATUS
-BdsLoadFileFromFirmwareVolume (
- IN EFI_HANDLE FvHandle,
- IN CHAR16 *FilePath,
- IN EFI_FV_FILETYPE FileTypeFilter,
- OUT EFI_DEVICE_PATH **EfiAppDevicePath
+LocateEfiApplicationInFvByName (
+ IN CONST CHAR16* EfiAppName,
+ OUT EFI_DEVICE_PATH **DevicePath
)
{
- EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
VOID *Key;
EFI_STATUS Status, FileStatus;
EFI_GUID NameGuid;
@@ -37,108 +42,212 @@ BdsLoadFileFromFirmwareVolume (
UINT32 Authentication;
EFI_DEVICE_PATH *FvDevicePath;
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileDevicePath;
+ EFI_HANDLE *HandleBuffer;
+ UINTN NumberOfHandles;
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
- Status = gBS->HandleProtocol (FvHandle,&gEfiFirmwareVolume2ProtocolGuid,
(VOID **)&FvProtocol);
- if (EFI_ERROR(Status)) {
- return Status;
- }
+ ASSERT (DevicePath != NULL);
// Length of FilePath
- UiStringLen = StrLen (FilePath);
-
- // Allocate Key
- Key = AllocatePool (FvProtocol->KeySize);
- ASSERT (Key != NULL);
- ZeroMem (Key, FvProtocol->KeySize);
+ UiStringLen = StrLen (EfiAppName);
+
+ // Locate all the Firmware Volume protocols.
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
- do {
- // Search in all files
- FileType = FileTypeFilter;
+ *DevicePath = NULL;
+
+ // Looking for FV with ACPI storage file
+ for (Index = 0; Index < NumberOfHandles; Index++) {
+ //
+ // Get the protocol on this handle
+ // This should not fail because of LocateHandleBuffer
+ //
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID**) &FvInstance
+ );
+ if (EFI_ERROR (Status)) {
+ goto FREE_HANDLE_BUFFER;
+ }
- Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid,
&Attributes, &Size);
- if (!EFI_ERROR (Status)) {
- UiSection = NULL;
- FileStatus = FvProtocol->ReadSection (
- FvProtocol,
- &NameGuid,
- EFI_SECTION_USER_INTERFACE,
- 0,
- (VOID **)&UiSection,
- &Size,
- &Authentication
- );
- if (!EFI_ERROR (FileStatus)) {
- if (StrnCmp (FilePath, UiSection, UiStringLen) == 0) {
- //
- // We found a UiString match.
- //
- Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid,
(VOID **)&FvDevicePath);
-
- // Generate the Device Path for the file
- //DevicePath = DuplicateDevicePath(FvDevicePath);
- EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);
- *EfiAppDevicePath = AppendDevicePathNode (FvDevicePath,
(EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);
-
- FreePool (Key);
+ // Allocate Key
+ Key = AllocatePool (FvInstance->KeySize);
+ ASSERT (Key != NULL);
+ ZeroMem (Key, FvInstance->KeySize);
+
+ do {
+ // Search in all files
+ FileType = EFI_FV_FILETYPE_ALL;
+
+ Status = FvInstance->GetNextFile (FvInstance, Key, &FileType, &NameGuid,
&Attributes, &Size);
+ if (!EFI_ERROR (Status)) {
+ UiSection = NULL;
+ FileStatus = FvInstance->ReadSection (
+ FvInstance,
+ &NameGuid,
+ EFI_SECTION_USER_INTERFACE,
+ 0,
+ (VOID **)&UiSection,
+ &Size,
+ &Authentication
+ );
+ if (!EFI_ERROR (FileStatus)) {
+ if (StrnCmp (EfiAppName, UiSection, UiStringLen) == 0) {
+ //
+ // We found a UiString match.
+ //
+ Status = gBS->HandleProtocol (HandleBuffer[Index],
&gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
+
+ // Generate the Device Path for the file
+ EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);
+ *DevicePath = AppendDevicePathNode (FvDevicePath,
(EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);
+ ASSERT (*DevicePath != NULL);
+
+ FreePool (Key);
+ FreePool (UiSection);
+ FreePool (HandleBuffer);
+ return FileStatus;
+ }
FreePool (UiSection);
- return FileStatus;
}
- FreePool (UiSection);
}
- }
- } while (!EFI_ERROR (Status));
+ } while (!EFI_ERROR (Status));
- FreePool(Key);
- return Status;
+ FreePool (Key);
+ }
+
+FREE_HANDLE_BUFFER:
+ FreePool (HandleBuffer);
+ return EFI_NOT_FOUND;
}
/**
- Start an EFI Application from any Firmware Volume
+ Locate an EFI application in a the Firmware Volumes by its GUID
- @param EfiApp EFI Application Name
+ @param EfiAppGuid Guid of the EFI Application into the Firmware
Volume
+ @param DevicePath EFI Device Path of the EFI application
- @retval EFI_SUCCESS All drivers have been connected
- @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
- @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store
the matching results.
+ @return EFI_SUCCESS The function completed successfully.
+ @return EFI_NOT_FOUND The protocol could not be located.
+ @return EFI_OUT_OF_RESOURCES There are not enough resources to find the
protocol.
**/
EFI_STATUS
-BdsLoadApplication (
- IN EFI_HANDLE ParentImageHandle,
- IN CHAR16* EfiApp,
- IN UINTN LoadOptionsSize,
- IN VOID* LoadOptions
+LocateEfiApplicationInFvByGuid (
+ IN CONST EFI_GUID *EfiAppGuid,
+ OUT EFI_DEVICE_PATH **DevicePath
)
{
- EFI_STATUS Status;
- UINTN NoHandles, HandleIndex;
- EFI_HANDLE *Handles;
- EFI_DEVICE_PATH *EfiAppDevicePath;
-
- // Need to connect every drivers to ensure no dependencies are missing for
the application
- Status = BdsConnectAllDrivers();
- if (EFI_ERROR(Status)) {
- DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH *FvDevicePath;
+ EFI_HANDLE *HandleBuffer;
+ UINTN NumberOfHandles;
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINT32 AuthenticationStatus;
+ EFI_FV_FILETYPE Type;
+ UINTN Size;
+ CHAR16 *UiSection;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileDevicePath;
+
+ ASSERT (DevicePath != NULL);
+
+ // Locate all the Firmware Volume protocols.
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
return Status;
}
- // Search the application in any Firmware Volume
- Status = gBS->LocateHandleBuffer (ByProtocol,
&gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Handles);
- if (EFI_ERROR (Status) || (NoHandles == 0)) {
- DEBUG ((EFI_D_ERROR, "FAIL to find Firmware Volume\n"));
- return Status;
- }
+ *DevicePath = NULL;
+
+ // Looking for FV with ACPI storage file
+ for (Index = 0; Index < NumberOfHandles; Index++) {
+ //
+ // Get the protocol on this handle
+ // This should not fail because of LocateHandleBuffer
+ //
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID**) &FvInstance
+ );
+ if (EFI_ERROR (Status)) {
+ goto FREE_HANDLE_BUFFER;
+ }
- // Search in all Firmware Volume for the EFI Application
- for (HandleIndex = 0; HandleIndex < NoHandles; HandleIndex++) {
- EfiAppDevicePath = NULL;
- Status = BdsLoadFileFromFirmwareVolume (Handles[HandleIndex], EfiApp,
EFI_FV_FILETYPE_APPLICATION, &EfiAppDevicePath);
- if (!EFI_ERROR (Status)) {
- // Start the application
- Status = BdsStartEfiApplication (ParentImageHandle, EfiAppDevicePath,
LoadOptionsSize, LoadOptions);
- return Status;
+ Status = FvInstance->ReadFile (
+ FvInstance,
+ EfiAppGuid,
+ NULL,
+ &Size,
+ &Type,
+ &Attributes,
+ &AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Skip if no EFI application file in the FV
+ //
+ continue;
+ } else {
+ UiSection = NULL;
+ Status = FvInstance->ReadSection (
+ FvInstance,
+ EfiAppGuid,
+ EFI_SECTION_USER_INTERFACE,
+ 0,
+ (VOID **)&UiSection,
+ &Size,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Create the EFI Device Path for the application using the Filename
of the application
+ //
+ *DevicePath = FileDevicePath (HandleBuffer[Index], UiSection);
+ } else {
+ Status = gBS->HandleProtocol (HandleBuffer[Index],
&gEfiDevicePathProtocolGuid, (VOID**)&FvDevicePath);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Create the EFI Device Path for the application using the EFI GUID
of the application
+ //
+ EfiInitializeFwVolDevicepathNode (&FvFileDevicePath, EfiAppGuid);
+
+ *DevicePath = AppendDevicePathNode (FvDevicePath,
(EFI_DEVICE_PATH_PROTOCOL *)&FvFileDevicePath);
+ ASSERT (*DevicePath != NULL);
+ }
+ break;
}
}
- return Status;
+FREE_HANDLE_BUFFER:
+ //
+ // Free any allocated buffers
+ //
+ FreePool (HandleBuffer);
+
+ if (*DevicePath == NULL) {
+ return EFI_NOT_FOUND;
+ } else {
+ return EFI_SUCCESS;
+ }
}
diff --git a/ArmPlatformPkg/Bds/Bds.inf b/ArmPlatformPkg/Bds/Bds.inf
index f4c0f1c..76a45e0 100644
--- a/ArmPlatformPkg/Bds/Bds.inf
+++ b/ArmPlatformPkg/Bds/Bds.inf
@@ -37,6 +37,7 @@
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
[LibraryClasses]
BdsLib
@@ -79,5 +80,7 @@
gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths
gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile
+
[Depex]
TRUE
diff --git a/ArmPlatformPkg/Bds/BootMenu.c b/ArmPlatformPkg/Bds/BootMenu.c
index d2dccbc..a304cc4 100644
--- a/ArmPlatformPkg/Bds/BootMenu.c
+++ b/ArmPlatformPkg/Bds/BootMenu.c
@@ -1069,17 +1069,27 @@ BootShell (
IN LIST_ENTRY *BootOptionsList
)
{
- EFI_STATUS Status;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH* EfiShellDevicePath;
- // Start EFI Shell
- Status = BdsLoadApplication (gImageHandle, L"Shell", 0, NULL);
+ // Find the EFI Shell
+ Status = LocateEfiApplicationInFvByName (L"Shell", &EfiShellDevicePath);
if (Status == EFI_NOT_FOUND) {
Print (L"Error: EFI Application not found.\n");
- } else if (EFI_ERROR(Status)) {
- Print (L"Error: Status Code: 0x%X\n",(UINT32)Status);
- }
+ return Status;
+ } else if (EFI_ERROR (Status)) {
+ Print (L"Error: Status Code: 0x%X\n", (UINT32)Status);
+ return Status;
+ } else {
+ // Need to connect every drivers to ensure no dependencies are missing for
the application
+ Status = BdsConnectAllDrivers ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));
+ return Status;
+ }
- return Status;
+ return BdsStartEfiApplication (gImageHandle, EfiShellDevicePath, 0, NULL);
+ }
}
struct BOOT_MAIN_ENTRY {
--
2.1.1
------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel