@@ -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;
@@ -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
*
@@ -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();
@@ -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):