mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-19 21:51:31 +00:00
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>
This commit is contained in:
parent
f43c401b72
commit
c61d94d860
1 changed files with 72 additions and 6 deletions
|
@ -445,6 +445,7 @@ struct pxe_label {
|
||||||
char *append;
|
char *append;
|
||||||
char *initrd;
|
char *initrd;
|
||||||
char *fdt;
|
char *fdt;
|
||||||
|
char *fdtdir;
|
||||||
int ipappend;
|
int ipappend;
|
||||||
int attempted;
|
int attempted;
|
||||||
int localboot;
|
int localboot;
|
||||||
|
@ -517,6 +518,9 @@ static void label_destroy(struct pxe_label *label)
|
||||||
if (label->fdt)
|
if (label->fdt)
|
||||||
free(label->fdt);
|
free(label->fdt);
|
||||||
|
|
||||||
|
if (label->fdtdir)
|
||||||
|
free(label->fdtdir);
|
||||||
|
|
||||||
free(label);
|
free(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,13 +679,67 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
|
||||||
bootm_argv[3] = getenv("fdt_addr_r");
|
bootm_argv[3] = getenv("fdt_addr_r");
|
||||||
|
|
||||||
/* if fdt label is defined then get fdt from server */
|
/* if fdt label is defined then get fdt from server */
|
||||||
if (bootm_argv[3] && label->fdt) {
|
if (bootm_argv[3]) {
|
||||||
if (get_relfile_envaddr(cmdtp, label->fdt, "fdt_addr_r") < 0) {
|
char *fdtfile = NULL;
|
||||||
|
char *fdtfilefree = NULL;
|
||||||
|
|
||||||
|
if (label->fdt) {
|
||||||
|
fdtfile = label->fdt;
|
||||||
|
} else if (label->fdtdir) {
|
||||||
|
fdtfile = getenv("fdtfile");
|
||||||
|
/*
|
||||||
|
* For complex cases, it might be worth calling a
|
||||||
|
* board- or SoC-provided function here to provide a
|
||||||
|
* better default:
|
||||||
|
*
|
||||||
|
* if (!fdtfile)
|
||||||
|
* fdtfile = gen_fdtfile();
|
||||||
|
*
|
||||||
|
* If this is added, be sure to keep the default below,
|
||||||
|
* or move it to the default weak implementation of
|
||||||
|
* gen_fdtfile().
|
||||||
|
*/
|
||||||
|
if (!fdtfile) {
|
||||||
|
char *soc = getenv("soc");
|
||||||
|
char *board = getenv("board");
|
||||||
|
char *slash;
|
||||||
|
|
||||||
|
len = strlen(label->fdtdir);
|
||||||
|
if (!len)
|
||||||
|
slash = "./";
|
||||||
|
else if (label->fdtdir[len - 1] != '/')
|
||||||
|
slash = "/";
|
||||||
|
else
|
||||||
|
slash = "";
|
||||||
|
|
||||||
|
len = strlen(label->fdtdir) + strlen(slash) +
|
||||||
|
strlen(soc) + 1 + strlen(board) + 5;
|
||||||
|
fdtfilefree = malloc(len);
|
||||||
|
if (!fdtfilefree) {
|
||||||
|
printf("malloc fail (FDT filename)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(fdtfilefree, len, "%s%s%s-%s.dtb",
|
||||||
|
label->fdtdir, slash, soc, board);
|
||||||
|
fdtfile = fdtfilefree;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fdtfile) {
|
||||||
|
int err = get_relfile_envaddr(cmdtp, fdtfile, "fdt_addr_r");
|
||||||
|
free(fdtfilefree);
|
||||||
|
if (err < 0) {
|
||||||
printf("Skipping %s for failure retrieving fdt\n",
|
printf("Skipping %s for failure retrieving fdt\n",
|
||||||
label->name);
|
label->name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
|
bootm_argv[3] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bootm_argv[3])
|
||||||
bootm_argv[3] = getenv("fdt_addr");
|
bootm_argv[3] = getenv("fdt_addr");
|
||||||
|
|
||||||
if (bootm_argv[3])
|
if (bootm_argv[3])
|
||||||
|
@ -716,6 +774,7 @@ enum token_type {
|
||||||
T_PROMPT,
|
T_PROMPT,
|
||||||
T_INCLUDE,
|
T_INCLUDE,
|
||||||
T_FDT,
|
T_FDT,
|
||||||
|
T_FDTDIR,
|
||||||
T_ONTIMEOUT,
|
T_ONTIMEOUT,
|
||||||
T_IPAPPEND,
|
T_IPAPPEND,
|
||||||
T_INVALID
|
T_INVALID
|
||||||
|
@ -747,6 +806,8 @@ static const struct token keywords[] = {
|
||||||
{"include", T_INCLUDE},
|
{"include", T_INCLUDE},
|
||||||
{"devicetree", T_FDT},
|
{"devicetree", T_FDT},
|
||||||
{"fdt", T_FDT},
|
{"fdt", T_FDT},
|
||||||
|
{"devicetreedir", T_FDTDIR},
|
||||||
|
{"fdtdir", T_FDTDIR},
|
||||||
{"ontimeout", T_ONTIMEOUT,},
|
{"ontimeout", T_ONTIMEOUT,},
|
||||||
{"ipappend", T_IPAPPEND,},
|
{"ipappend", T_IPAPPEND,},
|
||||||
{NULL, T_INVALID}
|
{NULL, T_INVALID}
|
||||||
|
@ -1135,6 +1196,11 @@ static int parse_label(char **c, struct pxe_menu *cfg)
|
||||||
err = parse_sliteral(c, &label->fdt);
|
err = parse_sliteral(c, &label->fdt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_FDTDIR:
|
||||||
|
if (!label->fdtdir)
|
||||||
|
err = parse_sliteral(c, &label->fdtdir);
|
||||||
|
break;
|
||||||
|
|
||||||
case T_LOCALBOOT:
|
case T_LOCALBOOT:
|
||||||
label->localboot = 1;
|
label->localboot = 1;
|
||||||
err = parse_integer(c, &label->localboot_val);
|
err = parse_integer(c, &label->localboot_val);
|
||||||
|
|
Loading…
Add table
Reference in a new issue