[PATCH 1/4] boot: pxe_utils: Add fallback support

When configured correctly, we can detect when boot fails after the boot process has been handed over to the kernel through the use of U-Boot's bootcount support. In some instances, such as when we are performing atomic updates via a system such as OSTree, it is desirable to provide a fallback option so that we can return to a previous (hopefully working) state.
Add a "fallback" option to the supported extlinux configuration options that points to a label like "default" so that we can utilise this in later commits.
Signed-off-by: Martyn Welch martyn.welch@collabora.com --- boot/pxe_utils.c | 15 +++++++++++++++ doc/README.pxe | 5 +++++ include/pxe_utils.h | 2 ++ 3 files changed, 22 insertions(+)
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index 4e27842b08..a80119c9a3 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -781,6 +781,7 @@ enum token_type { T_IPAPPEND, T_BACKGROUND, T_KASLRSEED, + T_FALLBACK, T_INVALID };
@@ -814,6 +815,7 @@ static const struct token keywords[] = { {"ipappend", T_IPAPPEND,}, {"background", T_BACKGROUND,}, {"kaslrseed", T_KASLRSEED,}, + {"fallback", T_FALLBACK,}, {NULL, T_INVALID} };
@@ -1356,6 +1358,18 @@ static int parse_pxefile_top(struct pxe_context *ctx, char *p, unsigned long bas
break;
+ case T_FALLBACK: + err = parse_sliteral(&p, &label_name); + + if (label_name) { + if (cfg->fallback_label) + free(cfg->fallback_label); + + cfg->fallback_label = label_name; + } + + break; + case T_INCLUDE: err = handle_include(ctx, &p, base + ALIGN(strlen(b), 4), cfg, @@ -1395,6 +1409,7 @@ void destroy_pxe_menu(struct pxe_menu *cfg)
free(cfg->title); free(cfg->default_label); + free(cfg->fallback_label);
list_for_each_safe(pos, n, &cfg->labels) { label = list_entry(pos, struct pxe_label, list); diff --git a/doc/README.pxe b/doc/README.pxe index 172201093d..af2e64a577 100644 --- a/doc/README.pxe +++ b/doc/README.pxe @@ -120,6 +120,11 @@ Unrecognized commands are ignored. default <label> - the label named here is treated as the default and is the first label 'pxe boot' attempts to boot.
+fallback <label> - the label named here is treated as a fallback option that + may be attempted should it be detected that booting of + the default has failed to complete, for example via + U-Boot's boot count limit functionality. + menu title <string> - sets a title for the menu of labels being displayed.
menu include <path> - use tftp to retrieve the pxe file at <path>, which diff --git a/include/pxe_utils.h b/include/pxe_utils.h index 9f19593048..a408fb7f13 100644 --- a/include/pxe_utils.h +++ b/include/pxe_utils.h @@ -62,6 +62,7 @@ struct pxe_label { * * title - the name of the menu as given by a 'menu title' line. * default_label - the name of the default label, if any. + * fallback_label - the name of the fallback label, if any. * bmp - the bmp file name which is displayed in background * timeout - time in tenths of a second to wait for a user key-press before * booting the default label. @@ -73,6 +74,7 @@ struct pxe_label { struct pxe_menu { char *title; char *default_label; + char *fallback_label; char *bmp; int timeout; int prompt;

The "fallback" extlinux config option allows us to set an alternative default boot option for when it has been detected that the default is failing. Implement the logic required to boot from this option when desired.
Signed-off-by: Martyn Welch martyn.welch@collabora.com --- boot/bootmeth_extlinux.c | 2 +- boot/bootmeth_pxe.c | 2 +- boot/pxe_utils.c | 14 +++++++++++++- cmd/pxe.c | 4 ++-- cmd/sysboot.c | 2 +- include/pxe_utils.h | 10 +++++++++- 6 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c index fbb05ef928..26c61a65e2 100644 --- a/boot/bootmeth_extlinux.c +++ b/boot/bootmeth_extlinux.c @@ -149,7 +149,7 @@ static int extlinux_boot(struct udevice *dev, struct bootflow *bflow) info.dev = dev; info.bflow = bflow; ret = pxe_setup_ctx(&ctx, &cmdtp, extlinux_getfile, &info, true, - bflow->fname, false); + bflow->fname, false, false); if (ret) return log_msg_ret("ctx", -EINVAL);
diff --git a/boot/bootmeth_pxe.c b/boot/bootmeth_pxe.c index 03d2589c26..05c6bece2c 100644 --- a/boot/bootmeth_pxe.c +++ b/boot/bootmeth_pxe.c @@ -150,7 +150,7 @@ static int extlinux_pxe_boot(struct udevice *dev, struct bootflow *bflow) info.bflow = bflow; info.cmdtp = &cmdtp; ret = pxe_setup_ctx(ctx, &cmdtp, extlinux_pxe_getfile, &info, false, - bflow->subdir, false); + bflow->subdir, false, false); if (ret) return log_msg_ret("ctx", -EINVAL);
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index a80119c9a3..d6a4b2cb85 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -1436,6 +1436,16 @@ struct pxe_menu *parse_pxefile(struct pxe_context *ctx, unsigned long menucfg)
buf = map_sysmem(menucfg, 0); r = parse_pxefile_top(ctx, buf, menucfg, cfg, 1); + + if (ctx->use_fallback) { + if (cfg->fallback_label) { + printf("Setting use of fallback\n"); + cfg->default_label = cfg->fallback_label; + } else { + printf("Selected fallback option, but not set\n"); + } + } + unmap_sysmem(buf); if (r < 0) { destroy_pxe_menu(cfg); @@ -1586,7 +1596,8 @@ void handle_pxe_menu(struct pxe_context *ctx, struct pxe_menu *cfg)
int pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp, pxe_getfile_func getfile, void *userdata, - bool allow_abs_path, const char *bootfile, bool use_ipv6) + bool allow_abs_path, const char *bootfile, bool use_ipv6, + bool use_fallback) { const char *last_slash; size_t path_len = 0; @@ -1597,6 +1608,7 @@ int pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp, ctx->userdata = userdata; ctx->allow_abs_path = allow_abs_path; ctx->use_ipv6 = use_ipv6; + ctx->use_fallback = use_fallback;
/* figure out the boot directory, if there is one */ if (bootfile && strlen(bootfile) >= MAX_TFTP_PATH_LEN) diff --git a/cmd/pxe.c b/cmd/pxe.c index ae02c28c07..982e2b1e7e 100644 --- a/cmd/pxe.c +++ b/cmd/pxe.c @@ -138,7 +138,7 @@ int pxe_get(ulong pxefile_addr_r, char **bootdirp, ulong *sizep, bool use_ipv6) int i;
if (pxe_setup_ctx(&ctx, cmdtp, do_get_tftp, NULL, false, - env_get("bootfile"), use_ipv6)) + env_get("bootfile"), use_ipv6, false)) return -ENOMEM;
if (IS_ENABLED(CONFIG_BOOTP_PXE_DHCP_OPTION) && @@ -288,7 +288,7 @@ do_pxe_boot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) }
if (pxe_setup_ctx(&ctx, cmdtp, do_get_tftp, NULL, false, - env_get("bootfile"), use_ipv6)) { + env_get("bootfile"), use_ipv6, false)) { printf("Out of memory\n"); return CMD_RET_FAILURE; } diff --git a/cmd/sysboot.c b/cmd/sysboot.c index 0ea08fd7b5..8a060780ca 100644 --- a/cmd/sysboot.c +++ b/cmd/sysboot.c @@ -105,7 +105,7 @@ static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc, }
if (pxe_setup_ctx(&ctx, cmdtp, sysboot_read_file, &info, true, - filename, false)) { + filename, false, false)) { printf("Out of memory\n"); return CMD_RET_FAILURE; } diff --git a/include/pxe_utils.h b/include/pxe_utils.h index a408fb7f13..68ac40b64a 100644 --- a/include/pxe_utils.h +++ b/include/pxe_utils.h @@ -96,6 +96,8 @@ typedef int (*pxe_getfile_func)(struct pxe_context *ctx, const char *file_path, * allocated * @pxe_file_size: Size of the PXE file * @use_ipv6: TRUE : use IPv6 addressing, FALSE : use IPv4 addressing + * @use_fallback: TRUE : use "fallback" option as default, FALSE : use + * "default" option as default */ struct pxe_context { struct cmd_tbl *cmdtp; @@ -116,6 +118,7 @@ struct pxe_context { char *bootdir; ulong pxe_file_size; bool use_ipv6; + bool use_fallback; };
/** @@ -215,12 +218,17 @@ int format_mac_pxe(char *outbuf, size_t outbuf_len); * none * @use_ipv6: TRUE : use IPv6 addressing * FALSE : use IPv4 addressing + * @use_fallback: TRUE : Use "fallback" option instead of "default" should no + * other choice be selected + * FALSE : Use "default" option should no other choice be + * selected * Return: 0 if OK, -ENOMEM if out of memory, -E2BIG if bootfile is larger than * MAX_TFTP_PATH_LEN bytes */ int pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp, pxe_getfile_func getfile, void *userdata, - bool allow_abs_path, const char *bootfile, bool use_ipv6); + bool allow_abs_path, const char *bootfile, bool use_ipv6, + bool use_fallback);
/** * pxe_destroy_ctx() - Destroy a PXE context

On Wed, 2 Oct 2024 at 07:26, Martyn Welch martyn.welch@collabora.com wrote:
The "fallback" extlinux config option allows us to set an alternative default boot option for when it has been detected that the default is failing. Implement the logic required to boot from this option when desired.
Signed-off-by: Martyn Welch martyn.welch@collabora.com
boot/bootmeth_extlinux.c | 2 +- boot/bootmeth_pxe.c | 2 +- boot/pxe_utils.c | 14 +++++++++++++- cmd/pxe.c | 4 ++-- cmd/sysboot.c | 2 +- include/pxe_utils.h | 10 +++++++++- 6 files changed, 27 insertions(+), 7 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

We have previously added logic to allow a "fallback" option to be specified in the extlinux configuration. Provide a command that allows us to set this as the preferred default option when booting.
Combined with the bootcount functionality, this allows the "altbootcmd" to provide a means of falling back to a previously known good state after a failed update. For example, if "bootcmd" is set to:
bootflow scan -lb
We would set "altbootcmd" to:
bootmeth set extlinux fallback 1; bootflow scan -lb
Causing the boot process to boot from the fallback option.
Signed-off-by: Martyn Welch martyn.welch@collabora.com --- boot/bootmeth-uclass.c | 25 ++++++++++++++ boot/bootmeth_extlinux.c | 73 +++++++++++++++++++++++++++++++++++++++- cmd/bootmeth.c | 25 ++++++++++++-- include/bootmeth.h | 31 +++++++++++++++++ 4 files changed, 151 insertions(+), 3 deletions(-)
diff --git a/boot/bootmeth-uclass.c b/boot/bootmeth-uclass.c index c0abadef97..5b5fea39b3 100644 --- a/boot/bootmeth-uclass.c +++ b/boot/bootmeth-uclass.c @@ -251,6 +251,31 @@ int bootmeth_set_order(const char *order_str) return 0; }
+int bootmeth_set_property(const char *name, const char *property, const char *value) +{ + int ret; + int len; + struct udevice *dev; + const struct bootmeth_ops *ops; + + len = strlen(name); + + ret = uclass_find_device_by_namelen(UCLASS_BOOTMETH, name, len, + &dev); + if (ret) { + printf("Unknown bootmeth '%s'\n", name); + return ret; + } + + ops = bootmeth_get_ops(dev); + if (!ops->set_property) { + printf("set_property not found\n"); + return -ENODEV; + } + + return ops->set_property(dev, property, value); +} + int bootmeth_setup_fs(struct bootflow *bflow, struct blk_desc *desc) { int ret; diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c index 26c61a65e2..be8fbf4df6 100644 --- a/boot/bootmeth_extlinux.c +++ b/boot/bootmeth_extlinux.c @@ -21,6 +21,39 @@ #include <mmc.h> #include <pxe_utils.h>
+struct extlinux_plat { + bool use_fallback; +}; + +enum extlinux_option_type { + EO_FALLBACK, + EO_INVALID +}; + +struct extlinux_option { + char *name; + enum extlinux_option_type option; +}; + +static const struct extlinux_option options[] = { + {"fallback", EO_FALLBACK}, + {NULL, EO_INVALID} +}; + +static enum extlinux_option_type get_option(const char *option) +{ + int i = 0; + + while (options[i].name) { + if (!strcmp(options[i].name, option)) + return options[i].option; + + i++; + } + + return EO_INVALID; +}; + static int extlinux_get_state_desc(struct udevice *dev, char *buf, int maxsize) { if (IS_ENABLED(CONFIG_SANDBOX)) { @@ -142,14 +175,18 @@ static int extlinux_boot(struct udevice *dev, struct bootflow *bflow) struct cmd_tbl cmdtp = {}; /* dummy */ struct pxe_context ctx; struct extlinux_info info; + struct extlinux_plat *plat; ulong addr; int ret;
addr = map_to_sysmem(bflow->buf); info.dev = dev; info.bflow = bflow; + + plat = dev_get_plat(dev); + ret = pxe_setup_ctx(&ctx, &cmdtp, extlinux_getfile, &info, true, - bflow->fname, false, false); + bflow->fname, false, plat->use_fallback); if (ret) return log_msg_ret("ctx", -EINVAL);
@@ -160,6 +197,38 @@ static int extlinux_boot(struct udevice *dev, struct bootflow *bflow) return 0; }
+static int extlinux_set_property(struct udevice *dev, const char *property, const char *value) +{ + struct extlinux_plat *plat; + static enum extlinux_option_type option; + + plat = dev_get_plat(dev); + + option = get_option(property); + if (option == EO_INVALID) { + printf("Invalid option\n"); + return -EINVAL; + } + + switch (option) { + case EO_FALLBACK: + if (!strcmp(value, "1")) { + plat->use_fallback = true; + } else if (!strcmp(value, "0")) { + plat->use_fallback = false; + } else { + printf("Unexpected value '%s'\n", value); + return -EINVAL; + } + break; + default: + printf("Unrecognised property '%s'\n", property); + return -EINVAL; + } + + return 0; +} + static int extlinux_bootmeth_bind(struct udevice *dev) { struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev); @@ -176,6 +245,7 @@ static struct bootmeth_ops extlinux_bootmeth_ops = { .read_bootflow = extlinux_read_bootflow, .read_file = bootmeth_common_read_file, .boot = extlinux_boot, + .set_property = extlinux_set_property, };
static const struct udevice_id extlinux_bootmeth_ids[] = { @@ -190,4 +260,5 @@ U_BOOT_DRIVER(bootmeth_1extlinux) = { .of_match = extlinux_bootmeth_ids, .ops = &extlinux_bootmeth_ops, .bind = extlinux_bootmeth_bind, + .plat_auto = sizeof(struct extlinux_plat) }; diff --git a/cmd/bootmeth.c b/cmd/bootmeth.c index ebf8b7e253..2f41fa1bec 100644 --- a/cmd/bootmeth.c +++ b/cmd/bootmeth.c @@ -103,10 +103,31 @@ static int do_bootmeth_order(struct cmd_tbl *cmdtp, int flag, int argc, return 0; }
+static int do_bootmeth_set(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + + if (argc < 4) { + printf("Required parameters not provided\n"); + return CMD_RET_FAILURE; + } + + ret = bootmeth_set_property(argv[1], argv[2], argv[3]); + if (ret) { + printf("Failed (err=%d)\n", ret); + return CMD_RET_FAILURE; + } + + return 0; +} + U_BOOT_LONGHELP(bootmeth, "list [-a] - list available bootmeths (-a all)\n" - "bootmeth order [<bd> ...] - select bootmeth order / subset to use"); + "bootmeth order [<bd> ...] - select bootmeth order / subset to use\n" + "bootmeth set <bootmeth> <property> <value> - set optional property");
U_BOOT_CMD_WITH_SUBCMDS(bootmeth, "Boot methods", bootmeth_help_text, U_BOOT_SUBCMD_MKENT(list, 2, 1, do_bootmeth_list), - U_BOOT_SUBCMD_MKENT(order, CONFIG_SYS_MAXARGS, 1, do_bootmeth_order)); + U_BOOT_SUBCMD_MKENT(order, CONFIG_SYS_MAXARGS, 1, do_bootmeth_order), + U_BOOT_SUBCMD_MKENT(set, CONFIG_SYS_MAXARGS, 1, do_bootmeth_set)); diff --git a/include/bootmeth.h b/include/bootmeth.h index 4d8ca48efd..a08ebf005a 100644 --- a/include/bootmeth.h +++ b/include/bootmeth.h @@ -146,6 +146,22 @@ struct bootmeth_ops { * something changes, other -ve on other error */ int (*boot)(struct udevice *dev, struct bootflow *bflow); + + /** + * set_property() - set the bootmeth property + * + * This allows the setting of boot method specific properties to enable + * automated finer grain control of the boot process + * + * @name: String containing the name of the relevant boot method + * @property: String containing the name of the property to set + * @value: String containing the value to be set for the specified + * property + * Return: 0 if OK, -ENODEV if an unknown bootmeth or property is + * provided, -ENOENT if there are no bootmeth devices + */ + int (*set_property)(struct udevice *dev, const char *property, + const char *value); };
#define bootmeth_get_ops(dev) ((struct bootmeth_ops *)(dev)->driver->ops) @@ -290,6 +306,21 @@ int bootmeth_setup_iter_order(struct bootflow_iter *iter, bool include_global); */ int bootmeth_set_order(const char *order_str);
+/** + * bootmeth_set_property() - Set the bootmeth property + * + * This allows the setting of boot method specific properties to enable + * automated finer grain control of the boot process + * + * @name: String containing the name of the relevant boot method + * @property: String containing the name of the property to set + * @value: String containing the value to be set for the specified property + * Return: 0 if OK, -ENODEV if an unknown bootmeth or property is provided, + * -ENOENT if there are no bootmeth devices + */ +int bootmeth_set_property(const char *name, const char *property, + const char *value); + /** * bootmeth_setup_fs() - Set up read to read a file *

On Wed, 2 Oct 2024 at 07:26, Martyn Welch martyn.welch@collabora.com wrote:
We have previously added logic to allow a "fallback" option to be specified in the extlinux configuration. Provide a command that allows us to set this as the preferred default option when booting.
Combined with the bootcount functionality, this allows the "altbootcmd" to provide a means of falling back to a previously known good state after a failed update. For example, if "bootcmd" is set to:
bootflow scan -lb
We would set "altbootcmd" to:
bootmeth set extlinux fallback 1; bootflow scan -lb
Causing the boot process to boot from the fallback option.
Signed-off-by: Martyn Welch martyn.welch@collabora.com
boot/bootmeth-uclass.c | 25 ++++++++++++++ boot/bootmeth_extlinux.c | 73 +++++++++++++++++++++++++++++++++++++++- cmd/bootmeth.c | 25 ++++++++++++-- include/bootmeth.h | 31 +++++++++++++++++ 4 files changed, 151 insertions(+), 3 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
But please update the documentation too - for the command and for the new bootstd feature

We have added a "set" sub command to bootmeth, add some tests to check it's operation.
Signed-off-by: Martyn Welch martyn.welch@collabora.com --- test/boot/bootmeth.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
diff --git a/test/boot/bootmeth.c b/test/boot/bootmeth.c index 113b789ea7..659f386228 100644 --- a/test/boot/bootmeth.c +++ b/test/boot/bootmeth.c @@ -130,6 +130,53 @@ static int bootmeth_cmd_order_glob(struct unit_test_state *uts) } BOOTSTD_TEST(bootmeth_cmd_order_glob, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+/* Check 'bootmeth set' command */ +static int bootmeth_cmd_set(struct unit_test_state *uts) +{ + /* Check we can enable extlinux fallback */ + console_record_reset_enable(); + ut_assertok(run_command("bootmeth set extlinux fallback 1", 0)); + ut_assert_console_end(); + + /* Check we can disable extlinux fallback */ + console_record_reset_enable(); + ut_assertok(run_command("bootmeth set extlinux fallback 0", 0)); + ut_assert_console_end(); + + /* Check extlinux fallback unexpected value */ + console_record_reset_enable(); + ut_asserteq(1, run_command("bootmeth set extlinux fallback fred", 0)); + ut_assert_nextline("Unexpected value 'fred'"); + ut_assert_nextline("Failed (err=-22)"); + ut_assert_console_end(); + + /* Check that we need to provide right number of parameters */ + ut_asserteq(1, run_command("bootmeth set extlinux fallback", 0)); + ut_assert_nextline("Required parameters not provided"); + ut_assert_console_end(); + + /* Check that we need to provide a valid bootmethod */ + ut_asserteq(1, run_command("bootmeth set fred fallback 0", 0)); + ut_assert_nextline("Unknown bootmeth 'fred'"); + ut_assert_nextline("Failed (err=-19)"); + ut_assert_console_end(); + + /* Check that we need to provide a valid property */ + ut_asserteq(1, run_command("bootmeth set extlinux fred 0", 0)); + ut_assert_nextline("Invalid option"); + ut_assert_nextline("Failed (err=-22)"); + ut_assert_console_end(); + + /* Check that we need to provide a bootmeth that supports properties */ + ut_asserteq(1, run_command("bootmeth set efi fallback 0", 0)); + ut_assert_nextline("set_property not found"); + ut_assert_nextline("Failed (err=-19)"); + ut_assert_console_end(); + + return 0; +} +BOOTSTD_TEST(bootmeth_cmd_set, UT_TESTF_DM | UT_TESTF_SCAN_FDT); + /* Check 'bootmeths' env var */ static int bootmeth_env(struct unit_test_state *uts) {

On Wed, 2 Oct 2024 at 07:26, Martyn Welch martyn.welch@collabora.com wrote:
We have added a "set" sub command to bootmeth, add some tests to check it's operation.
Signed-off-by: Martyn Welch martyn.welch@collabora.com
test/boot/bootmeth.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

On Wed, Oct 02, 2024 at 02:26:30PM +0100, Martyn Welch wrote:
When configured correctly, we can detect when boot fails after the boot process has been handed over to the kernel through the use of U-Boot's bootcount support. In some instances, such as when we are performing atomic updates via a system such as OSTree, it is desirable to provide a fallback option so that we can return to a previous (hopefully working) state.
Add a "fallback" option to the supported extlinux configuration options that points to a label like "default" so that we can utilise this in later commits.
Signed-off-by: Martyn Welch martyn.welch@collabora.com
Is "fallback" part of the nominal extlinux specification?

On Wed, 2024-10-02 at 13:16 -0600, Tom Rini wrote:
On Wed, Oct 02, 2024 at 02:26:30PM +0100, Martyn Welch wrote:
When configured correctly, we can detect when boot fails after the boot process has been handed over to the kernel through the use of U- Boot's bootcount support. In some instances, such as when we are performing atomic updates via a system such as OSTree, it is desirable to provide a fallback option so that we can return to a previous (hopefully working) state.
Add a "fallback" option to the supported extlinux configuration options that points to a label like "default" so that we can utilise this in later commits.
Signed-off-by: Martyn Welch martyn.welch@collabora.com
Is "fallback" part of the nominal extlinux specification?
When looking at options to implement this functionality, I did spend some time looking for an extlinux specification. The best I could find was:
https://wiki.syslinux.org/wiki/index.php
Putting aside the difference in syntax from that used by the syslinux project, of the 22 keywords currently supported by U-Boot, only 13 of them are mentioned there (surprisingly the syslinux documentation doesn't include "title" as an option).
I'd come to the conclusion that U-Boot already provides a greatly extended version of the syntax, made suitable for booting in a wider variety of instances than catered for by the syslinux project.
Though I admit, I could have missed another better source to documentation. Is that the one you're thinking of or is there a better one?
Martyn

On Thu, Oct 03, 2024 at 10:00:33AM +0100, Martyn Welch wrote:
On Wed, 2024-10-02 at 13:16 -0600, Tom Rini wrote:
On Wed, Oct 02, 2024 at 02:26:30PM +0100, Martyn Welch wrote:
When configured correctly, we can detect when boot fails after the boot process has been handed over to the kernel through the use of U- Boot's bootcount support. In some instances, such as when we are performing atomic updates via a system such as OSTree, it is desirable to provide a fallback option so that we can return to a previous (hopefully working) state.
Add a "fallback" option to the supported extlinux configuration options that points to a label like "default" so that we can utilise this in later commits.
Signed-off-by: Martyn Welch martyn.welch@collabora.com
Is "fallback" part of the nominal extlinux specification?
When looking at options to implement this functionality, I did spend some time looking for an extlinux specification. The best I could find was:
https://wiki.syslinux.org/wiki/index.php
Putting aside the difference in syntax from that used by the syslinux project, of the 22 keywords currently supported by U-Boot, only 13 of them are mentioned there (surprisingly the syslinux documentation doesn't include "title" as an option).
I'd come to the conclusion that U-Boot already provides a greatly extended version of the syntax, made suitable for booting in a wider variety of instances than catered for by the syslinux project.
Though I admit, I could have missed another better source to documentation. Is that the one you're thinking of or is there a better one?
I was thinking of https://systemd.io/BOOT_LOADER_SPECIFICATION/ which is now https://uapi-group.org/specifications/specs/boot_loader_specification/ and only has 11 keywords. So, yeah, I guess this is another place where we'll keep doing what's needed to make things more useful and see what happens down the road. I'm fine with what's being added in this series. Thanks!

On Wed, 2 Oct 2024 at 07:26, Martyn Welch martyn.welch@collabora.com wrote:
When configured correctly, we can detect when boot fails after the boot process has been handed over to the kernel through the use of U-Boot's bootcount support. In some instances, such as when we are performing atomic updates via a system such as OSTree, it is desirable to provide a fallback option so that we can return to a previous (hopefully working) state.
Add a "fallback" option to the supported extlinux configuration options that points to a label like "default" so that we can utilise this in later commits.
Signed-off-by: Martyn Welch martyn.welch@collabora.com
boot/pxe_utils.c | 15 +++++++++++++++ doc/README.pxe | 5 +++++ include/pxe_utils.h | 2 ++ 3 files changed, 22 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
participants (3)
-
Martyn Welch
-
Simon Glass
-
Tom Rini