Hi Tom. Is there someone who can review this ? or should I resent without RFC ?
Thanks, Neil On 07/05/2019 14:50, Neil Armstrong wrote: > This adds support for specicyinf FDT overlays in an extlinux/pxelinux > configuration file. > > Without this, there is no simple way to apply overlays when the kernel > and ftd is loaded by the pxe command. > > This change adds the 'fdtoverlays' keyword for a label, supporting multiple > overlay files to be applied on top of the fdt specific in the 'fdt' or > 'devicetree' keyword. > > Cc: Jernej Škrabec <[email protected]> > Cc: Jonas Karlman <[email protected]> > Signed-off-by: Neil Armstrong <[email protected]> > --- > cmd/pxe.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 104 insertions(+) > > diff --git a/cmd/pxe.c b/cmd/pxe.c > index 1dd0a74ea3..8d19e6f99f 100644 > --- a/cmd/pxe.c > +++ b/cmd/pxe.c > @@ -13,6 +13,8 @@ > #include <linux/ctype.h> > #include <errno.h> > #include <linux/list.h> > +#include <fdt_support.h> > +#include <linux/libfdt.h> > #include <fs.h> > #include <splash.h> > #include <asm/io.h> > @@ -481,6 +483,7 @@ struct pxe_label { > char *initrd; > char *fdt; > char *fdtdir; > + char *fdtoverlays; > int ipappend; > int attempted; > int localboot; > @@ -561,6 +564,9 @@ static void label_destroy(struct pxe_label *label) > if (label->fdtdir) > free(label->fdtdir); > > + if (label->fdtoverlays) > + free(label->fdtoverlays); > + > free(label); > } > > @@ -608,6 +614,92 @@ static int label_localboot(struct pxe_label *label) > return run_command_list(localcmd, strlen(localcmd), 0); > } > > +/* > + * Loads fdt overlays specified in 'fdtoverlays'. > + */ > +#ifdef CONFIG_OF_LIBFDT_OVERLAY > +static void label_boot_fdtoverlay(cmd_tbl_t *cmdtp, struct pxe_label *label) > +{ > + char *fdtoverlay = label->fdtoverlays; > + struct fdt_header *working_fdt; > + char *fdtoverlay_addr_env; > + ulong fdtoverlay_addr; > + ulong fdt_addr; > + int err; > + > + /* Get the main fdt and map it */ > + fdt_addr = simple_strtoul(env_get("fdt_addr_r"), NULL, 16); > + working_fdt = map_sysmem(fdt_addr, 0); > + err = fdt_check_header(working_fdt); > + if (err) > + return; > + > + /* Get the specific overlay loading address */ > + fdtoverlay_addr_env = env_get("fdtoverlay_addr_r"); > + if (!fdtoverlay_addr_env) { > + printf("Invalid fdtoverlay_addr_r for loading overlays\n"); > + return; > + } > + > + fdtoverlay_addr = simple_strtoul(fdtoverlay_addr_env, NULL, 16); > + > + /* Cycle over the overlay files and apply them in order */ > + do { > + struct fdt_header *blob; > + char *overlayfile; > + char *end; > + int len; > + > + /* Drop leading spaces */ > + while (*fdtoverlay == ' ') > + ++fdtoverlay; > + > + /* Copy a single filename if multiple provided */ > + end = strstr(fdtoverlay, " "); > + if (end) { > + len = (int)(end - fdtoverlay); > + overlayfile = malloc(len + 1); > + strncpy(overlayfile, fdtoverlay, len); > + overlayfile[len] = '\0'; > + } else > + overlayfile = fdtoverlay; > + > + if (!strlen(overlayfile)) > + goto skip_overlay; > + > + /* Load overlay file */ > + err = get_relfile_envaddr(cmdtp, overlayfile, > + "fdtoverlay_addr_r"); > + if (err < 0) { > + printf("Failed loading overlay %s\n", overlayfile); > + goto skip_overlay; > + } > + > + /* Resize main fdt */ > + fdt_shrink_to_minimum(working_fdt, 8192); > + > + blob = map_sysmem(fdtoverlay_addr, 0); > + err = fdt_check_header(blob); > + if (err) { > + printf("Invalid overlay %s, skipping\n", > + overlayfile); > + goto skip_overlay; > + } > + > + err = fdt_overlay_apply_verbose(working_fdt, blob); > + if (err) { > + printf("Failed to apply overlay %s, skipping\n", > + overlayfile); > + goto skip_overlay; > + } > + > +skip_overlay: > + if (end) > + free(overlayfile); > + } while ((fdtoverlay = strstr(fdtoverlay, " "))); > +} > +#endif > + > /* > * Boot according to the contents of a pxe_label. > * > @@ -798,6 +890,11 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label > *label) > label->name); > goto cleanup; > } > + > +#ifdef CONFIG_OF_LIBFDT_OVERLAY > + if (label->fdtoverlays) > + label_boot_fdtoverlay(cmdtp, label); > +#endif > } else { > bootm_argv[3] = NULL; > } > @@ -855,6 +952,7 @@ enum token_type { > T_INCLUDE, > T_FDT, > T_FDTDIR, > + T_FDTOVERLAYS, > T_ONTIMEOUT, > T_IPAPPEND, > T_BACKGROUND, > @@ -889,6 +987,7 @@ static const struct token keywords[] = { > {"fdt", T_FDT}, > {"devicetreedir", T_FDTDIR}, > {"fdtdir", T_FDTDIR}, > + {"fdtoverlays", T_FDTOVERLAYS}, > {"ontimeout", T_ONTIMEOUT,}, > {"ipappend", T_IPAPPEND,}, > {"background", T_BACKGROUND,}, > @@ -1322,6 +1421,11 @@ static int parse_label(char **c, struct pxe_menu *cfg) > err = parse_sliteral(c, &label->fdtdir); > break; > > + case T_FDTOVERLAYS: > + if (!label->fdtoverlays) > + err = parse_sliteral(c, &label->fdtoverlays); > + break; > + > case T_LOCALBOOT: > label->localboot = 1; > err = parse_integer(c, &label->localboot_val); > _______________________________________________ U-Boot mailing list [email protected] https://lists.denx.de/listinfo/u-boot

