[PATCH v2 4/8] efi_loader: load device-tree specified in boot option
Heinrich Schuchardt
heinrich.schuchardt at canonical.com
Tue May 28 16:42:48 CEST 2024
We allow to specify the triple of binary, initrd, and device-tree in boot
options.
Add the code to actually load the specified device-tree.
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
---
v2:
Put all related changes into one patch.
Do not boot if device-tree cannot be loaded.
---
lib/efi_loader/efi_bootmgr.c | 70 ++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index b0bf21cf841..5ac116a7edf 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -1185,6 +1185,59 @@ out:
return ret;
}
+/**
+ * load_fdt_from_load_option - load device-tree from load option
+ *
+ * fdt: pointer to loaded device-tree or NULL
+ * Return: status code
+ */
+static efi_status_t load_fdt_from_load_option(void **fdt)
+{
+ struct efi_device_path *dp = NULL;
+ struct efi_file_handle *f = NULL;
+ efi_uintn_t filesize;
+ efi_status_t ret;
+
+ *fdt = NULL;
+
+ dp = efi_get_dp_from_boot(&efi_guid_fdt);
+ if (!dp)
+ return EFI_SUCCESS;
+
+ /* Open file */
+ f = efi_file_from_path(dp);
+ if (!f) {
+ log_err("Can't find %pD specified in Boot####\n", dp);
+ ret = EFI_NOT_FOUND;
+ goto out;
+ }
+
+ /* Get file size */
+ ret = efi_file_size(f, &filesize);
+ if (ret != EFI_SUCCESS)
+ goto out;
+
+ *fdt = malloc(filesize);
+ if (!*fdt) {
+ log_err("Out of memory\n");
+ ret = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+ ret = EFI_CALL(f->read(f, &filesize, *fdt));
+ if (ret != EFI_SUCCESS) {
+ log_err("Can't read fdt\n");
+ free(*fdt);
+ *fdt = NULL;
+ }
+
+out:
+ efi_free_pool(dp);
+ if (f)
+ EFI_CALL(f->close(f));
+
+ return ret;
+}
+
/**
* efi_bootmgr_run() - execute EFI boot manager
* @fdt: Flat device tree
@@ -1200,6 +1253,7 @@ efi_status_t efi_bootmgr_run(void *fdt)
efi_handle_t handle;
void *load_options;
efi_status_t ret;
+ void *fdt_lo;
/* Initialize EFI drivers */
ret = efi_init_obj_list();
@@ -1215,7 +1269,23 @@ efi_status_t efi_bootmgr_run(void *fdt)
return ret;
}
+ if (!IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
+ ret = load_fdt_from_load_option(&fdt_lo);
+ if (ret != EFI_SUCCESS)
+ return ret;
+ if (fdt_lo)
+ fdt = fdt_lo;
+ }
+
+ /*
+ * Needed in ACPI case to create reservations based on
+ * control device-tree.
+ */
ret = efi_install_fdt(fdt);
+
+ if (!IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE))
+ free(fdt_lo);
+
if (ret != EFI_SUCCESS) {
if (EFI_CALL(efi_unload_image(handle)) == EFI_SUCCESS)
free(load_options);
--
2.43.0
More information about the U-Boot
mailing list