[U-Boot] [PATCH 1/1] efi_loader: use built-in device tree in bootefi command

Heinrich Schuchardt xypron.glpk at gmx.de
Sat Jan 20 12:56:19 UTC 2018


The bootefi command has two parameters: the address of the executable and
the address of the flattened device tree.

When executing the devicetree command in grub this command can only
replace an existing device tree. So we always want to pass a device tree.

With the patch the device tree defaults to the internal one. But of cause
the user still can supply his one via the second parameter.

One use case is booting via iPXE from an iSCSI drive. As we may be able
to choose between different operating systems in the iPXE menu we cannot
know the correct device tree when invoking bootefi. The dtb might not even
be installed on a local device.

Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
 cmd/bootefi.c | 40 +++++++++++++++++++++++++++-------------
 1 file changed, 27 insertions(+), 13 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 51213c0293..c7f2887df2 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -276,7 +276,7 @@ exit:
 	return ret;
 }
 
-static int do_bootefi_bootmgr_exec(unsigned long fdt_addr)
+static int do_bootefi_bootmgr_exec(struct fdt_header *fdt_addr)
 {
 	struct efi_device_path *device_path, *file_path;
 	void *addr;
@@ -310,10 +310,34 @@ static int do_bootefi_bootmgr_exec(unsigned long fdt_addr)
 /* Interpreter command to boot an arbitrary EFI image from memory */
 static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	char *saddr, *sfdt;
-	unsigned long addr, fdt_addr = 0;
+	char *saddr;
+	unsigned long addr;
+	struct fdt_header *fdt_addr = NULL;
 	efi_status_t r;
 
+	/* Set the device tree address */
+	if (argc > 2) {
+		fdt_addr = (struct fdt_header *)simple_strtoul(
+							argv[2], NULL, 16);
+	} else {
+		/* If no device tree is supplied, try using the internal one */
+		fdt_addr = (struct fdt_header *)gd->fdt_blob;
+		if (fdt_addr)
+			printf("Using built-in device tree\n");
+	}
+
+	/* Validate the device tree */
+	if (fdt_addr) {
+		int err = fdt_check_header(fdt_addr);
+
+		if (err < 0) {
+			printf("The device tree is not valid\n");
+			debug("libfdt fdt_check_header(): %s\n",
+			      fdt_strerror(err));
+			return CMD_RET_FAILURE;
+		}
+	}
+
 	if (argc < 2)
 		return CMD_RET_USAGE;
 #ifdef CONFIG_CMD_BOOTEFI_HELLO
@@ -362,21 +386,11 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	} else
 #endif
 	if (!strcmp(argv[1], "bootmgr")) {
-		unsigned long fdt_addr = 0;
-
-		if (argc > 2)
-			fdt_addr = simple_strtoul(argv[2], NULL, 16);
-
 		return do_bootefi_bootmgr_exec(fdt_addr);
 	} else {
 		saddr = argv[1];
 
 		addr = simple_strtoul(saddr, NULL, 16);
-
-		if (argc > 2) {
-			sfdt = argv[2];
-			fdt_addr = simple_strtoul(sfdt, NULL, 16);
-		}
 	}
 
 	printf("## Starting EFI application at %08lx ...\n", addr);
-- 
2.14.2



More information about the U-Boot mailing list