boot: Show the device path for EFI bootflows

If the bootflow relates to the EFI bootmeth, show the device path along
with the other info.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2025-08-27 13:30:23 -06:00
parent ead588c067
commit e6f9a0ae58
5 changed files with 101 additions and 0 deletions

View File

@@ -13,6 +13,7 @@
#include <command.h>
#include <console.h>
#include <dm.h>
#include <efi_device_path.h>
#include <expo.h>
#include <log.h>
#include <mapmem.h>
@@ -453,6 +454,22 @@ static int do_bootflow_info(struct cmd_tbl *cmdtp, int flag, int argc,
printf("FDT addr: %lx\n", bflow->fdt_addr);
}
printf("Error: %d\n", bflow->err);
if (IS_ENABLED(CONFIG_BOOTMETH_EFI) &&
bflow->method->driver == DM_DRIVER_GET(bootmeth_4efi)) {
struct efi_device_path *dp;
bool alloced;
ret = efi_dp_from_bootflow(bflow, &dp, &alloced);
printf("EFI path ");
if (!ret) {
printf("%pD\n", dp);
if (alloced)
efi_free_pool(dp);
} else {
printf("(err %dE)\n", ret);
}
}
if (dump && bflow->buf) {
/* Set some sort of maximum on the size */
int size = min(bflow->size, 10 << 10);

View File

@@ -23,6 +23,8 @@
#include <net.h>
#endif
struct udevice;
/* Type INTN in UEFI specification */
#define efi_intn_t ssize_t
/* Type UINTN in UEFI specification*/
@@ -848,4 +850,17 @@ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size,
struct efi_device_path *dp_dev,
struct efi_device_path *dp_img);
/**
* efi_dp_from_bootdev() - Get the device path from a bootdev
*
* This is only available in the app. It looks up the bootdev and returns the
* assocated device path (attached to its sibling block device)
*
* @dev: UCLASS_BOOTDEV device to check
* @dpp: Returns device path on success
* Returns: 0 if OK, -ve on error
*/
int efi_dp_from_bootdev(const struct udevice *dev,
const struct efi_device_path **dpp);
#endif /* _LINUX_EFI_H */

View File

@@ -12,6 +12,7 @@
enum uclass_id;
struct blk_desc;
struct bootflow;
struct efi_load_option;
struct udevice;
@@ -429,4 +430,17 @@ struct efi_device_path *efi_dp_from_http(const char *server,
const char *efi_dp_guess_uclass(struct efi_device_path *device_path,
enum uclass_id *guessp);
/**
* efi_dp_from_bootflow() - Get the device path for a bootflow
*
* @bflow: Bootflow to check
* @dpp: Returns the device path
* @allocedp: if NULL, no allocation is permitted, otherwise retrusn true if
* efi_free_pool() must be called to free the device path
* Return: 0 if OK, -EINVAL if @allocedp is NULL and allocation is needed,
* -ve on error
*/
int efi_dp_from_bootflow(const struct bootflow *bflow,
struct efi_device_path **dpp, bool *allocedp);
#endif /* EFI_DEVICE_PATH_H */

View File

@@ -8,6 +8,7 @@
#define LOG_CATEGORY LOGC_EFI
#include <blk.h>
#include <bootflow.h>
#include <dm.h>
#include <dm/root.h>
#include <efi_device_path.h>
@@ -1376,3 +1377,39 @@ const char *efi_dp_guess_uclass(struct efi_device_path *device_path,
return best_name;
}
int efi_dp_from_bootflow(const struct bootflow *bflow,
struct efi_device_path **dpp, bool *allocedp)
{
struct udevice *bdev = bflow->dev;
struct blk_desc *desc;
struct udevice *blk;
int ret;
if (IS_ENABLED(CONFIG_EFI_APP)) {
const struct efi_device_path *dpc;
ret = efi_dp_from_bootdev(bflow->dev, &dpc);
if (ret)
return log_msg_ret("dfa", ret);
*dpp = (struct efi_device_path *)dpc;
if (allocedp)
*allocedp = false;
} else {
struct efi_device_path *dp;
if (!allocedp)
return log_msg_ret("dfb", -EINVAL);
ret = bootdev_get_sibling_blk(bdev, &blk);
if (ret)
return log_msg_ret("dfc", ret);
desc = dev_get_uclass_plat(blk);
dp = efi_dp_from_part(desc, bflow->part);
if (!dp)
return log_msg_ret("dfd", -ENOMEM);
*allocedp = true;
*dpp = dp;
}
return 0;
}

View File

@@ -7,6 +7,7 @@
*/
#include <bootm.h>
#include <dm.h>
#include <efi.h>
#include <efi_api.h>
#include <efi_device_path.h>
@@ -89,3 +90,20 @@ efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt,
{
return efi_run_image(image, size, dp_dev, dp_img);
}
int efi_dp_from_bootdev(const struct udevice *dev,
const struct efi_device_path **dpp)
{
const struct udevice *media = dev_get_parent(dev);
const struct efi_media_plat *plat;
log_debug("dev '%s': uclass ID %d\n", media->name,
device_get_uclass_id(media));
if (device_get_uclass_id(media) != UCLASS_EFI_MEDIA)
return log_msg_ret("efb", -ENOTSUPP);
plat = dev_get_plat(media);
*dpp = plat->device_path;
return 0;
}