From patchwork Fri Jan 9 23:11:36 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1423 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768000450; bh=BIohxOgzTHE1BBEjeTHLYKwhbGIqkbzmsZ6CQ5kmciw=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=koPMwXAC6SxQq2FPBOI/pEa2XlqxSBghDLqwtWJMYRZdFVJa5cOVeV7Dg6TFsBig1 u/5g3ccv+VzKagzxYyKo5uy71lBDTPLGTjvqVy6ajKlOYvOEzy6KwdDkpGilCtwG7j BeCtnmUrjrZ+lo1MIgitZeZosABiBvgRYpynBy+Iprow+PVmrGGWSawp3qhH6l7obD tLFnuSOXXFiaBE6C7m+r1hlcKITfIPGxRu0DlTi7NHTz7yrFycFxzCHys9IKkvMBjd JgGbAYdSyxP23Cd5k5PMq7aqNI/zjawEs7q54KR9z+0ddYX0IL478FHCEmstHsPVCG ksRXEqFiYx7Wg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id EBA9469243 for ; Fri, 9 Jan 2026 16:14:10 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id KqajOalGLUi1 for ; Fri, 9 Jan 2026 16:14:10 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768000450; bh=BIohxOgzTHE1BBEjeTHLYKwhbGIqkbzmsZ6CQ5kmciw=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=koPMwXAC6SxQq2FPBOI/pEa2XlqxSBghDLqwtWJMYRZdFVJa5cOVeV7Dg6TFsBig1 u/5g3ccv+VzKagzxYyKo5uy71lBDTPLGTjvqVy6ajKlOYvOEzy6KwdDkpGilCtwG7j BeCtnmUrjrZ+lo1MIgitZeZosABiBvgRYpynBy+Iprow+PVmrGGWSawp3qhH6l7obD tLFnuSOXXFiaBE6C7m+r1hlcKITfIPGxRu0DlTi7NHTz7yrFycFxzCHys9IKkvMBjd JgGbAYdSyxP23Cd5k5PMq7aqNI/zjawEs7q54KR9z+0ddYX0IL478FHCEmstHsPVCG ksRXEqFiYx7Wg== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id DA7A069241 for ; Fri, 9 Jan 2026 16:14:10 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768000448; bh=GKDONxy17cLnndN1MtxWGApzjA8LEPRxew4hkzxQZ1c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BDjXoMQK6OIlpig934BqvO+jA/BMOuMqRsblOkp0ieAbWUTcYzpFDRA9zlcDePtP5 d/jeSxBrynLbLVb15PDHPIdSVihntii9q60h2yYQe9z4GSTk/vGW7e1744SWvZys6S Imb+mvgPbBLFwxOShDpWWnWqVfBMjN2pxi3aJYCZxy/HX32VfAQuOePYVai40yplRN bPQA3hYHqx247d8X1QLneVORw2cQEWF02BF8SF4x0L97Sin9HXLLkKFIlc7cnl8L9w bslcHOF5mi00GvXFL1WpourlBDa68u2RalHsKasFHkwB1yQDUXQxprEPyaAyhNt6/3 ao/CjC0QCSthg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id E637F69218; Fri, 9 Jan 2026 16:14:08 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id mwH7YhzNY9hs; Fri, 9 Jan 2026 16:14:08 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768000444; bh=vqiDX4tKntZg8tQ3THH1IuG8e+gOJ/rssAY4nu65NmI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Et0t/20A4OPnnViod1DATicKBzSN1I7NetA/IjIILZJRJMS2h7nEax8qD6JBBq54P iykQeWjkh6KwYH9HT9F92I5GQ9/tlUBWkFP5cMv3zny3QkoYjYNGxL2pJ8UTEunZ6f 93sn/pWQttIPXHLsO9AZPEAtMKvF17Owds/zlU24/MdfYnnKZzTg85XsrzzXVFP6wI DGmLcKQtfsYbE2ZS+f7Qh1C8gUMXdPBYI6vcMfFYdckUtXUnF7KCQVtNw7Dd7iWu6V P9hWwU4Lv20dsHbT+Dt4+M8U+HKYSHRQUOwpsenb1uAhb1lF/ih04rYBZKIV6631oj 763YDzcaiL2zg== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 5519D5FF82; Fri, 9 Jan 2026 16:14:04 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Fri, 9 Jan 2026 16:11:36 -0700 Message-ID: <20260109231151.4056804-28-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260109231151.4056804-1-sjg@u-boot.org> References: <20260109231151.4056804-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: OMEKCG26JRJVXNGJC6VZOWWOXH4ZJ5KA X-Message-ID-Hash: OMEKCG26JRJVXNGJC6VZOWWOXH4ZJ5KA X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Heinrich Schuchardt , Simon Glass , "Claude Opus 4 . 5" X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 27/32] boot: pxe: Split overlay loading and applying into two passes List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Introduce struct pxe_fdtoverlay to hold both the path and loaded address for each overlay. Update label_boot_fdtoverlay() to: 1. First pass: load all overlay files and store their addresses 2. Resize the main FDT once to make room for all overlays 3. Second pass: apply all loaded overlays This ensures all overlays are loaded before any are applied, which may be useful when overlays depend on each other or when the FDT resize could affect memory layout. Co-developed-by: Claude Opus 4.5 Signed-off-by: Simon Glass --- boot/pxe_parse.c | 19 ++++++++++--------- boot/pxe_utils.c | 37 +++++++++++++++++++++---------------- include/pxe_utils.h | 13 ++++++++++++- test/boot/pxe.c | 4 ++-- 4 files changed, 45 insertions(+), 28 deletions(-) diff --git a/boot/pxe_parse.c b/boot/pxe_parse.c index b115fb413a2..6d148756b0d 100644 --- a/boot/pxe_parse.c +++ b/boot/pxe_parse.c @@ -106,14 +106,14 @@ static struct pxe_label *label_create(void) if (!label) return NULL; memset(label, 0, sizeof(struct pxe_label)); - alist_init_struct(&label->fdtoverlays, char *); + alist_init_struct(&label->fdtoverlays, struct pxe_fdtoverlay); return label; } void label_destroy(struct pxe_label *label) { - char **overlayp; + struct pxe_fdtoverlay *overlay; free(label->name); free(label->kernel_label); @@ -123,8 +123,8 @@ void label_destroy(struct pxe_label *label) free(label->initrd); free(label->fdt); free(label->fdtdir); - alist_for_each(overlayp, &label->fdtoverlays) - free(*overlayp); + alist_for_each(overlay, &label->fdtoverlays) + free(overlay->path); alist_uninit(&label->fdtoverlays); free(label->say); free(label); @@ -323,7 +323,7 @@ static int parse_fdtoverlays(char **c, struct alist *overlays) return err; while (*val) { - char *path; + struct pxe_fdtoverlay item; char *end; /* Skip leading spaces */ @@ -336,15 +336,16 @@ static int parse_fdtoverlays(char **c, struct alist *overlays) /* Find end of this path */ end = strchr(val, ' '); if (end) { - path = strndup(val, end - val); + item.path = strndup(val, end - val); val = end; } else { - path = strdup(val); + item.path = strdup(val); val += strlen(val); } + item.addr = 0; - if (!path || !alist_add(overlays, path)) { - free(path); + if (!item.path || !alist_add(overlays, item)) { + free(item.path); return -ENOMEM; } } diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index a50fa4bc333..8d565d971fc 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -306,9 +306,9 @@ static void label_boot_kaslrseed(struct pxe_context *ctx) static void label_boot_fdtoverlay(struct pxe_context *ctx, struct pxe_label *label) { + struct pxe_fdtoverlay *overlay; struct fdt_header *blob; ulong fdtoverlay_addr; - char **overlayp; bool use_lmb; char *envaddr; int err; @@ -331,38 +331,43 @@ static void label_boot_fdtoverlay(struct pxe_context *ctx, use_lmb = true; } - /* Apply each overlay file in order */ - alist_for_each(overlayp, &label->fdtoverlays) { - const char *overlayfile = *overlayp; + /* First pass: load all overlay files */ + alist_for_each(overlay, &label->fdtoverlays) { ulong addr = fdtoverlay_addr; ulong size; - /* Load overlay file */ - err = get_relfile(ctx, overlayfile, &addr, SZ_4K, + err = get_relfile(ctx, overlay->path, &addr, SZ_4K, (enum bootflow_img_t)IH_TYPE_FLATDT, &size); if (err < 0) { - printf("Failed loading overlay %s\n", overlayfile); + printf("Failed loading overlay %s\n", overlay->path); continue; } + overlay->addr = addr; - /* Resize main fdt */ - fdt_shrink_to_minimum(ctx->fdt, 8192); + /* Move to next address if using fixed addresses */ + if (!use_lmb) + fdtoverlay_addr = addr + size; + } + + /* Resize main fdt to make room for overlays */ + fdt_shrink_to_minimum(ctx->fdt, 8192); - blob = map_sysmem(addr, 0); + /* Second pass: apply all loaded overlays */ + alist_for_each(overlay, &label->fdtoverlays) { + if (!overlay->addr) + continue; + + blob = map_sysmem(overlay->addr, 0); err = fdt_check_header(blob); if (err) { - printf("Invalid overlay %s, skipping\n", overlayfile); + printf("Invalid overlay %s, skipping\n", overlay->path); continue; } err = fdt_overlay_apply_verbose(ctx->fdt, blob); if (err) printf("Failed to apply overlay %s, skipping\n", - overlayfile); - - /* Move to next address if using fixed addresses */ - if (!use_lmb) - fdtoverlay_addr = addr + size; + overlay->path); } } diff --git a/include/pxe_utils.h b/include/pxe_utils.h index 52a520e4823..d2062c03997 100644 --- a/include/pxe_utils.h +++ b/include/pxe_utils.h @@ -24,6 +24,17 @@ * take a 'include file getter' function. */ +/** + * struct pxe_fdtoverlay - info about an FDT overlay + * + * @path: Path to the overlay file + * @addr: Address where the overlay was loaded (0 if not yet loaded) + */ +struct pxe_fdtoverlay { + char *path; + ulong addr; +}; + /** * struct pxe_label - describes a single label in a pxe file * @@ -39,7 +50,7 @@ * @initrd: path to the initrd to use for this label. * @fdt: path to FDT to use * @fdtdir: path to FDT directory to use - * @fdtoverlays: list of paths of FDT overlays to apply (alist of char *) + * @fdtoverlays: list of FDT overlays to apply (alist of struct pxe_fdtoverlay) * @say: message to print when this label is selected for booting * @ipappend: flags for appending IP address (0x1) and MAC address (0x3) * @attempted: 0 if we haven't tried to boot this label, 1 if we have diff --git a/test/boot/pxe.c b/test/boot/pxe.c index 47cfa4042f5..df5c106caab 100644 --- a/test/boot/pxe.c +++ b/test/boot/pxe.c @@ -192,9 +192,9 @@ static int pxe_test_parse_norun(struct unit_test_state *uts) ut_assertnull(label->fdtdir); ut_asserteq(2, label->fdtoverlays.count); ut_asserteq_str("/dtb/overlay1.dtbo", - *alist_get(&label->fdtoverlays, 0, char *)); + alist_get(&label->fdtoverlays, 0, struct pxe_fdtoverlay)->path); ut_asserteq_str("/dtb/overlay2.dtbo", - *alist_get(&label->fdtoverlays, 1, char *)); + alist_get(&label->fdtoverlays, 1, struct pxe_fdtoverlay)->path); ut_asserteq_str("Booting default Linux kernel", label->say); ut_asserteq(0, label->ipappend); ut_asserteq(0, label->attempted);