[PATCH 38/39] pxe_utils: Refactor to separate reading from booting
Simon Glass
sjg at chromium.org
Tue Nov 19 14:18:43 CET 2024
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 at chromium.org>
---
boot/pxe_utils.c | 72 +++++++++++++++++++++++++++++++++++++++++----
include/pxe_utils.h | 41 ++++++++++++++++++++++++++
2 files changed, 108 insertions(+), 5 deletions(-)
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index 99c968a1202..01fff350f1b 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,29 @@ 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 +1748,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 */
--
2.34.1
More information about the U-Boot
mailing list