mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-26 23:41:50 +00:00
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>
This commit is contained in:
parent
bfaed6969c
commit
881f0b77dc
1 changed files with 16 additions and 8 deletions
|
@ -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++) {
|
||||
|
|
Loading…
Add table
Reference in a new issue