]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
cmd: pxe: support INITRD and FDT selection with FIT
authorPatrick Delaunay <patrick.delaunay@foss.st.com>
Fri, 28 Oct 2022 09:01:19 +0000 (11:01 +0200)
committerTom Rini <trini@konsulko.com>
Mon, 12 Dec 2022 19:03:12 +0000 (14:03 -0500)
Since the commit d5ba6188dfbf ("cmd: pxe_utils: Check fdtcontroladdr
in label_boot") the FDT or the FDTDIR label is required in extlinux.conf
and the fallback done by bootm command when only the device tree present
in this command parameters is no more performed when FIT is used for
kernel.

When the label FDT or FDTDIR are absent or if the device tree file is
absent, the PXE command in U-Boot uses the default U-Boot device tree
selected by fdtcontroladdr = gd->fdt_blob, it is the "Scenario 3".

With this scenario the bootm FIP fallback is no more possible with
the extlinux.conf when only "kernel" label is present and is a FIP:

  kernel <path>#<conf>[#<extra-conf[#...]]

As the U-Boot FDT is always provided in the third bootm argument,
the device tree found in FIP is not used as fallback, it was done
previously in boot_get_fdt().

This patch adds a new field kernel_label to save the full kernel label.
The FDT bootm parameters use the kernel address (to avoid to load a
second time the same FIP) and the config when this full label is reused
for "fdt" or "initrd" label.

This FIP support in extlinux.conf is restored when the "FDT" label
can be found and select the same FIP (identical file and configuration):

  kernel <path>#<conf>[#<extra-conf[#...]]
  fdt <path>#<conf>[#<extra-conf[#...]]

The patch add also this possibility for initrd.

  initrd <path>#<conf>[#<extra-conf[#...]]

Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
boot/pxe_utils.c
doc/README.pxe
include/pxe_utils.h

index fc453bd53973050195bd6351a796c6ba23d5acdc..b59e959f715fdb8eac7b751686a6bf3ba060da05 100644 (file)
@@ -258,6 +258,7 @@ static struct pxe_label *label_create(void)
 static void label_destroy(struct pxe_label *label)
 {
        free(label->name);
+       free(label->kernel_label);
        free(label->kernel);
        free(label->config);
        free(label->append);
@@ -542,9 +543,11 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
                kernel_addr = fit_addr;
        }
 
-       if (label->initrd) {
+       /* For FIT, the label can be identical to kernel one */
+       if (label->initrd && !strcmp(label->kernel_label, label->initrd)) {
+               initrd_addr_str =  kernel_addr;
+       } else if (label->initrd) {
                ulong size;
-
                if (get_relfile_envaddr(ctx, label->initrd, "ramdisk_addr_r",
                                        &size) < 0) {
                        printf("Skipping %s for failure retrieving initrd\n",
@@ -622,8 +625,11 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
         */
        bootm_argv[3] = env_get("fdt_addr_r");
 
+       /* For FIT, the label can be identical to kernel one */
+       if (label->fdt && !strcmp(label->kernel_label, label->fdt)) {
+               bootm_argv[3] = kernel_addr;
        /* if fdt label is defined then get fdt from server */
-       if (bootm_argv[3]) {
+       } else if (bootm_argv[3]) {
                char *fdtfile = NULL;
                char *fdtfilefree = NULL;
 
@@ -1164,6 +1170,11 @@ static int parse_label_kernel(char **c, struct pxe_label *label)
        if (err < 0)
                return err;
 
+       /* copy the kernel label to compare with FDT / INITRD when FIT is used */
+       label->kernel_label = strdup(label->kernel);
+       if (!label->kernel_label)
+               return -ENOMEM;
+
        s = strstr(label->kernel, "#");
        if (!s)
                return 1;
index d14d2bdcc9b0b7d6e39a6edfcf5d8c4f13c87f65..172201093d0260325483e67f7a4e759d317ba7ad 100644 (file)
@@ -179,11 +179,19 @@ initrd <path>         - if this label is chosen, use tftp to retrieve the initrd
                      at <path>. it will be stored at the address indicated in
                      the initrd_addr_r environment variable, and that address
                      will be passed to bootm.
+                     For FIT image, the initrd can be provided with the same value than
+                     kernel, including configuration:
+                       <path>#<conf>[#<extra-conf[#...]]
+                     In this case, kernel_addr_r is passed to bootm.
 
 fdt <path>         - if this label is chosen, use tftp to retrieve the fdt blob
                      at <path>. it will be stored at the address indicated in
                      the fdt_addr_r environment variable, and that address will
                      be passed to bootm.
+                     For FIT image, the device tree can be provided with the same value
+                     than kernel, including configuration:
+                       <path>#<conf>[#<extra-conf[#...]]
+                     In this case, kernel_addr_r is passed to bootm.
 
 devicetree <path>   - if this label is chosen, use tftp to retrieve the fdt blob
                      at <path>. it will be stored at the address indicated in
index 4a73b2aace3420872a9d7800b896f7f450fba358..1e5e8424f53fb61c5119637434617dc423a2c8c5 100644 (file)
@@ -28,6 +28,7 @@
  * Create these with the 'label_create' function given below.
  *
  * name - the name of the menu as given on the 'menu label' line.
+ * kernel_label - the kernel label, including FIT config if present.
  * kernel - the path to the kernel file to use for this label.
  * append - kernel command line to use when booting this label
  * initrd - path to the initrd to use for this label.
@@ -40,6 +41,7 @@ struct pxe_label {
        char num[4];
        char *name;
        char *menu;
+       char *kernel_label;
        char *kernel;
        char *config;
        char *append;