[Concept,30/32] boot: pxe: Add test for FDT overlay loading

Message ID 20260109231151.4056804-31-sjg@u-boot.org
State New
Headers
Series boot: pxe: Refactor into separate load/setup phases |

Commit Message

Simon Glass Jan. 9, 2026, 11:11 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Extend the PXE parser test to verify that FDT overlays can be loaded.
This tests the label_load_fdtoverlays() function by:

1. Creating real DTB and DTBO files in the Python test fixture using dtc
2. Creating dummy kernel/initrd files for loading tests
3. Setting up environment variables for file loading addresses
4. Calling pxe_load_files() to load all files including overlays
5. Verifying overlay addresses are set and sequential

Make pxe_load_files() a public function so it can be called from
tests to verify file loading without the full boot setup.

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

 boot/pxe_utils.c                 |  4 ++--
 include/pxe_utils.h              | 16 ++++++++++++++
 test/boot/pxe.c                  | 36 ++++++++++++++++++++++++++++++++
 test/py/tests/test_pxe_parser.py |  9 ++++++++
 4 files changed, 63 insertions(+), 2 deletions(-)
  

Patch

diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index e336b125716..8609d832aa6 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -627,8 +627,8 @@  static int generate_localboot(struct pxe_label *label)
 	return 0;
 }
 
-static int pxe_load_files(struct pxe_context *ctx, struct pxe_label *label,
-			  char *fdtfile)
+int pxe_load_files(struct pxe_context *ctx, struct pxe_label *label,
+		   char *fdtfile)
 {
 	int ret;
 
diff --git a/include/pxe_utils.h b/include/pxe_utils.h
index d2062c03997..aa73f5ff7f0 100644
--- a/include/pxe_utils.h
+++ b/include/pxe_utils.h
@@ -445,6 +445,22 @@  int pxe_do_boot(struct pxe_context *ctx);
 int pxe_select_label(struct pxe_menu *cfg, bool prompt,
 		     struct pxe_label **labelp);
 
+/**
+ * pxe_load_files() - Load kernel/initrd/FDT/overlays for a label
+ *
+ * Loads the files specified in the label into memory and saves the
+ * addresses in @ctx. This does not process the FDT or set up boot
+ * parameters - use pxe_load_label() for that.
+ *
+ * @ctx: PXE context with getfile callback
+ * @label: Label whose files to load
+ * @fdtfile: Path to FDT file (may be NULL)
+ * Return: 0 on success, -ENOENT if no kernel specified, -EIO if file
+ *	retrieval failed
+ */
+int pxe_load_files(struct pxe_context *ctx, struct pxe_label *label,
+		   char *fdtfile);
+
 /**
  * pxe_load_label() - Load kernel/initrd/FDT for a label
  *
diff --git a/test/boot/pxe.c b/test/boot/pxe.c
index df5c106caab..97049e27ab6 100644
--- a/test/boot/pxe.c
+++ b/test/boot/pxe.c
@@ -289,6 +289,42 @@  static int pxe_test_parse_norun(struct unit_test_state *uts)
 		ut_asserteq_str(name, label->name);
 	}
 
+	/*
+	 * Test FDT overlay loading
+	 *
+	 * Get the first label (linux) which has fdtoverlays, set up the
+	 * environment, and verify overlay files can be loaded.
+	 */
+	label = list_first_entry(&cfg->labels, struct pxe_label, list);
+	ut_asserteq(2, label->fdtoverlays.count);
+
+	/* Set environment variables for file loading */
+	ut_assertok(env_set_hex("kernel_addr_r", PXE_KERNEL_ADDR));
+	ut_assertok(env_set_hex("ramdisk_addr_r", PXE_INITRD_ADDR));
+	ut_assertok(env_set_hex("fdt_addr_r", PXE_FDT_ADDR));
+	ut_assertok(env_set_hex("fdtoverlay_addr_r", PXE_OVERLAY_ADDR));
+
+	/*
+	 * Load files via pxe_load_files(). Note: pxe_load_files takes
+	 * ownership of fdtfile and frees it, so we must strdup here.
+	 */
+	ret = pxe_load_files(&ctx, label, strdup(label->fdt));
+	ut_assertok(ret);
+
+	/* Verify kernel and FDT were loaded */
+	ut_asserteq(PXE_KERNEL_ADDR, ctx.kern_addr);
+	ut_asserteq(PXE_FDT_ADDR, ctx.fdt_addr);
+
+	/* Verify overlays were loaded to valid addresses */
+	ut_assert(alist_get(&label->fdtoverlays, 0,
+			    struct pxe_fdtoverlay)->addr >= PXE_OVERLAY_ADDR);
+	ut_assert(alist_get(&label->fdtoverlays, 1,
+			    struct pxe_fdtoverlay)->addr >= PXE_OVERLAY_ADDR);
+
+	/* Second overlay should be at a higher address than the first */
+	ut_assert(alist_get(&label->fdtoverlays, 1, struct pxe_fdtoverlay)->addr >
+		  alist_get(&label->fdtoverlays, 0, struct pxe_fdtoverlay)->addr);
+
 	/* Verify no more console output */
 	ut_assert_console_end();
 
diff --git a/test/py/tests/test_pxe_parser.py b/test/py/tests/test_pxe_parser.py
index af97568e960..bbcd63d58e2 100644
--- a/test/py/tests/test_pxe_parser.py
+++ b/test/py/tests/test_pxe_parser.py
@@ -233,6 +233,15 @@  def pxe_image(u_boot_config):
 
     cfg_path = create_extlinux_conf(fsh.srcdir, labels, menu_opts)
 
+    # Create DTB and overlay files for testing
+    dtbdir = os.path.join(fsh.srcdir, 'dtb')
+    os.makedirs(dtbdir, exist_ok=True)
+    compile_dts(BASE_DTS, os.path.join(dtbdir, 'board.dtb'))
+    compile_dts(OVERLAY1_DTS, os.path.join(dtbdir, 'overlay1.dtbo'),
+                is_overlay=True)
+    compile_dts(OVERLAY2_DTS, os.path.join(dtbdir, 'overlay2.dtbo'),
+                is_overlay=True)
+
     # Create a chain of 16 nested include files to test MAX_NEST_LEVEL
     # Level 1 is extlinux.conf, levels 2-16 are extra.conf, nest3.conf, etc.
     for level in range(2, 17):