If the image address matches the last loaded PE_COFF, it is an error
to pass the incorrect size (but the size may be omitted).
Signed-off-by: Kyle Evans <kev...@freebsd.org>
---
Changes since v1:
- Specifying an address that isn't the last-known without a size produces the
same error as in the past ("No UEFI binary known at ...")
- Specifying a size with the last known address that doesn't match the last
recorded size will get: Size does not match known UEFI binary at %s
cmd/bootefi.c | 42 ++++++++++++++++++++++++++++++++++--------
1 file changed, 34 insertions(+), 8 deletions(-)
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 53d9f0e0dc..0d3aecb2a1 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -425,7 +425,7 @@ static int do_efibootmgr(void)
* @image_opt: string of image start address
* Return: status code
*/
-static int do_bootefi_image(const char *image_opt)
+static int do_bootefi_image(const char *image_opt, const char *size_opt)
{
void *image_buf;
unsigned long addr, size;
@@ -444,13 +444,35 @@ static int do_bootefi_image(const char *image_opt)
if (!addr)
return CMD_RET_USAGE;
+ size = 0;
+ if (size_opt) {
+ size = strtoul(size_opt, NULL, 16);
+ /* Check that a numeric value was passed */
+ if (!size)
+ return CMD_RET_USAGE;
+ }
+
image_buf = map_sysmem(addr, 0);
if (image_buf != image_addr) {
- log_err("No UEFI binary known at %s\n", image_opt);
- return CMD_RET_FAILURE;
+ /* Fake device path -- we must have a size. */
+
+ if (size == 0) {
+ printf("No UEFI binary known at %s\n",
image_opt);
+ return CMD_RET_FAILURE;
+ }
+
+ if (image_addr)
+ efi_clear_bootdev();
+ } else {
+ if (size != 0 && size != image_size) {
+ printf("Size does not match known UEFI binary at
%s\n",
+ image_opt);
+ return CMD_RET_FAILURE;
+ }
+
+ size = image_size;
}
- size = image_size;
}
ret = efi_run_image(image_buf, size);
@@ -654,7 +676,7 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, int
argc,
return CMD_RET_FAILURE;
}
- if (argc > 2) {
+ if (argc > 2 && strcmp(argv[2], "-") != 0) {
uintptr_t fdt_addr;
fdt_addr = hextoul(argv[2], NULL);
@@ -677,15 +699,19 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag,
int argc,
return do_efi_selftest();
#endif
- return do_bootefi_image(argv[1]);
+ return do_bootefi_image(argv[1], argc > 3 ? argv[3] : NULL);
}
#ifdef CONFIG_SYS_LONGHELP
static char bootefi_help_text[] =
- "<image address> [fdt address]\n"
+ "<image address> [fdt address [image size]]\n"
" - boot EFI payload stored at address <image address>.\n"
" If specified, the device tree located at <fdt address> gets\n"
" exposed as EFI configuration table.\n"
+ " The image size is required if this is not a preloaded image, but\n"
+ " it must be omitted if the image was preloaded.\n"
+ " The <fdt address> parameter accepts '-' to indicate FDT already\n"
+ " installed or pre-specified in fdt_addr or fdtcontroladdr.\n"
#ifdef CONFIG_CMD_BOOTEFI_HELLO
"bootefi hello\n"
" - boot a sample Hello World application stored within U-Boot\n"
@@ -707,7 +733,7 @@ static char bootefi_help_text[] =
#endif
U_BOOT_CMD(
- bootefi, 3, 0, do_bootefi,
+ bootefi, 4, 0, do_bootefi,
"Boots an EFI payload from memory",
bootefi_help_text
);
--
2.33.0