cmd: pxe: add support for FIT config selection
authorPatrick Delaunay <patrick.delaunay@st.com>
Tue, 2 Oct 2018 08:54:48 +0000 (10:54 +0200)
committerTom Rini <trini@konsulko.com>
Mon, 8 Oct 2018 18:45:02 +0000 (14:45 -0400)
Add a way in configuration files (exlinux.conf for sysboot command)
to select a specific FIT configuration. The configuration is selected
with a string added after the FIT filename in the label "KERNEL" or
"LINUX", using the same format than bootm command:

KERNEL [Filename]#<conf>[#<extra-conf[#...]]

This configuration string, beginning by '#', is directly appended
to bootm argument 1 after <kernel_addr_r>.

bootm [<kernel_addr_r>]#<conf>[#<extra-conf[#...]]

see doc/uImage.FIT/command_syntax_extensions.txt for details

Example :
 KERNEL /fit.itb#cfg1
 KERNEL /fit.itb#cfg2

Configuration can be use also for overlay management :
 KERNEL /fit.itb#cfg1#dtbo1#dtbo3

see doc/uImage.FIT/overlay-fdt-boot.txt for details

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
cmd/pxe.c
doc/README.pxe

index 5609545de575d090b27f48fd0d2d2ee61b8bdc73..274555319ba8d8ab026e9600a8a23e9428281b15 100644 (file)
--- a/cmd/pxe.c
+++ b/cmd/pxe.c
@@ -471,6 +471,7 @@ struct pxe_label {
        char *name;
        char *menu;
        char *kernel;
+       char *config;
        char *append;
        char *initrd;
        char *fdt;
@@ -538,6 +539,9 @@ static void label_destroy(struct pxe_label *label)
        if (label->kernel)
                free(label->kernel);
 
+       if (label->config)
+               free(label->config);
+
        if (label->append)
                free(label->append);
 
@@ -618,6 +622,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
        char initrd_str[28];
        char mac_str[29] = "";
        char ip_str[68] = "";
+       char *fit_addr = NULL;
        int bootm_argc = 2;
        int len = 0;
        ulong kernel_addr;
@@ -699,6 +704,18 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
        }
 
        bootm_argv[1] = env_get("kernel_addr_r");
+       /* for FIT, append the configuration identifier */
+       if (label->config) {
+               int len = strlen(bootm_argv[1]) + strlen(label->config) + 1;
+
+               fit_addr = malloc(len);
+               if (!fit_addr) {
+                       printf("malloc fail (FIT address)\n");
+                       return 1;
+               }
+               snprintf(fit_addr, len, "%s%s", bootm_argv[1], label->config);
+               bootm_argv[1] = fit_addr;
+       }
 
        /*
         * fdt usage is optional:
@@ -758,7 +775,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
                        fdtfilefree = malloc(len);
                        if (!fdtfilefree) {
                                printf("malloc fail (FDT filename)\n");
-                               return 1;
+                               goto cleanup;
                        }
 
                        snprintf(fdtfilefree, len, "%s%s%s%s%s%s",
@@ -772,7 +789,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
                        if (err < 0) {
                                printf("Skipping %s for failure retrieving fdt\n",
                                                label->name);
-                               return 1;
+                               goto cleanup;
                        }
                } else {
                        bootm_argv[3] = NULL;
@@ -803,6 +820,10 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
                do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
 #endif
        unmap_sysmem(buf);
+
+cleanup:
+       if (fit_addr)
+               free(fit_addr);
        return 1;
 }
 
@@ -1187,6 +1208,33 @@ static int parse_label_menu(char **c, struct pxe_menu *cfg,
        return 0;
 }
 
+/*
+ * Handles parsing a 'kernel' label.
+ * expecting "filename" or "<fit_filename>#cfg"
+ */
+static int parse_label_kernel(char **c, struct pxe_label *label)
+{
+       char *s;
+       int err;
+
+       err = parse_sliteral(c, &label->kernel);
+       if (err < 0)
+               return err;
+
+       s = strstr(label->kernel, "#");
+       if (!s)
+               return 1;
+
+       label->config = malloc(strlen(s) + 1);
+       if (!label->config)
+               return -ENOMEM;
+
+       strcpy(label->config, s);
+       *s = 0;
+
+       return 1;
+}
+
 /*
  * Parses a label and adds it to the list of labels for a menu.
  *
@@ -1228,7 +1276,7 @@ static int parse_label(char **c, struct pxe_menu *cfg)
 
                case T_KERNEL:
                case T_LINUX:
-                       err = parse_sliteral(c, &label->kernel);
+                       err = parse_label_kernel(c, label);
                        break;
 
                case T_APPEND:
index 98862cdfdef480a85f4d79db41d229f8e86a1ac0..42f913c61feba1b61ccbf46e1c51fe0a34d64fe3 100644 (file)
@@ -140,6 +140,13 @@ kernel <path>          - if this label is chosen, use tftp to retrieve the kernel
                      (or FIT image) at <path>. it will be stored at the address
                      indicated in the kernel_addr_r environment variable, and
                      that address will be passed to bootm to boot this kernel.
+                     For FIT image, The configuration specification can be
+                     appended to the file name, with the format:
+                       <path>#<conf>[#<extra-conf[#...]]
+                     It will passed to bootm with that address.
+                     (see: doc/uImage.FIT/command_syntax_extensions.txt)
+                     It useful for overlay selection in pxe file
+                     (see: doc/uImage.FIT/overlay-fdt-boot.txt)
 
 append <string>            - use <string> as the kernel command line when booting this
                      label.