Created
May 27, 2022 15:41
-
-
Save RobertCNelson/a5d52932481d1f9c090ac1cf551716bd to your computer and use it in GitHub Desktop.
u-boot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/cmd/pxe_utils.c b/cmd/pxe_utils.c | |
| index 8716e782f6..25367190a7 100644 | |
| --- a/cmd/pxe_utils.c | |
| +++ b/cmd/pxe_utils.c | |
| @@ -13,6 +13,8 @@ | |
| #include <mapmem.h> | |
| #include <lcd.h> | |
| #include <net.h> | |
| +#include <fdt_support.h> | |
| +#include <linux/libfdt.h> | |
| #include <linux/string.h> | |
| #include <linux/ctype.h> | |
| #include <errno.h> | |
| @@ -284,6 +286,9 @@ static void label_destroy(struct pxe_label *label) | |
| if (label->fdtdir) | |
| free(label->fdtdir); | |
| + if (label->fdtoverlays) | |
| + free(label->fdtoverlays); | |
| + | |
| free(label); | |
| } | |
| @@ -331,6 +336,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(struct cmd_tbl *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. | |
| * | |
| @@ -525,6 +616,11 @@ static int label_boot(struct cmd_tbl *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; | |
| } | |
| @@ -582,6 +678,7 @@ enum token_type { | |
| T_INCLUDE, | |
| T_FDT, | |
| T_FDTDIR, | |
| + T_FDTOVERLAYS, | |
| T_ONTIMEOUT, | |
| T_IPAPPEND, | |
| T_BACKGROUND, | |
| @@ -616,6 +713,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,}, | |
| @@ -1048,6 +1146,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); | |
| diff --git a/cmd/pxe_utils.h b/cmd/pxe_utils.h | |
| index 77d2588875..6af9523734 100644 | |
| --- a/cmd/pxe_utils.h | |
| +++ b/cmd/pxe_utils.h | |
| @@ -43,6 +43,7 @@ struct pxe_label { | |
| char *initrd; | |
| char *fdt; | |
| char *fdtdir; | |
| + char *fdtoverlays; | |
| int ipappend; | |
| int attempted; | |
| int localboot; | |
| diff --git a/doc/README.pxe b/doc/README.pxe | |
| index 42f913c61f..b67151ca51 100644 | |
| --- a/doc/README.pxe | |
| +++ b/doc/README.pxe | |
| @@ -89,6 +89,9 @@ pxe boot | |
| fdt_addr - the location of a fdt blob. 'fdt_addr' will be passed to bootm | |
| command if it is set and 'fdt_addr_r' is not passed to bootm command. | |
| + fdtoverlay_addr_r - location in RAM at which 'pxe boot' will temporarily store | |
| + fdt overlay(s) before applying them to the fdt blob stored at 'fdt_addr_r'. | |
| + | |
| pxe file format | |
| =============== | |
| The pxe file format is nearly a subset of the PXELINUX file format; see | |
| @@ -148,6 +151,12 @@ kernel <path> - if this label is chosen, use tftp to retrieve the kernel | |
| It useful for overlay selection in pxe file | |
| (see: doc/uImage.FIT/overlay-fdt-boot.txt) | |
| +fdtoverlays <path> [...] - if this label is chosen, use tftp to retrieve the DT | |
| + overlay(s) at <path>. it will be temporarily stored at the | |
| + address indicated in the fdtoverlay_addr_r environment variable, | |
| + and then applied in the load order to the fdt blob stored at the | |
| + address indicated in the fdt_addr_r environment variable. | |
| + | |
| append <string> - use <string> as the kernel command line when booting this | |
| label. | |
| diff --git a/include/configs/ti_armv7_common.h b/include/configs/ti_armv7_common.h | |
| index 0c9856a11a..c48c4c2398 100644 | |
| --- a/include/configs/ti_armv7_common.h | |
| +++ b/include/configs/ti_armv7_common.h | |
| @@ -54,6 +54,7 @@ | |
| "ramdisk_addr_r=0x88080000\0" \ | |
| "scriptaddr=0x80000000\0" \ | |
| "pxefile_addr_r=0x80100000\0" \ | |
| + "fdtoverlay_addr_r=0x80200000\0" \ | |
| "bootm_size=0x10000000\0" \ | |
| "boot_fdt=try\0" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment