]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
efi_loader: Support loading a ramdisk with bootefi
authorSimon Glass <sjg@chromium.org>
Tue, 5 Aug 2025 05:46:14 +0000 (07:46 +0200)
committerHeinrich Schuchardt <heinrich.schuchardt@canonical.com>
Fri, 8 Aug 2025 06:45:18 +0000 (08:45 +0200)
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@chromium.org>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Mark Kettenis <kettenis@openbsd.org>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
cmd/bootefi.c
doc/usage/cmd/bootefi.rst

index 8e8752127ed85fe350dede9d54f9fe4cf110a452..b8f5bb3595044b7130994637e4123f6e3c1272aa 100644 (file)
@@ -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"
index d6e4e62e383762810a6abda8e735102ab324fe12..7c5448586b713810293fb5e41fb8d431119724df 100644 (file)
@@ -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.