[PATCH v4 45/46] pxe_utils: Refactor to separate reading from booting

It is useful to be able to select a bootflow and read its images, without actually doing the boot. This allows adjusting the bootargs, for example.
Provide support for this in the pxe_utils module, by adding a 'probe' method which selects a label and saves its settings, so it can be booted later, if desired.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v4: - Fix the force-prompt logic to leave the flag alone unless forced
boot/pxe_utils.c | 71 ++++++++++++++++++++++++++++++++++++++++++--- include/pxe_utils.h | 41 ++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 4 deletions(-)
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index 71347b19119..16608c6ebc8 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -802,8 +802,31 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label) if (ctx->bflow) ctx->bflow->fdt_addr = hextoul(conf_fdt, NULL);
- if (ctx->no_boot) + if (IS_ENABLED(CONFIG_BOOTSTD_FULL) && ctx->no_boot) { + ctx->label = label; + ctx->kernel_addr = strdup(kernel_addr); + if (initrd_addr_str) { + ctx->initrd_addr_str = strdup(initrd_addr_str); + ctx->initrd_filesize = strdup(initrd_filesize); + ctx->initrd_str = strdup(initrd_str); + } + ctx->conf_fdt = strdup(conf_fdt); + log_debug("Saving label '%s':\n", label->name); + log_debug("- kernel_addr '%s' conf_fdt '%s'\n", + ctx->kernel_addr, ctx->conf_fdt); + if (initrd_addr_str) { + log_debug("- initrd addr '%s' filesize '%s' str '%s'\n", + ctx->initrd_addr_str, ctx->initrd_filesize, + ctx->initrd_str); + } + if (!ctx->kernel_addr || !ctx->conf_fdt || + (initrd_addr_str && (!ctx->initrd_addr_str || + !ctx->initrd_filesize || !ctx->initrd_str))) { + printf("malloc fail (saving label)\n"); + return 1; + } return 0; + }
label_run_boot(ctx, label, kernel_addr, initrd_addr_str, initrd_filesize, initrd_str, conf_fdt); @@ -1695,18 +1718,30 @@ void pxe_destroy_ctx(struct pxe_context *ctx) free(ctx->bootdir); }
-int pxe_process(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt) +struct pxe_menu *pxe_prepare(struct pxe_context *ctx, ulong pxefile_addr_r, + bool prompt) { struct pxe_menu *cfg;
cfg = parse_pxefile(ctx, pxefile_addr_r); if (!cfg) { printf("Error parsing config file\n"); - return 1; + return NULL; }
if (prompt) - cfg->prompt = 1; + cfg->prompt = prompt; + + return cfg; +} + +int pxe_process(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt) +{ + struct pxe_menu *cfg; + + cfg = pxe_prepare(ctx, pxefile_addr_r, prompt); + if (!cfg) + return 1;
handle_pxe_menu(ctx, cfg);
@@ -1714,3 +1749,31 @@ int pxe_process(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt)
return 0; } + +int pxe_probe(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt) +{ + ctx->cfg = pxe_prepare(ctx, pxefile_addr_r, prompt); + if (!ctx->cfg) + return -EINVAL; + ctx->no_boot = true; + + handle_pxe_menu(ctx, ctx->cfg); + + return 0; +} + +int pxe_do_boot(struct pxe_context *ctx) +{ + int ret; + + if (!ctx->label) + return log_msg_ret("pxb", -ENOENT); + + ret = label_run_boot(ctx, ctx->label, ctx->kernel_addr, + ctx->initrd_addr_str, ctx->initrd_filesize, + ctx->initrd_str, ctx->conf_fdt); + if (ret) + return log_msg_ret("lrb", ret); + + return 0; +} diff --git a/include/pxe_utils.h b/include/pxe_utils.h index beadd221475..6425e349d19 100644 --- a/include/pxe_utils.h +++ b/include/pxe_utils.h @@ -111,6 +111,16 @@ typedef int (*pxe_getfile_func)(struct pxe_context *ctx, const char *file_path, * "default" option as default * @no_boot: Stop show of actually booting and just return * @bflow: Bootflow being booted, or NULL if none (must be valid if @no_boot) + * @cfg: PXE menu (NULL if not yet probed) + * + * The following are only used when probing for a label + * @label: Label to process + * @kernel_addr: String containing kernel address (cannot be NULL) + * @initrd_addr_str: String containing initaddr address (NULL if none) + * @initrd_filesize: String containing initrd size (only used if + * @initrd_addr_str) + * @initrd_str: initrd string to process (only used if @initrd_addr_str) + * @conf_fdt: string containing the FDT address */ struct pxe_context { /** @@ -133,6 +143,15 @@ struct pxe_context { bool use_fallback; bool no_boot; struct bootflow *bflow; + struct pxe_menu *cfg; + + /* information on the selected label to boot */ + struct pxe_label *label; + char *kernel_addr; + char *initrd_addr_str; + char *initrd_filesize; + char *initrd_str; + char *conf_fdt; };
/** @@ -283,4 +302,26 @@ int pxe_get_file_size(ulong *sizep); */ int pxe_get(ulong pxefile_addr_r, char **bootdirp, ulong *sizep, bool use_ipv6);
+/** + * pxe_probe() - Process a PXE file to find the label to boot + * + * This fills in the label, etc. fields in @ctx, assuming it funds something to + * boot. Then pxe_do_boot() can be called to boot it. + * + * @ctx: PXE context created with pxe_setup_ctx() + * @pxefile_addr_r: Address to load file + * @prompt: Force a prompt for the user + * Return: 0 if OK, -ve on error + */ +int pxe_probe(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt); + +/** + * pxe_do_boot() - Boot the selected label + * + * This boots the label discovered by pxe_probe() + * + * Return: Does not return, on success, otherwise returns a -ve error code + */ +int pxe_do_boot(struct pxe_context *ctx); + #endif /* __PXE_UTILS_H */

On Thu, Jan 23, 2025 at 09:11:06AM -0700, Simon Glass wrote:
It is useful to be able to select a bootflow and read its images, without actually doing the boot. This allows adjusting the bootargs, for example.
Provide support for this in the pxe_utils module, by adding a 'probe' method which selects a label and saves its settings, so it can be booted later, if desired.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v4:
- Fix the force-prompt logic to leave the flag alone unless forced
boot/pxe_utils.c | 71 ++++++++++++++++++++++++++++++++++++++++++--- include/pxe_utils.h | 41 ++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 4 deletions(-)
In the future can you please use --in-reply-to so that patchwork and b4 will track this correctly? Thanks.

Hi Tom,
On Thu, 23 Jan 2025 at 09:28, Tom Rini trini@konsulko.com wrote:
On Thu, Jan 23, 2025 at 09:11:06AM -0700, Simon Glass wrote:
It is useful to be able to select a bootflow and read its images, without actually doing the boot. This allows adjusting the bootargs, for example.
Provide support for this in the pxe_utils module, by adding a 'probe' method which selects a label and saves its settings, so it can be booted later, if desired.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v4:
- Fix the force-prompt logic to leave the flag alone unless forced
boot/pxe_utils.c | 71 ++++++++++++++++++++++++++++++++++++++++++--- include/pxe_utils.h | 41 ++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 4 deletions(-)
In the future can you please use --in-reply-to so that patchwork and b4 will track this correctly? Thanks.
OK will do.
Regards, Simon
participants (2)
-
Simon Glass
-
Tom Rini