[Concept,10/26] boot: pxe: Use the files list instead of fdtoverlays

Message ID 20260110202906.187370-11-sjg@u-boot.org
State New
Headers
Series boot: pxe: Add three-phase API and fix memory leaks |

Commit Message

Simon Glass Jan. 10, 2026, 8:28 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Use the new files list for handling the FDT overlays, using the type
PFT_FDTOVERLAY. Add a helper function to check if any overlays exist
in the list, to preserve the existing behaviour of only adding new
overlays if not done already.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 boot/pxe_parse.c    | 33 ++++++++++++++++++++++++---------
 boot/pxe_utils.c    | 13 ++++++++-----
 include/pxe_utils.h |  2 --
 test/boot/pxe.c     | 26 +++++++++++++-------------
 4 files changed, 45 insertions(+), 29 deletions(-)
  

Patch

diff --git a/boot/pxe_parse.c b/boot/pxe_parse.c
index 29bee4d908c..b516da8f759 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, struct pxe_file);
+	alist_init_struct(&label->files, struct pxe_file);
 
 	return label;
 }
 
 void label_destroy(struct pxe_label *label)
 {
-	struct pxe_file *overlay;
+	struct pxe_file *file;
 
 	free(label->name);
 	free(label->menu);
@@ -124,9 +124,9 @@  void label_destroy(struct pxe_label *label)
 	free(label->initrd);
 	free(label->fdt);
 	free(label->fdtdir);
-	alist_for_each(overlay, &label->fdtoverlays)
-		free(overlay->path);
-	alist_uninit(&label->fdtoverlays);
+	alist_for_each(file, &label->files)
+		free(file->path);
+	alist_uninit(&label->files);
 	free(label->say);
 	free(label);
 }
@@ -312,10 +312,25 @@  static int parse_sliteral(char **c, char **dst)
 	return 1;
 }
 
+/*
+ * Check if a files list contains any FDT overlays.
+ */
+static bool has_fdtoverlays(struct alist *files)
+{
+	struct pxe_file *file;
+
+	alist_for_each(file, files) {
+		if (file->type == PFT_FDTOVERLAY)
+			return true;
+	}
+
+	return false;
+}
+
 /*
  * Parse a space-separated list of overlay paths into an alist.
  */
