Commit c61d94d86035ab2165aedf208b8f3c768b277a3d
Committed by
Tom Rini
1 parent
f43c401b72
Exists in
master
and in
49 other branches
pxe: implement fdtdir extlinux.conf tag
People who write (or scripts that auto-generate) extlinux.conf don't want to know about HW-specific information such as FDT filenames. Create a new extlinux.conf tag "fdtdir" that specifies only the directory where FDT files are located, and defer all knowledge of the filename to U-Boot. The algorithm implemented is: ========== if $fdt_addr_r is set: if "fdt" tag was specified in extlinux.conf: load the FDT from the filename in the tag else if "fdtdir" tag was specified in extlinux.conf: if "fdtfile" is set in the environment: load the FDT from filename in "$fdtfile" else: load the FDT from some automatically generated filename if no FDT file was loaded, and $fdtaddr is set: # This indicates an FDT packaged with firmware use the FDT at $fdtaddr ========== A small part of an example /boot/extlinux.conf might be: ========== LABEL primary LINUX zImage FDTDIR ./ LABEL failsafe LINUX bkp/zImage FDTDIR bkp/ ========== ... with /boot/tegra20-seaboard.dtb or /boot/bkp/tegra20-seaboard.dtb being loaded by the sysboot/pxe code. Signed-off-by: Stephen Warren <swarren@nvidia.com>
Showing 1 changed file with 72 additions and 6 deletions Side-by-side Diff
common/cmd_pxe.c
... | ... | @@ -445,6 +445,7 @@ |
445 | 445 | char *append; |
446 | 446 | char *initrd; |
447 | 447 | char *fdt; |
448 | + char *fdtdir; | |
448 | 449 | int ipappend; |
449 | 450 | int attempted; |
450 | 451 | int localboot; |
... | ... | @@ -517,6 +518,9 @@ |
517 | 518 | if (label->fdt) |
518 | 519 | free(label->fdt); |
519 | 520 | |
521 | + if (label->fdtdir) | |
522 | + free(label->fdtdir); | |
523 | + | |
520 | 524 | free(label); |
521 | 525 | } |
522 | 526 | |
523 | 527 | |
... | ... | @@ -675,13 +679,67 @@ |
675 | 679 | bootm_argv[3] = getenv("fdt_addr_r"); |
676 | 680 | |
677 | 681 | /* if fdt label is defined then get fdt from server */ |
678 | - if (bootm_argv[3] && label->fdt) { | |
679 | - if (get_relfile_envaddr(cmdtp, label->fdt, "fdt_addr_r") < 0) { | |
680 | - printf("Skipping %s for failure retrieving fdt\n", | |
681 | - label->name); | |
682 | - return 1; | |
682 | + if (bootm_argv[3]) { | |
683 | + char *fdtfile = NULL; | |
684 | + char *fdtfilefree = NULL; | |
685 | + | |
686 | + if (label->fdt) { | |
687 | + fdtfile = label->fdt; | |
688 | + } else if (label->fdtdir) { | |
689 | + fdtfile = getenv("fdtfile"); | |
690 | + /* | |
691 | + * For complex cases, it might be worth calling a | |
692 | + * board- or SoC-provided function here to provide a | |
693 | + * better default: | |
694 | + * | |
695 | + * if (!fdtfile) | |
696 | + * fdtfile = gen_fdtfile(); | |
697 | + * | |
698 | + * If this is added, be sure to keep the default below, | |
699 | + * or move it to the default weak implementation of | |
700 | + * gen_fdtfile(). | |
701 | + */ | |
702 | + if (!fdtfile) { | |
703 | + char *soc = getenv("soc"); | |
704 | + char *board = getenv("board"); | |
705 | + char *slash; | |
706 | + | |
707 | + len = strlen(label->fdtdir); | |
708 | + if (!len) | |
709 | + slash = "./"; | |
710 | + else if (label->fdtdir[len - 1] != '/') | |
711 | + slash = "/"; | |
712 | + else | |
713 | + slash = ""; | |
714 | + | |
715 | + len = strlen(label->fdtdir) + strlen(slash) + | |
716 | + strlen(soc) + 1 + strlen(board) + 5; | |
717 | + fdtfilefree = malloc(len); | |
718 | + if (!fdtfilefree) { | |
719 | + printf("malloc fail (FDT filename)\n"); | |
720 | + return 1; | |
721 | + } | |
722 | + | |
723 | + snprintf(fdtfilefree, len, "%s%s%s-%s.dtb", | |
724 | + label->fdtdir, slash, soc, board); | |
725 | + fdtfile = fdtfilefree; | |
726 | + } | |
683 | 727 | } |
684 | - } else | |
728 | + | |
729 | + if (fdtfile) { | |
730 | + int err = get_relfile_envaddr(cmdtp, fdtfile, "fdt_addr_r"); | |
731 | + free(fdtfilefree); | |
732 | + if (err < 0) { | |
733 | + printf("Skipping %s for failure retrieving fdt\n", | |
734 | + label->name); | |
735 | + return 1; | |
736 | + } | |
737 | + } else { | |
738 | + bootm_argv[3] = NULL; | |
739 | + } | |
740 | + } | |
741 | + | |
742 | + if (!bootm_argv[3]) | |
685 | 743 | bootm_argv[3] = getenv("fdt_addr"); |
686 | 744 | |
687 | 745 | if (bootm_argv[3]) |
... | ... | @@ -716,6 +774,7 @@ |
716 | 774 | T_PROMPT, |
717 | 775 | T_INCLUDE, |
718 | 776 | T_FDT, |
777 | + T_FDTDIR, | |
719 | 778 | T_ONTIMEOUT, |
720 | 779 | T_IPAPPEND, |
721 | 780 | T_INVALID |
... | ... | @@ -747,6 +806,8 @@ |
747 | 806 | {"include", T_INCLUDE}, |
748 | 807 | {"devicetree", T_FDT}, |
749 | 808 | {"fdt", T_FDT}, |
809 | + {"devicetreedir", T_FDTDIR}, | |
810 | + {"fdtdir", T_FDTDIR}, | |
750 | 811 | {"ontimeout", T_ONTIMEOUT,}, |
751 | 812 | {"ipappend", T_IPAPPEND,}, |
752 | 813 | {NULL, T_INVALID} |
... | ... | @@ -1133,6 +1194,11 @@ |
1133 | 1194 | case T_FDT: |
1134 | 1195 | if (!label->fdt) |
1135 | 1196 | err = parse_sliteral(c, &label->fdt); |
1197 | + break; | |
1198 | + | |
1199 | + case T_FDTDIR: | |
1200 | + if (!label->fdtdir) | |
1201 | + err = parse_sliteral(c, &label->fdtdir); | |
1136 | 1202 | break; |
1137 | 1203 | |
1138 | 1204 | case T_LOCALBOOT: |