diff --git a/cmd/pxe.c b/cmd/pxe.c index 5609545..2745553 100644 --- 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; } @@ -1188,6 +1209,33 @@ static int parse_label_menu(char **c, struct pxe_menu *cfg, } /* + * Handles parsing a 'kernel' label. + * expecting "filename" or "#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. * * A label ends when we either get to the end of a file, or @@ -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: diff --git a/doc/README.pxe b/doc/README.pxe index 98862cd..42f913c 100644 --- a/doc/README.pxe +++ b/doc/README.pxe @@ -140,6 +140,13 @@ kernel - if this label is chosen, use tftp to retrieve the kernel (or FIT image) at . 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: + #[# - use as the kernel command line when booting this label.