aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuentin Schulz <quentin.schulz@cherry.de>2025-01-22 16:53:15 +0100
committerTom Rini <trini@konsulko.com>2025-02-04 11:57:36 -0600
commit881f0b77dc8cfc454fb99ee183717d2538013665 (patch)
tree192da0c9c1c95a8f69ee5aab696cc8308fa899b3
parentbfaed6969c119673c3087ffd778b8e3e324c3202 (diff)
downloadu-boot-881f0b77dc8cfc454fb99ee183717d2538013665.tar.gz
image: apply FDTOs on FDT image node without a load property
A FIT image which is NOT using -E when created by mkimage - that is with image data within the FIT - will fail to apply FDTO if the base FDT image node does not specify a load property (which points to an address in DRAM). This is because we check that the FDT address we want to apply overlay to (i.e. modify and likely increase in size) is not inside the FIT and give up otherwise. This is assumed necessary because we may then overwrite other data when applying in-place. However, we can do better than giving up: relocating the FDT in another place in DRAM where it's safe to increase its size and apply FDTOs. While at it, do not discriminate anymore on whether the data is within the FIT data address space - that is FIT images created with mkimage -E - as that still may be susceptible to unintended data overwrites as mkimage -E simply concatenates all blobs after the FIT. If the FDT blob isn't the last, it'll result in overwriting later blobs when resizing. The side effect is that the load property in the FIT is only temporarily used to load the FDT but then relocated right before we start applying overlays. Suggested-by: Marek Vasut <marex@denx.de> Reviewed-by: Marek Vasut <marex@denx.de> Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
-rw-r--r--boot/image-fit.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/boot/image-fit.c b/boot/image-fit.c
index e119c48ef6c..aa139da628c 100644
--- a/boot/image-fit.c
+++ b/boot/image-fit.c
@@ -2355,10 +2355,17 @@ int boot_get_fdt_fit(struct bootm_headers *images, ulong addr,
char *next_config = NULL;
ulong load, len;
#ifdef CONFIG_OF_LIBFDT_OVERLAY
- ulong image_start, image_end;
ulong ovload, ovlen, ovcopylen;
const char *uconfig;
const char *uname;
+ /*
+ * of_flat_tree is storing the void * returned by map_sysmem, then its
+ * address is passed to boot_relocate_fdt which expects a char ** and it
+ * is then cast into a ulong. Setting its type to void * would require
+ * to cast its address to char ** when passing it to boot_relocate_fdt.
+ * Instead, let's be lazy and use void *.
+ */
+ char *of_flat_tree;
void *base, *ov, *ovcopy = NULL;
int i, err, noffset, ov_noffset;
#endif
@@ -2402,17 +2409,18 @@ int boot_get_fdt_fit(struct bootm_headers *images, ulong addr,
/* we need to apply overlays */
#ifdef CONFIG_OF_LIBFDT_OVERLAY
- image_start = addr;
- image_end = addr + fit_get_size(fit);
- /* verify that relocation took place by load address not being in fit */
- if (load >= image_start && load < image_end) {
- /* check is simplified; fit load checks for overlaps */
- printf("Overlayed FDT requires relocation\n");
+ /* Relocate FDT so resizing does not overwrite other data in FIT. */
+ of_flat_tree = map_sysmem(load, len);
+ len = ALIGN(fdt_totalsize(load), SZ_4K);
+ err = boot_relocate_fdt(&of_flat_tree, &len);
+ if (err) {
+ printf("Required FDT relocation for applying DTOs failed: %d\n",
+ err);
fdt_noffset = -EBADF;
goto out;
}
- base = map_sysmem(load, len);
+ load = (ulong)of_flat_tree;
/* apply extra configs in FIT first, followed by args */
for (i = 1; ; i++) {