[PATCH v3 41/46] bootstd: Update extlinux and pxe to allow boot interruption
Simon Glass
sjg at chromium.org
Fri Dec 6 03:36:20 CET 2024
It is useful to be able to inspect things before the OS is actually
booted, perhaps to check that all is well or to adjust the kernel
command-line. Implement the 'read_all()' method to allow this.
Provide a simple test to check that the images are found.
For now it is not possible to actually continue the uninterrupted boot,
without re-reading all the images.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
Changes in v3:
- Pass through the bootfile since extlinux and PXE are different
boot/bootmeth_extlinux.c | 11 ++++++++++
boot/bootmeth_pxe.c | 11 ++++++++++
boot/ext_pxe_common.c | 29 ++++++++++++++++++++++++---
include/extlinux.h | 15 ++++++++++++++
test/boot/bootflow.c | 43 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 106 insertions(+), 3 deletions(-)
diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c
index e7277ccdaa9..bd9026d448b 100644
--- a/boot/bootmeth_extlinux.c
+++ b/boot/bootmeth_extlinux.c
@@ -145,6 +145,14 @@ static int extlinux_local_boot(struct udevice *dev, struct bootflow *bflow)
return extlinux_boot(dev, bflow, extlinux_getfile, true, bflow->fname);
}
+#if CONFIG_IS_ENABLED(BOOTSTD_FULL)
+static int extlinux_local_read_all(struct udevice *dev, struct bootflow *bflow)
+{
+ return extlinux_read_all(dev, bflow, extlinux_getfile, true,
+ bflow->fname);
+}
+#endif
+
static int extlinux_bootmeth_bind(struct udevice *dev)
{
struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
@@ -162,6 +170,9 @@ static struct bootmeth_ops extlinux_bootmeth_ops = {
.read_file = bootmeth_common_read_file,
.boot = extlinux_local_boot,
.set_property = extlinux_set_property,
+#if CONFIG_IS_ENABLED(BOOTSTD_FULL)
+ .read_all = extlinux_local_read_all,
+#endif
};
static const struct udevice_id extlinux_bootmeth_ids[] = {
diff --git a/boot/bootmeth_pxe.c b/boot/bootmeth_pxe.c
index 5f3d595628c..4b5b88bae52 100644
--- a/boot/bootmeth_pxe.c
+++ b/boot/bootmeth_pxe.c
@@ -143,6 +143,14 @@ static int extlinux_pxe_boot(struct udevice *dev, struct bootflow *bflow)
bflow->subdir);
}
+#if CONFIG_IS_ENABLED(BOOTSTD_FULL)
+static int extlinux_pxe_read_all(struct udevice *dev, struct bootflow *bflow)
+{
+ return extlinux_read_all(dev, bflow, extlinux_pxe_getfile, false,
+ bflow->subdir);
+}
+#endif
+
static int extlinux_bootmeth_pxe_bind(struct udevice *dev)
{
struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
@@ -159,6 +167,9 @@ static struct bootmeth_ops extlinux_bootmeth_pxe_ops = {
.read_file = extlinux_pxe_read_file,
.boot = extlinux_pxe_boot,
.set_property = extlinux_set_property,
+#if CONFIG_IS_ENABLED(BOOTSTD_FULL)
+ .read_all = extlinux_pxe_read_all,
+#endif
};
static const struct udevice_id extlinux_bootmeth_pxe_ids[] = {
diff --git a/boot/ext_pxe_common.c b/boot/ext_pxe_common.c
index 0d808048289..6e999af5fca 100644
--- a/boot/ext_pxe_common.c
+++ b/boot/ext_pxe_common.c
@@ -75,9 +75,9 @@ int extlinux_set_property(struct udevice *dev, const char *property,
return 0;
}
-int extlinux_boot(struct udevice *dev, struct bootflow *bflow,
- pxe_getfile_func getfile, bool allow_abs_path,
- const char *bootfile)
+static int extlinux_process(struct udevice *dev, struct bootflow *bflow,
+ pxe_getfile_func getfile, bool allow_abs_path,
+ const char *bootfile, bool no_boot)
{
struct extlinux_plat *plat = dev_get_plat(dev);
ulong addr;
@@ -92,6 +92,7 @@ int extlinux_boot(struct udevice *dev, struct bootflow *bflow,
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);
if (ret)
@@ -99,3 +100,25 @@ int extlinux_boot(struct udevice *dev, struct bootflow *bflow,
return 0;
}
+
+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);
+}
+
+int extlinux_read_all(struct udevice *dev, struct bootflow *bflow,
+ pxe_getfile_func getfile, bool allow_abs_path,
+ const char *bootfile)
+{
+ int ret;
+
+ ret = extlinux_process(dev, bflow, getfile, allow_abs_path, bootfile,
+ true);
+ if (ret)
+ return log_msg_ret("era", -EINVAL);
+
+ return 0;
+}
diff --git a/include/extlinux.h b/include/extlinux.h
index 5baa2440b53..f64597ebdef 100644
--- a/include/extlinux.h
+++ b/include/extlinux.h
@@ -64,4 +64,19 @@ int extlinux_boot(struct udevice *dev, struct bootflow *bflow,
pxe_getfile_func getfile, bool allow_abs_path,
const char *bootfile);
+/**
+ * extlinux_read_all() - read all files for a bootflow
+ *
+ * @dev: Bootmethod device to boot
+ * @bflow: Bootflow to read
+ * @getfile: Function to use to read files
+ * @allow_abs_path: true to allow absolute paths
+ * @bootfile: Bootfile whose directory loaded files are relative to, NULL if
+ * none
+ * Return: 0 if OK, -EIO on I/O error, other -ve on other error
+ */
+int extlinux_read_all(struct udevice *dev, struct bootflow *bflow,
+ pxe_getfile_func getfile, bool allow_abs_path,
+ const char *bootfile);
+
#endif
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index f7d12765928..ef8c0c1bbaa 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -1433,3 +1433,46 @@ static int bootstd_adhoc(struct unit_test_state *uts)
return 0;
}
BOOTSTD_TEST(bootstd_adhoc, UTF_CONSOLE);
+
+/* Check scanning extlinux, adjusting cmdline and booting */
+static int bootflow_scan_extlinux(struct unit_test_state *uts)
+{
+ const struct bootflow_img *img;
+ struct bootstd_priv *std;
+ struct bootflow *bflow;
+
+ ut_assertok(run_command("bootflow scan", 0));
+ ut_assert_console_end();
+ ut_assertok(bootstd_get_priv(&std));
+
+ ut_asserteq(1, std->bootflows.count);
+
+ bflow = alist_getw(&std->bootflows, 0, struct bootflow);
+ std->cur_bootflow = bflow;
+
+ /* read all the images, but don't actually boot */
+ ut_assertok(inject_response(uts));
+ ut_assertok(bootflow_read_all(bflow));
+
+ /* check that the command line is now present */
+ ut_asserteq_str(
+ "ro root=UUID=9732b35b-4cd5-458b-9b91-80f7047e0b8a rhgb quiet LANG=en_US.UTF-8 cma=192MB cma=256MB",
+ bflow->cmdline);
+
+ ut_asserteq(3, bflow->images.count);
+
+ /* check each image */
+ img = alist_get(&bflow->images, 0, struct bootflow_img);
+ ut_asserteq_strn("# extlinux.conf", map_sysmem(img->addr, 0));
+
+ img = alist_get(&bflow->images, 1, struct bootflow_img);
+ ut_asserteq(IH_TYPE_KERNEL, img->type);
+ ut_asserteq(0x1000000, img->addr); /* kernel_addr_r */
+
+ img = alist_get(&bflow->images, 2, struct bootflow_img);
+ ut_asserteq(IH_TYPE_RAMDISK, img->type);
+ ut_asserteq(0x2000000, img->addr); /* ramdisk_addr_r */
+
+ return 0;
+}
+BOOTSTD_TEST(bootflow_scan_extlinux, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
--
2.34.1
More information about the U-Boot
mailing list