summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Salter <msalter@redhat.com>2014-05-08 15:09:27 +0000
committerLeif Lindholm <leif.lindholm@linaro.org>2014-05-09 21:27:21 +0100
commit74d4e8ec968848aee82fea05ca3b0287ef52d622 (patch)
tree5c5bfcfb8467deca5caf00fbb73922a7c9ac62ac
parent7447345a364e6aa5f5bd5219d25d28a2d6147bce (diff)
ArmPkg/BdsLib: Fix booting with partial paths
Boot entries created by efibootmgr may contain a partial device path to the EFI application to boot. These entries begin with a partition device path whereas entries created via ARM Boot Manager contain a full path to the EFI application. The ARM BDS code will fill in the missing parts of this partial device path as it does for removeable device paths. This allows the application to be loaded and started. However, the current code passes the original partial device path to gBS->LoadImage() and thus LoadImage is unable to find a DeviceHandle for the path. This means the application being booted cannot find the boot device from the Loaded Image Protocol structure. In the case of grub, this prevents the grub config file from being found. This patch fixes this by making sure the full path is propagated back to the caller of gBS->LoadImage() so that a proper DeviceHandle gets passed to the application being booted. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Mark Salter <msalter@redhat.com> Signed-off-by: Olivier Martin <olivier.martin@arm.com> Reviewed-By: Olivier Martin <olivier.martin@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15518 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--ArmPkg/Library/BdsLib/BdsFilePath.c78
1 files changed, 51 insertions, 27 deletions
diff --git a/ArmPkg/Library/BdsLib/BdsFilePath.c b/ArmPkg/Library/BdsLib/BdsFilePath.c
index 25f92725f..487bd7654 100644
--- a/ArmPkg/Library/BdsLib/BdsFilePath.c
+++ b/ArmPkg/Library/BdsLib/BdsFilePath.c
@@ -300,35 +300,24 @@ TryRemovableDevice (
return Status;
}
-/**
- Connect a Device Path and return the handle of the driver that support this DevicePath
-
- @param DevicePath Device Path of the File to connect
- @param Handle Handle of the driver that support this DevicePath
- @param RemainingDevicePath Remaining DevicePath nodes that do not match the driver DevicePath
-
- @retval EFI_SUCCESS A driver that matches the Device Path has been found
- @retval EFI_NOT_FOUND No handles match the search.
- @retval EFI_INVALID_PARAMETER DevicePath or Handle is NULL
-
-**/
+STATIC
EFI_STATUS
-BdsConnectDevicePath (
- IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,
- OUT EFI_HANDLE *Handle,
- OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath
+BdsConnectAndUpdateDevicePath (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ OUT EFI_HANDLE *Handle,
+ OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath
)
{
EFI_DEVICE_PATH* Remaining;
EFI_DEVICE_PATH* NewDevicePath;
EFI_STATUS Status;
- if ((DevicePath == NULL) || (Handle == NULL)) {
+ if ((DevicePath == NULL) || (*DevicePath == NULL) || (Handle == NULL)) {
return EFI_INVALID_PARAMETER;
}
do {
- Remaining = DevicePath;
+ Remaining = *DevicePath;
// The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns
// the handle to the device that is closest to DevicePath. On output, the device path pointer is modified
// to point to the remaining part of the device path
@@ -348,7 +337,7 @@ BdsConnectDevicePath (
if (!EFI_ERROR (Status)) {
// Now, we have got the whole Device Path connected, call again ConnectController to ensure all the supported Driver
// Binding Protocol are connected (such as DiskIo and SimpleFileSystem)
- Remaining = DevicePath;
+ Remaining = *DevicePath;
Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);
if (!EFI_ERROR (Status)) {
Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);
@@ -371,9 +360,11 @@ BdsConnectDevicePath (
//TODO: Should we just return success and leave the caller decide if it is the expected RemainingPath
Status = EFI_SUCCESS;
} else {
- Status = TryRemovableDevice (DevicePath, Handle, &NewDevicePath);
+ Status = TryRemovableDevice (*DevicePath, Handle, &NewDevicePath);
if (!EFI_ERROR (Status)) {
- return BdsConnectDevicePath (NewDevicePath, Handle, RemainingDevicePath);
+ Status = BdsConnectAndUpdateDevicePath (&NewDevicePath, Handle, RemainingDevicePath);
+ *DevicePath = NewDevicePath;
+ return Status;
}
}
@@ -384,6 +375,28 @@ BdsConnectDevicePath (
return Status;
}
+/**
+ Connect a Device Path and return the handle of the driver that support this DevicePath
+
+ @param DevicePath Device Path of the File to connect
+ @param Handle Handle of the driver that support this DevicePath
+ @param RemainingDevicePath Remaining DevicePath nodes that do not match the driver DevicePath
+
+ @retval EFI_SUCCESS A driver that matches the Device Path has been found
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_INVALID_PARAMETER DevicePath or Handle is NULL
+
+**/
+EFI_STATUS
+BdsConnectDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,
+ OUT EFI_HANDLE *Handle,
+ OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath
+ )
+{
+ return BdsConnectAndUpdateDevicePath (&DevicePath, Handle, RemainingDevicePath);
+}
+
BOOLEAN
BdsFileSystemSupport (
IN EFI_DEVICE_PATH *DevicePath,
@@ -866,8 +879,8 @@ BDS_FILE_LOADER FileLoaders[] = {
};
EFI_STATUS
-BdsLoadImage (
- IN EFI_DEVICE_PATH *DevicePath,
+BdsLoadImageAndUpdateDevicePath (
+ IN OUT EFI_DEVICE_PATH **DevicePath,
IN EFI_ALLOCATE_TYPE Type,
IN OUT EFI_PHYSICAL_ADDRESS* Image,
OUT UINTN *FileSize
@@ -878,15 +891,15 @@ BdsLoadImage (
EFI_DEVICE_PATH *RemainingDevicePath;
BDS_FILE_LOADER* FileLoader;
- Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath);
+ Status = BdsConnectAndUpdateDevicePath (DevicePath, &Handle, &RemainingDevicePath);
if (EFI_ERROR (Status)) {
return Status;
}
FileLoader = FileLoaders;
while (FileLoader->Support != NULL) {
- if (FileLoader->Support (DevicePath, Handle, RemainingDevicePath)) {
- return FileLoader->LoadImage (DevicePath, Handle, RemainingDevicePath, Type, Image, FileSize);
+ if (FileLoader->Support (*DevicePath, Handle, RemainingDevicePath)) {
+ return FileLoader->LoadImage (*DevicePath, Handle, RemainingDevicePath, Type, Image, FileSize);
}
FileLoader++;
}
@@ -894,6 +907,17 @@ BdsLoadImage (
return EFI_UNSUPPORTED;
}
+EFI_STATUS
+BdsLoadImage (
+ IN EFI_DEVICE_PATH *DevicePath,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN OUT EFI_PHYSICAL_ADDRESS* Image,
+ OUT UINTN *FileSize
+ )
+{
+ return BdsLoadImageAndUpdateDevicePath (&DevicePath, Type, Image, FileSize);
+}
+
/**
Start an EFI Application from a Device Path
@@ -920,7 +944,7 @@ BdsStartEfiApplication (
EFI_LOADED_IMAGE_PROTOCOL* LoadedImage;
// Find the nearest supported file loader
- Status = BdsLoadImage (DevicePath, AllocateAnyPages, &BinaryBuffer, &BinarySize);
+ Status = BdsLoadImageAndUpdateDevicePath (&DevicePath, AllocateAnyPages, &BinaryBuffer, &BinarySize);
if (EFI_ERROR (Status)) {
return Status;
}