
On Sat, Apr 9, 2022 at 5:37 AM Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 4/6/22 07:04, kevans@FreeBSD.org wrote:
From: Kyle Evans kevans@FreeBSD.org
Up until commit 5f59518a7b1ae ("efi_loader: setting boot device"), we could boot an arbitrary blob with bootefi. Indeed, efi_run_image() even has a special case for missing device paths indicating a payload that was directly loaded via JTAG, for example.
Restore the ability to inject a UEFI payload into memory and `bootefi` it. If the address passed isn't the last PE-COFF loaded, then we'll wipe out the pre-existing DP/Image information and let efi_run_image() synthesize a memory device path.
An image size is required if we're booting an arbitrary payload, and the FDT argument has been changed to accept `-`. The size could be deduced from the image header, but it's required anyways as an explicit acknowledgment that one's trying to boot an arbitrary payload rather than accidentally using the wrong address in the single-addr form.
Signed-off-by: Kyle Evans kevans@FreeBSD.org
I have tested at follows:
host bind 0 ../sandbox.img load host 0:1 $kernel_addr_r helloworld.efi bootefi $fdt_add_r
Expected result is a message No UEFI binary known at 0xc00000
With your patch the message is not shown. Instead the help text for bootefi is displayed.
I can certainly pare down how often the help text is shown, I kind of threw it everywhere thinking it'd be helpful because a lot of these are "you're using it wrong" (including the above), but I'm a little more awake now and could also see how this is more correct as "No UEFI binary known" and the latter is more correct as "Incorrect size specified".
cmd/bootefi.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 53d9f0e0dc..1dac74781e 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,29 @@ 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 (image_addr)
efi_clear_bootdev();
if (size == 0)
return CMD_RET_USAGE;
} else {
if (size != 0)
return CMD_RET_USAGE;
size = image_size; }
size = image_size; } ret = efi_run_image(image_buf, size);
@@ -654,7 +670,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 +693,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"
Why must the image size be omitted?
I expect the following to work fine:
load host 0:1 $kernel_addr_r foo.efi bootefi $kernel_addr_r - $filesize
I'll change this to allow omission and require a match if it's specified and the address matches last loaded.
Best regards
Heinrich
" The <fdt address> parameter accepts '-' to indicate FDT already\n"
#ifdef CONFIG_CMD_BOOTEFI_HELLO "bootefi hello\n" " - boot a sample Hello World application stored within U-Boot\n"" installed or pre-specified in fdt_addr or fdtcontroladdr.\n"
@@ -707,7 +727,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