diff mbox series

[v3,46/46] bootmeth_extlinux: Refactor extlinux to split boot

Message ID 20241206023626.2456858-47-sjg@chromium.org
State Changes Requested
Delegated to: Tom Rini
Headers show
Series pxe: Support read_all() for extlinux and PXE | expand

Commit Message

Simon Glass Dec. 6, 2024, 2:36 a.m. UTC
Add a new extlinux_setup() function which sets things up so that the
bootflow can either be booted, or just probed.

Provide a readall() method so that images can be read into memory,
without booting the OS. Adjust the boot() method so that it can boot,
after any changes have been made by the user.

Update the test to change the bootargs and check that they are booted
with the changes intact.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Pass through the bootfile since extlinux and PXE are different

 boot/ext_pxe_common.c | 53 +++++++++++++++++++++++++++----------------
 test/boot/bootflow.c  | 24 ++++++++++++++++++++
 2 files changed, 58 insertions(+), 19 deletions(-)

Comments

Simon Glass Dec. 20, 2024, 4:04 a.m. UTC | #1
Add a new extlinux_setup() function which sets things up so that the
bootflow can either be booted, or just probed.

Provide a readall() method so that images can be read into memory,
without booting the OS. Adjust the boot() method so that it can boot,
after any changes have been made by the user.

Update the test to change the bootargs and check that they are booted
with the changes intact.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Pass through the bootfile since extlinux and PXE are different

 boot/ext_pxe_common.c | 53 +++++++++++++++++++++++++++----------------
 test/boot/bootflow.c  | 24 ++++++++++++++++++++
 2 files changed, 58 insertions(+), 19 deletions(-)

Applied to sjg/master, thanks!
diff mbox series

Patch

diff --git a/boot/ext_pxe_common.c b/boot/ext_pxe_common.c
index 6e999af5fca..2037099708a 100644
--- a/boot/ext_pxe_common.c
+++ b/boot/ext_pxe_common.c
@@ -75,28 +75,20 @@  int extlinux_set_property(struct udevice *dev, const char *property,
 	return 0;
 }
 
-static int extlinux_process(struct udevice *dev, struct bootflow *bflow,
-			    pxe_getfile_func getfile, bool allow_abs_path,
-			    const char *bootfile, bool no_boot)
+static int extlinux_setup(struct udevice *dev, struct bootflow *bflow,
+			  pxe_getfile_func getfile, bool allow_abs_path,
+			  const char *bootfile, struct pxe_context *ctx)
 {
 	struct extlinux_plat *plat = dev_get_plat(dev);
-	ulong addr;
 	int ret;
 
-	addr = map_to_sysmem(bflow->buf);
-
 	plat->info.dev = dev;
 	plat->info.bflow = bflow;
 
-	ret = pxe_setup_ctx(&plat->ctx, getfile, &plat->info, allow_abs_path,
-			    bootfile, false, plat->use_fallback, bflow);
-	if (ret)
-		return log_msg_ret("ctx", -EINVAL);
-	plat->ctx.no_boot = no_boot;
-
-	ret = pxe_process(&plat->ctx, addr, false);
+	ret = pxe_setup_ctx(ctx, getfile, &plat->info, allow_abs_path, bootfile,
+			    false, plat->use_fallback, bflow);
 	if (ret)
-		return log_msg_ret("bread", -EINVAL);
+		return log_msg_ret("ctx", ret);
 
 	return 0;
 }
@@ -105,20 +97,43 @@  int extlinux_boot(struct udevice *dev, struct bootflow *bflow,
 		  pxe_getfile_func getfile, bool allow_abs_path,
 		  const char *bootfile)
 {
-	return extlinux_process(dev, bflow, getfile, allow_abs_path, bootfile,
-				false);
+	struct extlinux_plat *plat = dev_get_plat(dev);
+	ulong addr;
+	int ret;
+
+	/* if we have already selected a label, just boot it */
+	if (plat->ctx.label) {
+		ret = pxe_do_boot(&plat->ctx);
+	} else {
+		ret = extlinux_setup(dev, bflow, getfile, allow_abs_path,
+				     bootfile, &plat->ctx);
+		if (ret)
+			return log_msg_ret("elb", ret);
+		addr = map_to_sysmem(bflow->buf);
+		ret = pxe_process(&plat->ctx, addr, false);
+	}
+	if (ret)
+		return log_msg_ret("elb", -EFAULT);
+
+	return 0;
 }
 
 int extlinux_read_all(struct udevice *dev, struct bootflow *bflow,
 		      pxe_getfile_func getfile, bool allow_abs_path,
 		      const char *bootfile)
 {
+	struct extlinux_plat *plat = dev_get_plat(dev);
+	ulong addr;
 	int ret;
 
-	ret = extlinux_process(dev, bflow, getfile, allow_abs_path, bootfile,
-			       true);
+	ret = extlinux_setup(dev, bflow, getfile, allow_abs_path, bootfile,
+			     &plat->ctx);
+	if (ret)
+		return log_msg_ret("era", ret);
+	addr = map_to_sysmem(bflow->buf);
+	ret = pxe_probe(&plat->ctx, addr, false);
 	if (ret)
-		return log_msg_ret("era", -EINVAL);
+		return log_msg_ret("elb", -EFAULT);
 
 	return 0;
 }
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 640a7cdb7c9..35580cee90c 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -21,6 +21,7 @@ 
 #endif
 #include <dm/device-internal.h>
 #include <dm/lists.h>
+#include <linux/libfdt.h>
 #include <test/suites.h>
 #include <test/ut.h>
 #include "bootstd_common.h"
@@ -1440,6 +1441,9 @@  static int bootflow_scan_extlinux(struct unit_test_state *uts)
 	const struct bootflow_img *img;
 	struct bootstd_priv *std;
 	struct bootflow *bflow;
+	const char *cline;
+	const void *fdt;
+	int node;
 
 	ut_assertok(run_command("bootflow scan", 0));
 	ut_assert_console_end();
@@ -1477,6 +1481,26 @@  static int bootflow_scan_extlinux(struct unit_test_state *uts)
 	ut_asserteq(IH_TYPE_FLATDT, img->type);
 	ut_asserteq(0xc00000, img->addr);	/* fdt_addr_r */
 
+	/* adjust the command line */
+	ut_assertok(run_command("bootflow cmdline set root /dev/mmc2", 0));
+
+	ut_asserteq(-EFAULT, bootflow_boot(bflow));
+	ut_assert_skip_to_line("sandbox: continuing, as we cannot run Linux");
+	ut_assert_console_end();
+
+	/* check that the images were not loaded again */
+	ut_asserteq(4, bflow->images.count);
+
+	/* check the cmdline in the booted FDT */
+	fdt = working_fdt;
+	node = fdt_subnode_offset(fdt, 0, "chosen");
+	ut_assert(node > 0);
+	cline = fdt_getprop(fdt, node, "bootargs", 0);
+	ut_assertnonnull(cline);
+	ut_asserteq_str(
+		"ro root=/dev/mmc2 rhgb quiet LANG=en_US.UTF-8 cma=192MB cma=256MB",
+		bflow->cmdline);
+
 	return 0;
 }
 BOOTSTD_TEST(bootflow_scan_extlinux, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);