[U-Boot] [PATCH 4/4] efi_loader: use efi_devpath to get correct boot device-path

Rob Clark
2017-07-21T18:43:39Z

This way grub can properly match up the loaded_image device-path to a
partition device object, so it can locate it's grub.cfg.

Signed-off-by: Rob Clark <robdclark@gmail.com>
---
cmd/bootefi.c | 31 ++++++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 5030b7bd86..ea0d5dbc79 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -41,6 +41,11 @@ static struct efi_device_path_file_path bootefi_image_path[] = {
}
};

+/* if we have CONFIG_DM we construct a proper device-path from the
+ * boot device, otherwise fallback to using bootefi_device_path.
+ */
+static struct efi_device_path *real_bootefi_device_path;
+
static struct efi_device_path_file_path bootefi_device_path[] = {
{
.dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE,
@@ -58,13 +63,12 @@ static efi_status_t EFIAPI bootefi_open_dp(void *handle, efi_guid_t *protocol,
void **protocol_interface, void *agent_handle,
void *controller_handle, uint32_t attributes)
{
- *protocol_interface = bootefi_device_path;
+ *protocol_interface = real_bootefi_device_path;
return EFI_SUCCESS;
}

/* The EFI loaded_image interface for the image executed via "bootefi" */
static struct efi_loaded_image loaded_image_info = {
- .device_handle = bootefi_device_path,
.file_path = bootefi_image_path,
};

@@ -93,7 +97,6 @@ static struct efi_object loaded_image_info_obj = {

/* The EFI object struct for the device the "bootefi" image was loaded from */
static struct efi_object bootefi_device_obj = {
- .handle = bootefi_device_path,
.protocols = {
{
/* When asking for the device path interface, return
@@ -239,8 +242,6 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt)

if (!memcmp(bootefi_device_path[0].str, "N\0e\0t", 6))
loaded_image_info.device_handle = nethandle;
- else
- loaded_image_info.device_handle = bootefi_device_path;
#endif
#ifdef CONFIG_GENERATE_SMBIOS_TABLE
efi_smbios_register();
@@ -339,6 +340,18 @@ U_BOOT_CMD(
bootefi_help_text
);

+#ifdef CONFIG_DM
+static int parse_partnum(const char *devnr)
+{
+ const char *str = strchr(devnr, ':');
+ if (str) {
+ str++;
+ return simple_strtoul(str, NULL, 16);
+ }
+ return 0;
+}
+#endif
+
void efi_set_bootdev(const char *dev, const char *devnr, const char *path)
{
__maybe_unused struct blk_desc *desc;
@@ -376,9 +389,14 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path)
if (colon)
*colon = '\0';

+#ifdef CONFIG_DM
+ real_bootefi_device_path = efi_dp_from_part(desc, parse_partnum(devnr));
+#else
/* Patch bootefi_device_path to the target device */
+ real_bootefi_device_path = bootefi_device_path;
memset(bootefi_device_path[0].str, 0, sizeof(bootefi_device_path[0].str));
ascii2unicode(bootefi_device_path[0].str, devname);
+#endif

/* Patch bootefi_image_path to the target file path */
memset(bootefi_image_path[0].str, 0, sizeof(bootefi_image_path[0].str));
@@ -389,4 +407,7 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path)
snprintf(devname, sizeof(devname), "%s", path);
}
ascii2unicode(bootefi_image_path[0].str, devname);
+
+ loaded_image_info.device_handle = real_bootefi_device_path;
+ bootefi_device_obj.handle = real_bootefi_device_path;
}
--
2.13.0