On 05.08.25 08:56, Ilias Apalodimas wrote:
Hi Heinrich,
On Tue, 5 Aug 2025 at 08:46, Heinrich Schuchardt
<heinrich.schucha...@canonical.com
<mailto:heinrich.schucha...@canonical.com>> wrote:
From: Simon Glass <s...@chromium.org <mailto:s...@chromium.org>>
It is sometimes useful to be able to boot via EFI using a Linux initrd.
Add support for this.
Overall I don't mind adding this to bootefi.
Fix a 'specifiy' typo while here.
Signed-off-by: Simon Glass <s...@chromium.org <mailto:s...@chromium.org>>
Reviewed-by: Heinrich Schuchardt <heinrich.schucha...@canonical.com
<mailto:heinrich.schucha...@canonical.com>>
---
v2:
consistently refer to Linux initrd instead of RAM disk
---
cmd/bootefi.c | 33 +++++++++++++++++++++++++--------
doc/usage/cmd/bootefi.rst | 37 ++++++++++++++++++++++++++++++-------
2 files changed, 55 insertions(+), 15 deletions(-)
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 8e8752127ed..b8f5bb35950 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -136,22 +136,39 @@ static int do_bootefi(struct cmd_tbl *cmdtp,
int flag, int argc,
{
efi_status_t ret;
char *p;
- void *fdt, *image_buf;
- unsigned long addr, size;
+ void *fdt, *initrd = NULL, *image_buf;
+ unsigned long addr, size, rd_len = 0, fdt_addr = 0;
void *image_addr;
size_t image_size;
+ int fdt_arg = 2;
if (argc < 2)
return CMD_RET_USAGE;
if (argc > 2) {
- uintptr_t fdt_addr;
+ ulong rd_addr = 0;
+ char *end = strchr(argv[2], ':');
- fdt_addr = hextoul(argv[2], NULL);
+ if (end) {
+ rd_addr = hextoul(argv[2], NULL);
+ if (!rd_addr)
+ return CMD_RET_USAGE;
+
+ rd_len = hextoul(++end, NULL);
+ initrd = map_sysmem(rd_addr, rd_len);
+ ++fdt_arg;
+ }
+ }
Shouldn't we keep the order unchanged? I dont know if scripts are using
bootefi in the wild and although they shouldn't changing the order is an
ABI breakage
You can still use the existing forms:
bootefi <image_addr>
bootefi <image_addr> <fdt_addr>
The patch adds two new forms:
bootefi <image_addr> <initrd_addr:size>
bootefi <image_addr> <initrd_addr:size> <fdt_addr>
Existing scripts should not be impacted.
+
+ if (argc > fdt_arg + 1)
+ return CMD_RET_USAGE;
+ if (argc == fdt_arg + 1)
+ fdt_addr = hextoul(argv[fdt_arg], NULL);
+
+ if (fdt_addr)
fdt = map_sysmem(fdt_addr, 0);
- } else {
+ else
fdt = EFI_FDT_USE_INTERNAL;
- }
if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR) &&
!strcmp(argv[1], "bootmgr")) {
@@ -215,7 +232,7 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int
flag, int argc,
}
}
- ret = efi_binary_run(image_buf, size, fdt, NULL, 0);
+ ret = efi_binary_run(image_buf, size, fdt, initrd, rd_len);
The loadfile2 protocol that gets installed is later removed by a bootmgr
event in case of a failure. Is the event still called for bootefi ?
do_bootefi_exec() signals the event group
efi_guid_event_group_return_to_efibootmgr after returning from the payload.
Best regards
Heinrich
Thanks
/Ilias
if (ret != EFI_SUCCESS)
return CMD_RET_FAILURE;
@@ -224,7 +241,7 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int
flag, int argc,
}
U_BOOT_LONGHELP(bootefi,
- "<image address>[:<image size>] [<fdt address>]\n"
+ "<image address>[:<size>] [<initrd address>:<size>] [<fdt
address>]\n"
" - boot EFI payload\n"
#ifdef CONFIG_CMD_BOOTEFI_HELLO
"bootefi hello\n"
diff --git a/doc/usage/cmd/bootefi.rst b/doc/usage/cmd/bootefi.rst
index d6e4e62e383..7c5448586b7 100644
--- a/doc/usage/cmd/bootefi.rst
+++ b/doc/usage/cmd/bootefi.rst
@@ -12,7 +12,7 @@ Synopsis
::
- bootefi <image_addr>[:<image_size>] [<fdt_addr>]
+ bootefi <image_addr>[:<image_size>]
[<initrd_addr>:<initrd_size>] [<fdt_address>]
bootefi bootmgr [<fdt_addr>]
bootefi hello [<fdt_addr>]
bootefi selftest [<fdt_addr>]
@@ -44,6 +44,16 @@ command sequence to run a UEFI application might
look like
load mmc 0:1 $kernel_addr_r /EFI/grub/grubaa64.efi
bootefi $kernel_addr_r $fdt_addr_r
+or
+
+::
+
+ setenv bootargs root=/dev/vda1
+ load mmc 0:1 $fdt_addr_r dtb
+ load mmc 0:1 $kernel_addr_r vmlinux
+ load mmc 0:1 $initrd_addr_r intird
+ bootefi $kernel_addr_r $initrd_addr_r:$filesize $fdt_addr_r
+
The last UEFI binary loaded defines the image file path in the
loaded image
protocol.
@@ -51,21 +61,34 @@ The value of the environment variable *bootargs*
is converted from UTF-8 to
UTF-16 and passed as load options in the loaded image protocol to
the UEFI
binary.
+.. note::
+
+ The bootefi command accepts one to three arguments.
+ If the second argument contains a colon ':', it is assumed to
specify the
+ initial RAM disk.
+
image_addr
Address of the UEFI binary.
-fdt_addr
- Address of the device-tree or '-'. If no address is specifiy, the
- environment variable $fdt_addr is used as first fallback, the
address of
- U-Boot's internal device-tree $fdtcontroladdr as second fallback.
- When using ACPI no device-tree shall be specified.
-
image_size
Size of the UEFI binary file. This argument is only needed if
*image_addr*
does not match the address of the last loaded UEFI binary. In
this case
a memory device path will be used as image file path in the
loaded image
protocol.
+initrd_addr
+ Address of the Linux initial RAM disk or '-'. If no address is
specified,
+ no RAM disk is used when booting.
+
+initrd_size
+ Size of the Linux initial RAM disk.
+
+fdt_addr
+ Address of the device-tree or '-'. If no address is specified, the
+ environment variable $fdt_addr is used as first fallback, the
address of
+ U-Boot's internal device-tree $fdtcontroladdr as second fallback.
+ When using ACPI no device-tree shall be specified.
+
Note
UEFI binaries that are contained in FIT images are launched
via the
*bootm* command.
--
2.50.0