[PATCH v2 1/1] efi_loader: Support loading a ramdisk with bootefi

Heinrich Schuchardt heinrich.schuchardt at canonical.com
Tue Aug 5 09:33:43 CEST 2025


On 05.08.25 08:56, Ilias Apalodimas wrote:
> Hi Heinrich,
> 
> 
> On Tue, 5 Aug 2025 at 08:46, Heinrich Schuchardt 
> <heinrich.schuchardt at canonical.com 
> <mailto:heinrich.schuchardt at canonical.com>> wrote:
> 
>     From: Simon Glass <sjg at chromium.org <mailto:sjg at 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 <sjg at chromium.org <mailto:sjg at chromium.org>>
>     Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com
>     <mailto:heinrich.schuchardt at 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
> 



More information about the U-Boot mailing list