@@ -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;
}
}
@@ -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);
}
}
@@ -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
@@ -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);