177 lines
4.5 KiB
Diff
177 lines
4.5 KiB
Diff
From 13b5a55b02e80735288d90f3d098b08fe8f10a10 Mon Sep 17 00:00:00 2001
|
|
From: Stephen Warren <swarren@nvidia.com>
|
|
Date: Tue, 28 Jan 2014 21:50:10 -0700
|
|
Subject: [PATCH 02/13] pxe: implement fdtdir extlinux.conf tag
|
|
|
|
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>
|
|
---
|
|
common/cmd_pxe.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
|
|
1 file changed, 72 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c
|
|
index 4f00b1a..2bd572d 100644
|
|
--- a/common/cmd_pxe.c
|
|
+++ b/common/cmd_pxe.c
|
|
@@ -445,6 +445,7 @@ struct pxe_label {
|
|
char *append;
|
|
char *initrd;
|
|
char *fdt;
|
|
+ char *fdtdir;
|
|
int ipappend;
|
|
int attempted;
|
|
int localboot;
|
|
@@ -517,6 +518,9 @@ static void label_destroy(struct pxe_label *label)
|
|
if (label->fdt)
|
|
free(label->fdt);
|
|
|
|
+ if (label->fdtdir)
|
|
+ free(label->fdtdir);
|
|
+
|
|
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");
|
|
|
|
/* if fdt label is defined then get fdt from server */
|
|
- if (bootm_argv[3] && label->fdt) {
|
|
- if (get_relfile_envaddr(cmdtp, label->fdt, "fdt_addr_r") < 0) {
|
|
- printf("Skipping %s for failure retrieving fdt\n",
|
|
- label->name);
|
|
- return 1;
|
|
+ if (bootm_argv[3]) {
|
|
+ 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;
|
|
+ }
|
|
}
|
|
- } else
|
|
+
|
|
+ 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",
|
|
+ label->name);
|
|
+ return 1;
|
|
+ }
|
|
+ } else {
|
|
+ bootm_argv[3] = NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!bootm_argv[3])
|
|
bootm_argv[3] = getenv("fdt_addr");
|
|
|
|
if (bootm_argv[3])
|
|
@@ -716,6 +774,7 @@ enum token_type {
|
|
T_PROMPT,
|
|
T_INCLUDE,
|
|
T_FDT,
|
|
+ T_FDTDIR,
|
|
T_ONTIMEOUT,
|
|
T_IPAPPEND,
|
|
T_INVALID
|
|
@@ -747,6 +806,8 @@ static const struct token keywords[] = {
|
|
{"include", T_INCLUDE},
|
|
{"devicetree", T_FDT},
|
|
{"fdt", T_FDT},
|
|
+ {"devicetreedir", T_FDTDIR},
|
|
+ {"fdtdir", T_FDTDIR},
|
|
{"ontimeout", T_ONTIMEOUT,},
|
|
{"ipappend", T_IPAPPEND,},
|
|
{NULL, T_INVALID}
|
|
@@ -1135,6 +1196,11 @@ static int parse_label(char **c, struct pxe_menu *cfg)
|
|
err = parse_sliteral(c, &label->fdt);
|
|
break;
|
|
|
|
+ case T_FDTDIR:
|
|
+ if (!label->fdtdir)
|
|
+ err = parse_sliteral(c, &label->fdtdir);
|
|
+ break;
|
|
+
|
|
case T_LOCALBOOT:
|
|
label->localboot = 1;
|
|
err = parse_integer(c, &label->localboot_val);
|
|
--
|
|
1.8.5.3
|
|
|