[PATCH 06/11] boot: imagemap: read only the bytes an extend adds
Daniel Golle
daniel at makrotopia.org
Mon Sep 28 17:05:32 PDT 2026
Growing a region re-reads it from the start even when the reservation
was renewed at the same address and the leading bytes are still valid.
The translation table exists to avoid re-reading data that is already in
RAM, so the common case of probing a FIT header and then mapping the
whole structure pays for the header twice.
Read only the range the larger request adds when the region has not
moved. A reservation that had to be placed elsewhere still needs the
whole range.
Fixes: 9b41c7dbee96 ("boot: add imagemap on-demand loading from storage")
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
boot/imagemap.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/boot/imagemap.c b/boot/imagemap.c
index a28c7928e46..b004aa1644b 100644
--- a/boot/imagemap.c
+++ b/boot/imagemap.c
@@ -213,8 +213,10 @@ void *imagemap_map(struct udevice *dev, loff_t img_offset, ulong size)
ulong overhead = img_offset & (bl_len - 1);
loff_t base_off = img_offset - overhead;
ulong read_size = ALIGN(size + overhead, bl_len);
+ phys_addr_t old_addr;
phys_addr_t addr;
phys_size_t alloc_size;
+ ulong old_size;
void *base;
int ret;
struct imagemap_region *r;
@@ -241,9 +243,11 @@ void *imagemap_map(struct udevice *dev, loff_t img_offset, ulong size)
if (!r->lmb_reserved)
break;
- addr = map_to_sysmem(r->ram);
+ old_size = r->size;
+ old_addr = map_to_sysmem(r->ram);
+ addr = old_addr;
- lmb_free(addr, ALIGN(r->size, ARCH_DMA_MINALIGN),
+ lmb_free(addr, ALIGN(old_size, ARCH_DMA_MINALIGN),
LMB_NONE);
/* Try to re-reserve at the same address with new size */
@@ -261,8 +265,14 @@ void *imagemap_map(struct udevice *dev, loff_t img_offset, ulong size)
}
base = map_sysmem(addr, alloc_size);
- ret = spl_load_region(&priv->info, img_offset, size,
- base);
+ if (addr == old_addr)
+ ret = spl_load_region(&priv->info,
+ base_off + old_size,
+ read_size - old_size,
+ (char *)base + old_size);
+ else
+ ret = spl_load_region(&priv->info, img_offset,
+ size, base);
if (ret < 0) {
log_err("imagemap: read failed at offset 0x%llx (size 0x%lx): %d\n",
(unsigned long long)img_offset, size, ret);
--
2.55.0
More information about the openwrt-devel
mailing list