[PATCH v4 1/1] image: fit: Apply overlays using aligned writable FDT copies
James Hilliard
james.hilliard1 at gmail.com
Thu Feb 12 22:32:08 CET 2026
On Thu, Feb 12, 2026 at 1:05 PM Marek Vasut <marek.vasut at mailbox.org> wrote:
>
> On 2/12/26 8:52 PM, James Hilliard wrote:
> > On Thu, Feb 12, 2026 at 8:26 AM Marek Vasut <marek.vasut at mailbox.org> wrote:
> >>
> >> On 2/11/26 7:06 PM, James Hilliard wrote:
> >>
> >>> +static int boot_get_fdt_fit_into_buffer(const void *src, ulong srclen,
> >>> + ulong extra, ulong min_dstlen,
> >>> + void **fdtdstbuf, ulong *fdtdstlenp)
> >>> +{
> >>> + const void *fdtsrcbuf;
> >>> + void *tmp = NULL;
> >>> + void *dstbuf, *newdstbuf;
> >>> + ulong dstlen, newdstlen;
> >>> + int err;
> >>> +
> >>> + /* Make sure the source FDT/DTO is 8-byte aligned for libfdt. */
> >>> + fdtsrcbuf = src;
> >>> + if (!IS_ALIGNED((uintptr_t)src, 8)) {
> >>> + tmp = memalign(8, srclen);
> >>> + if (!tmp)
> >>> + return -ENOMEM;
> >>> +
> >>> + memcpy(tmp, src, srclen);
> >>> + fdtsrcbuf = tmp;
> >>> + }
> >>> +
> >>> + newdstlen = ALIGN(fdt_totalsize(fdtsrcbuf) + extra, SZ_4K);
> >>> + min_dstlen = ALIGN(min_dstlen, SZ_4K);
> >>> + if (newdstlen < min_dstlen)
> >>> + newdstlen = min_dstlen;
> >>> +
> >>> + dstbuf = *fdtdstbuf;
> >>> + dstlen = dstbuf ? *fdtdstlenp : 0;
> >>> +
> >>> + /*
> >>> + * If the caller already provided a large enough writable buffer,
> >>> + * and we're not moving the FDT, nothing to do.
> >>> + */
> >>> + if (dstbuf && dstlen >= newdstlen && dstbuf == fdtsrcbuf) {
> >>
> >> Can $dstbuf ever be NULL ?
> >>
> >>> + free(tmp);
> >>> + return 0;
> >>
> >> You could try something like this here, to reduce the duplicate
> >> free(tmp) in the code:
> >>
> >> "
> >> err = 0;
> >> goto exit;
> >>
> >> ...
> >>
> >> exit:
> >> free(tmp);
> >> return err;
> >> "
> >>
> >>> + }
> >>> +
> >>
> >> [...]
> >>
> >>> - load = (ulong)of_flat_tree;
> >>> + len = fdt_off_dt_strings(base_buf) + fdt_size_dt_strings(base_buf);
> >> How does this new length calculation work, can you please clarify that ?
> >
> > From my understanding, that len is tracking the current packed DTB data
> > length (up to the end of the strings block), not the allocated buffer size. We
> > recompute it after each overlay so need = len + ovcopylen
> > CONFIG_SYS_FDT_PAD grows from real used bytes instead of
> > accumulated slack. This is roughly the same idea as libfdt’s internal
> > fdt_data_size_(), and the final returned size is still taken after fdt_pack()
> > with fdt_totalsize().
>
> Ah I see, thank you for the clarification, this helped. It would be nice
> to include that as code comment too.
I'll add a comment.
>
> But don't you have to account for the FDT headers too, so wouldn't
> fdt_totalsize() be more appropriate here ?
>From my understanding, fdt_off_dt_strings() + fdt_size_dt_strings() is the
packed DTB data size we need for growth calculations, and it already
covers data from the blob start (so headers are implicitly accounted for
via the offset). fdt_totalsize() includes spare/free space, so using it there
would overestimate need and cause unnecessary buffer growth.
>
> >> I don't think this will work for fitImages with external data (generated
> >> using mkimage -E) , but I might be wrong.
> >
> > From my understanding, this should still work with mkimage -E, external
> > data only changes where FIT payload bytes are stored, and
> > fit_image_load()/fit_image_get_data() already resolves that before overlay
> > application. At that point we’re operating on a normal copied DTB buffer,
> > and the length math is based on DTB-internal layout, not FIT
> > external-data placement.
>
> Clear, you're right.
More information about the U-Boot
mailing list