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

Mark Kettenis mark.kettenis at xs4all.nl
Tue Aug 5 09:50:04 CEST 2025


> From: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
> Date: Tue,  5 Aug 2025 07:46:14 +0200
> 
> From: Simon Glass <sjg at chromium.org>
> 
> It is sometimes useful to be able to boot via EFI using a Linux initrd.
> Add support for this.
> 
> Fix a 'specifiy' typo while here.
> 
> Signed-off-by: Simon Glass <sjg at chromium.org>
> Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
> ---
> v2:
> 	consistently refer to Linux initrd instead of RAM disk

Thanks!

Reviewed-by: Mark Kettenis <kettenis at openbsd.org>

> ---
>  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;
> +		}
> +	}
> +
> +	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);
>  
>  	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