-static int parse_fdtoverlays(char **c, struct alist *overlays)
+static int parse_fdtoverlays(char **c, struct alist *files)
 {
 	char *val, *start;
 	int err;
@@ -349,7 +364,7 @@  static int parse_fdtoverlays(char **c, struct alist *overlays)
 		item.addr = 0;
 		item.size = 0;
 
-		if (!item.path || !alist_add(overlays, item)) {
+		if (!item.path || !alist_add(files, item)) {
 			free(item.path);
 			free(start);
 			return -ENOMEM;
@@ -589,8 +604,8 @@  static int parse_label(char **c, struct pxe_menu *cfg)
 				err = parse_sliteral(c, &label->fdtdir);
 			break;
 		case T_FDTOVERLAYS:
-			if (!label->fdtoverlays.count)
-				err = parse_fdtoverlays(c, &label->fdtoverlays);
+			if (!has_fdtoverlays(&label->files))
+				err = parse_fdtoverlays(c, &label->files);
 			break;
 		case T_LOCALBOOT:
 			label->localboot = 1;
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index b4bcba422b8..a2a2b986de1 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -327,11 +327,14 @@  static void label_load_fdtoverlays(struct pxe_context *ctx,
 		use_lmb = true;
 	}
 
-	alist_for_each(overlay, &label->fdtoverlays) {
+	alist_for_each(overlay, &label->files) {
 		ulong addr = fdtoverlay_addr;
 		ulong size;
 		int err;
 
+		if (overlay->type != PFT_FDTOVERLAY)
+			continue;
+
 		err = get_relfile(ctx, overlay->path, &addr, SZ_4K,
 				  (enum bootflow_img_t)IH_TYPE_FLATDT, &size);
 		if (err < 0) {
@@ -368,8 +371,8 @@  static void label_apply_fdtoverlays(struct pxe_context *ctx,
 	/* Resize main fdt to make room for overlays */
 	fdt_shrink_to_minimum(ctx->fdt, 8192);
 
-	alist_for_each(overlay, &label->fdtoverlays) {
-		if (!overlay->addr)
+	alist_for_each(overlay, &label->files) {
+		if (overlay->type != PFT_FDTOVERLAY || !overlay->addr)
 			continue;
 
 		blob = map_sysmem(overlay->addr, 0);
@@ -515,7 +518,7 @@  static int label_process_fdt(struct pxe_context *ctx, struct pxe_label *label)
 	if (label->kaslrseed)
 		label_boot_kaslrseed(ctx);
 
-	if (IS_ENABLED(CONFIG_OF_LIBFDT_OVERLAY) && label->fdtoverlays.count)
+	if (IS_ENABLED(CONFIG_OF_LIBFDT_OVERLAY) && label->files.count)
 		label_apply_fdtoverlays(ctx, label);
 
 	return 0;
@@ -679,7 +682,7 @@  int pxe_load_files(struct pxe_context *ctx, struct pxe_label *label,
 		}
 	}
 
-	if (IS_ENABLED(CONFIG_OF_LIBFDT_OVERLAY) && label->fdtoverlays.count)
+	if (IS_ENABLED(CONFIG_OF_LIBFDT_OVERLAY) && label->files.count)
 		label_load_fdtoverlays(ctx, label);
 
 	return 0;
diff --git a/include/pxe_utils.h b/include/pxe_utils.h
index 75437885dd3..266204b97ef 100644
--- a/include/pxe_utils.h
+++ b/include/pxe_utils.h
@@ -39,7 +39,6 @@ 
  * @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 FDT overlays to apply (alist of struct pxe_file)
  * @files: list of files to load (alist of struct pxe_file)
  * @say: message to print when this label is selected for booting
  * @ipappend: flags for appending IP address (0x1) and MAC address (0x3)
@@ -60,7 +59,6 @@  struct pxe_label {
 	char *initrd;
 	char *fdt;
 	char *fdtdir;
-	struct alist fdtoverlays;
 	struct alist files;
 	char *say;
 	int ipappend;
diff --git a/test/boot/pxe.c b/test/boot/pxe.c
index 260fc918592..df7cf2a781a 100644
--- a/test/boot/pxe.c
+++ b/test/boot/pxe.c
@@ -190,11 +190,11 @@  static int pxe_test_parse_norun(struct unit_test_state *uts)
 	ut_asserteq_str("/initrd.img", label->initrd);
 	ut_asserteq_str("/dtb/board.dtb", label->fdt);
 	ut_assertnull(label->fdtdir);
-	ut_asserteq(2, label->fdtoverlays.count);
+	ut_asserteq(2, label->files.count);
 	ut_asserteq_str("/dtb/overlay1.dtbo",
-			alist_get(&label->fdtoverlays, 0, struct pxe_file)->path);
+			alist_get(&label->files, 0, struct pxe_file)->path);
 	ut_asserteq_str("/dtb/overlay2.dtbo",
-			alist_get(&label->fdtoverlays, 1, struct pxe_file)->path);
+			alist_get(&label->files, 1, struct pxe_file)->path);
 	ut_asserteq_str("Booting default Linux kernel", label->say);
 	ut_asserteq(0, label->ipappend);
 	ut_asserteq(0, label->attempted);
@@ -214,7 +214,7 @@  static int pxe_test_parse_norun(struct unit_test_state *uts)
 	ut_assertnull(label->initrd);
 	ut_assertnull(label->fdt);
 	ut_asserteq_str("/dtb/", label->fdtdir);
-	ut_asserteq(0, label->fdtoverlays.count);
+	ut_asserteq(0, label->files.count);
 	ut_assertnull(label->say);
 	ut_asserteq(3, label->ipappend);
 	ut_asserteq(0, label->attempted);
@@ -234,7 +234,7 @@  static int pxe_test_parse_norun(struct unit_test_state *uts)
 	ut_assertnull(label->initrd);
 	ut_assertnull(label->fdt);
 	ut_assertnull(label->fdtdir);
-	ut_asserteq(0, label->fdtoverlays.count);
+	ut_asserteq(0, label->files.count);
 	ut_assertnull(label->say);
 	ut_asserteq(0, label->ipappend);
 	ut_asserteq(0, label->attempted);
@@ -254,7 +254,7 @@  static int pxe_test_parse_norun(struct unit_test_state *uts)
 	ut_assertnull(label->initrd);
 	ut_assertnull(label->fdt);
 	ut_assertnull(label->fdtdir);
-	ut_asserteq(0, label->fdtoverlays.count);
+	ut_asserteq(0, label->files.count);
 	ut_assertnull(label->say);
 	ut_asserteq(0, label->ipappend);
 	ut_asserteq(0, label->attempted);
@@ -274,7 +274,7 @@  static int pxe_test_parse_norun(struct unit_test_state *uts)
 	ut_assertnull(label->initrd);
 	ut_assertnull(label->fdt);
 	ut_assertnull(label->fdtdir);
-	ut_asserteq(0, label->fdtoverlays.count);
+	ut_asserteq(0, label->files.count);
 	ut_assertnull(label->say);
 	ut_asserteq(0, label->ipappend);
 	ut_asserteq(0, label->attempted);
@@ -296,7 +296,7 @@  static int pxe_test_parse_norun(struct unit_test_state *uts)
 	 * environment, and verify overlay files can be loaded.
 	 */
 	label = list_first_entry(&cfg->labels, struct pxe_label, list);
-	ut_asserteq(2, label->fdtoverlays.count);
+	ut_asserteq(2, label->files.count);
 
 	/* Set environment variables for file loading */
 	ut_assertok(env_set_hex("kernel_addr_r", PXE_KERNEL_ADDR));
@@ -316,14 +316,14 @@  static int pxe_test_parse_norun(struct unit_test_state *uts)
 	ut_asserteq(PXE_FDT_ADDR, ctx.fdt_addr);
 
 	/* Verify overlays were loaded to valid addresses */
-	ut_assert(alist_get(&label->fdtoverlays, 0,
+	ut_assert(alist_get(&label->files, 0,
 			    struct pxe_file)->addr >= PXE_OVERLAY_ADDR);
-	ut_assert(alist_get(&label->fdtoverlays, 1,
+	ut_assert(alist_get(&label->files, 1,
 			    struct pxe_file)->addr >= PXE_OVERLAY_ADDR);
 
 	/* Second overlay should be at a higher address than the first */
-	ut_assert(alist_get(&label->fdtoverlays, 1, struct pxe_file)->addr >
-		  alist_get(&label->fdtoverlays, 0, struct pxe_file)->addr);
+	ut_assert(alist_get(&label->files, 1, struct pxe_file)->addr >
+		  alist_get(&label->files, 0, struct pxe_file)->addr);
 
 	/* Verify no more console output */
 	ut_assert_console_end();
@@ -702,7 +702,7 @@  static int pxe_test_overlay_no_addr_norun(struct unit_test_state *uts)
 	/* Get the first label (linux) which has fdtoverlays */
 	label = list_first_entry(&cfg->labels, struct pxe_label, list);
 	ut_asserteq_str("linux", label->name);
-	ut_assert(label->fdtoverlays.count > 0);
+	ut_assert(label->files.count > 0);
 
 	/* Enable output for loading phase */
 	ctx.quiet = false;