* [PATCH 0/2] bootstd: New bootmeth for RAUC A/B systems
@ 2025-01-29 14:25 Martin Schwan
2025-01-29 14:25 ` [PATCH 1/2] bootstd: Add implementation for bootmeth rauc Martin Schwan
2025-01-29 14:25 ` [PATCH 2/2] doc: Add description " Martin Schwan
0 siblings, 2 replies; 20+ messages in thread
From: Martin Schwan @ 2025-01-29 14:25 UTC (permalink / raw)
To: Tom Rini, Simon Glass; +Cc: u-boot, upstream
This series implements a new bootmeth for RAUC A/B systems. RAUC (Robust
Auto Update Controller) is a lightweight update client, providing "Safe
and Secure OTA Updates for Embedded Linux". See the following links for
more information about RAUC:
https://rauc.io/
https://rauc.readthedocs.io/en/latest/
PHYTEC uses RAUC in its Yocto based distribution "Ampliphy" as the
default way of updating embedded devices based on PHYTEC hardware. So
far, the logic selecting the correct partitions and files to boot was
being implemented in the U-Boot environment. While this is a
straightforward way to do it, adding and supporting new platforms became
somewhat tedious and is platform-specific. The introduction of U-Boot's
"Standard Boot" provided a convincing alternative, promising a simpler
and more portable way of booting, even for RAUC systems. This led me to
implement a new bootmeth supporting RAUC A/B systems. Note, that this
new bootmeth is not proprietary to PHYTEC products and is designed to
work on other hardware with a RAUC A/B system, too.
The bootmeth currently only supports symmetric A/B partitioning layouts.
E.g. A/rescue is not (yet) supported. The partition indexes and default
slot tries can be specified via environment variables, so that these
settings can be changed on a running system, in case they may change in
the future for that individual target, without needing to update the
U-Boot proper.
For now, the bootmeth_rauc uses a similar approach for loading the
Kernel and device tree as the bootmeth_script, in that it requires a FIT
containing a U-Boot script loading the desired distro. It could be
possible to support booting without a script and load the Kernel and DT
directly with this bootmeth, but I found the script method to be very
flexible for now, in letting the distro decide what to load.
The bootmeth_rauc was tested on a phyBOARD-Pollux i.MX8M Plus [1] with
BSP-Yocto-Ampliphy-i.MX8MP-PD24.1.2 [2] and the following changes in the
U-Boot environment:
BOOT_ORDER=system0 system1
rauc_slots=system0 system1
rauc_partitions=1,5 2,6
rauc_slot_default_tries=3
Supported boot devices are currently only MMC devices, but it should be
possible to add SPI flashes in the future.
To test this patch stack with PHYTEC's phyBOARD-Pollux i.MX8M Plus
board, you need to adjust the boot files to include the boot.scr.uimg
containing the distro's boot script and set "optargs" to "${raucargs}"
in it. Also disable any legacyboot in the U-Boot environment and simply
boot with Standard Boot:
bootmeth order rauc
bootflow scan -lb
Regards,
Martin
[1]: https://www.phytec.eu/en/produkte/single-board-computer/phyboard-pollux/
[2]: https://download.phytec.de/Software/Linux/BSP-Yocto-i.MX8MP/BSP-Yocto-Ampliphy-i.MX8MP-PD24.1.2/
---
Martin Schwan (2):
bootstd: Add implementation for bootmeth rauc
doc: Add description for bootmeth rauc
boot/Kconfig | 11 ++
boot/Makefile | 1 +
boot/bootmeth_rauc.c | 408 +++++++++++++++++++++++++++++++++++++++
doc/develop/bootstd/index.rst | 1 +
doc/develop/bootstd/overview.rst | 1 +
doc/develop/bootstd/rauc.rst | 55 ++++++
6 files changed, 477 insertions(+)
---
base-commit: a2b489b170f8382f746202c36616eaf2bc38fe86
change-id: 20250129-wip-bootmeth-rauc-03b5e2dd88f4
Best regards,
--
Martin Schwan <m.schwan@phytec.de>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-01-29 14:25 [PATCH 0/2] bootstd: New bootmeth for RAUC A/B systems Martin Schwan
@ 2025-01-29 14:25 ` Martin Schwan
2025-01-29 16:03 ` Tom Rini
` (2 more replies)
2025-01-29 14:25 ` [PATCH 2/2] doc: Add description " Martin Schwan
1 sibling, 3 replies; 20+ messages in thread
From: Martin Schwan @ 2025-01-29 14:25 UTC (permalink / raw)
To: Tom Rini, Simon Glass; +Cc: u-boot, upstream
Add a bootmeth driver which supports booting A/B system with RAUC as
their update client.
Signed-off-by: Martin Schwan <m.schwan@phytec.de>
---
boot/Kconfig | 11 ++
boot/Makefile | 1 +
boot/bootmeth_rauc.c | 408 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 420 insertions(+)
diff --git a/boot/Kconfig b/boot/Kconfig
index 20935a269c60dad53ce11ac7e58247dc23cf617e..966573d8eb7675d36f299c8c2fa6509bac147cae 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -782,6 +782,17 @@ config EXPO
The expo can be presented in graphics form using a vidconsole, or in
text form on a serial console.
+config BOOTMETH_RAUC
+ bool "Bootdev support for RAUC A/B systems"
+ default y if BOOTSTD_FULL
+ depends on CMDLINE
+ select BOOTMETH_GLOBAL
+ select HUSH_PARSER
+ help
+ Enables support for booting RAUC A/B systems from MMC devices. This
+ makes the bootdevs look for a 'boot.scr.uimg' or 'boot.scr' in the
+ respective boot partitions, describing how to boot the distro.
+
config BOOTMETH_SANDBOX
def_bool y
depends on SANDBOX
diff --git a/boot/Makefile b/boot/Makefile
index c2753de8163cf59b1abdc01149a856e2847960e6..427898449a8727747137ab1c7c571c473148c8c3 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_$(PHASE_)BOOTMETH_EXTLINUX_PXE) += bootmeth_pxe.o
obj-$(CONFIG_$(PHASE_)BOOTMETH_EFILOADER) += bootmeth_efi.o
obj-$(CONFIG_$(PHASE_)BOOTMETH_CROS) += bootm.o bootm_os.o bootmeth_cros.o
obj-$(CONFIG_$(PHASE_)BOOTMETH_QFW) += bootmeth_qfw.o
+obj-$(CONFIG_$(PHASE_)BOOTMETH_RAUC) += bootmeth_rauc.o
obj-$(CONFIG_$(PHASE_)BOOTMETH_SANDBOX) += bootmeth_sandbox.o
obj-$(CONFIG_$(PHASE_)BOOTMETH_SCRIPT) += bootmeth_script.o
obj-$(CONFIG_$(PHASE_)CEDIT) += cedit.o
diff --git a/boot/bootmeth_rauc.c b/boot/bootmeth_rauc.c
new file mode 100644
index 0000000000000000000000000000000000000000..fcb7e8df4556710b160349f1dcc54cdda9b59c9d
--- /dev/null
+++ b/boot/bootmeth_rauc.c
@@ -0,0 +1,408 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Bootmethod for distro boot with RAUC
+ *
+ * Copyright 2025 PHYTEC Messtechnik GmbH
+ * Written by Martin Schwan <m.schwan@phytec.de>
+ */
+
+#define LOG_CATEGORY UCLASS_BOOTSTD
+#define LOG_DEBUG
+
+#include <asm/cache.h>
+#include <blk.h>
+#include <bootflow.h>
+#include <bootmeth.h>
+#include <bootstd.h>
+#include <dm.h>
+#include <env.h>
+#include <fs.h>
+#include <malloc.h>
+#include <mapmem.h>
+#include <string.h>
+
+static const char * const script_names[] = { "boot.scr.uimg", "boot.scr", NULL };
+static const char * const rauc_files[] = { "/usr/bin/rauc", "/etc/rauc/system.conf", NULL };
+
+/**
+ * struct distro_rauc_slot - Slot information
+ *
+ * @name The slot name
+ * @left The number of boot tries left
+ * @boot_part The boot partition number on disk
+ * @root_part The boot partition number on disk
+ */
+struct distro_rauc_slot {
+ char *name;
+ ulong left;
+ int boot_part;
+ int root_part;
+};
+
+/**
+ * struct distro_rauc_priv - Private data
+ *
+ * @slots All slots of the device in default order
+ * @boot_order The current boot order string containing the active slot names
+ */
+struct distro_rauc_priv {
+ struct distro_rauc_slot *slots;
+ char *boot_order;
+};
+
+static int distro_rauc_check(struct udevice *dev, struct bootflow_iter *iter)
+{
+ /* This distro only works on whole MMC devices, as multiple partitions
+ * are needed for an A/B system. */
+ if (bootflow_iter_check_mmc(iter))
+ return log_msg_ret("mmc", -EOPNOTSUPP);
+ if (iter->part != 0)
+ return log_msg_ret("part", -EOPNOTSUPP);
+
+ return 0;
+}
+
+static int distro_rauc_scan_boot_part(struct bootflow *bflow)
+{
+ struct blk_desc *desc;
+ struct distro_rauc_priv *priv;
+ int exists;
+ int i;
+ int j;
+ int ret;
+
+ desc = dev_get_uclass_plat(bflow->blk);
+ if (!desc)
+ return log_msg_ret("desc", -ENOMEM);
+
+ priv = bflow->bootmeth_priv;
+ if (!priv || !priv->slots || !priv->boot_order)
+ return log_msg_ret("priv", -EINVAL);
+
+ for (i = 0; priv->slots[i].name != NULL; i++) {
+ exists = 0;
+ for (j = 0; script_names[j] != NULL; j++) {
+ ret = fs_set_blk_dev_with_part(desc, priv->slots[i].boot_part);
+ if (ret)
+ return log_msg_ret("blk", ret);
+ exists |= fs_exists(script_names[j]);
+ }
+ if (!exists)
+ return log_msg_ret("fs", -ENOENT);
+ }
+
+ return 0;
+}
+
+static int distro_rauc_scan_root_part(struct bootflow *bflow)
+{
+ struct blk_desc *desc;
+ struct distro_rauc_priv *priv;
+ int exists;
+ int i;
+ int j;
+ int ret;
+
+ desc = dev_get_uclass_plat(bflow->blk);
+ if (!desc)
+ return log_msg_ret("desc", -ENOMEM);
+
+ priv = bflow->bootmeth_priv;
+ if (!priv || !priv->slots || !priv->boot_order)
+ return log_msg_ret("priv", -EINVAL);
+
+ for (i = 0; priv->slots[i].name != NULL; i++) {
+ exists = 0;
+ for (j = 0; rauc_files[j] != NULL; j++) {
+ ret = fs_set_blk_dev_with_part(desc,
+ priv->slots[i].root_part);
+ if (ret)
+ return log_msg_ret("set", ret);
+ if (!fs_exists(rauc_files[j]))
+ return log_msg_ret("fs", -ENOENT);
+ }
+ }
+
+ return 0;
+}
+
+static int distro_rauc_read_bootflow(struct udevice *dev, struct bootflow *bflow)
+{
+ struct distro_rauc_priv *priv;
+ int ret;
+ char *slot;
+ int i;
+ char *boot_order;
+ char *partitions;
+ const char **partitions_list;
+ char *slots;
+ const char **slots_list;
+ char boot_left[32];
+ char *parts;
+ ulong default_tries;
+
+ bflow->state = BOOTFLOWST_MEDIA;
+
+ priv = malloc(sizeof(struct distro_rauc_priv));
+ if (!priv)
+ return log_msg_ret("buf", -ENOMEM);
+
+
+ partitions = env_get("rauc_partitions");
+ if (!partitions)
+ return log_msg_ret("env", -ENOENT);
+ partitions_list = str_to_list(partitions);
+
+ slots = env_get("rauc_slots");
+ if (!slots)
+ return log_msg_ret("env", -ENOENT);
+ slots_list = str_to_list(slots);
+
+ boot_order = env_get("BOOT_ORDER");
+ if (!boot_order) {
+ if (env_set("BOOT_ORDER", slots))
+ return log_msg_ret("env", -EPERM);
+ }
+ priv->boot_order = strdup(boot_order);
+
+ default_tries = env_get_ulong("rauc_slot_default_tries", 10, 3);
+ for (i = 0; slots_list[i] != NULL; i++) {
+ sprintf(boot_left, "BOOT_%s_LEFT", slots_list[i]);
+ if (!env_get(boot_left))
+ env_set_ulong(boot_left, default_tries);
+ }
+
+ for (i = 0; slots_list[i] != NULL && partitions_list[i] != NULL; i++);
+ priv->slots = malloc((i + 1) * sizeof(struct distro_rauc_slot));
+ if (!priv->slots)
+ return log_msg_ret("priv", -ENOMEM);
+ for (i = 0; slots_list[i] != NULL && partitions_list[i] != NULL; i++) {
+ priv->slots[i].name = strdup(slots_list[i]);
+ sprintf(boot_left, "BOOT_%s_LEFT", slot);
+ priv->slots[i].left = env_get_ulong(boot_left, 10, default_tries);
+ parts = strdup(partitions_list[i]);
+ priv->slots[i].boot_part = simple_strtoul(strsep(&parts, ","), NULL, 10);
+ priv->slots[i].root_part = simple_strtoul(strsep(&parts, ","), NULL, 10);
+ free(parts);
+ parts = NULL;
+ }
+ priv->slots[i].name = NULL;
+ priv->slots[i].left = 0;
+ priv->slots[i].boot_part = 0;
+ priv->slots[i].root_part = 0;
+
+ bflow->bootmeth_priv = priv;
+ bflow->state = BOOTFLOWST_FS;
+
+ ret = distro_rauc_scan_boot_part(bflow);
+ if (ret < 0)
+ goto free_priv;
+ ret = distro_rauc_scan_root_part(bflow);
+ if (ret < 0)
+ goto free_priv;
+
+ bflow->state = BOOTFLOWST_READY;
+
+ return 0;
+
+free_priv:
+ for (i = 0; priv->slots[i].name != NULL; i++)
+ free(priv->slots[i].name);
+ free(priv->slots);
+ free(priv);
+ bflow->bootmeth_priv = NULL;
+ return ret;
+}
+
+static int distro_rauc_read_file(struct udevice *dev, struct bootflow *bflow,
+ const char *file_path, ulong addr,
+ enum bootflow_img_t type, ulong *sizep)
+{
+ /* Reading individual files is not supported since we only operate on
+ * whole MMC devices (because we require multiple partitions)
+ */
+ return log_msg_ret("Unsupported", -ENOSYS);
+}
+
+static int distro_rauc_load_boot_script(struct bootflow *bflow, const char *slot)
+{
+ struct blk_desc *desc;
+ struct distro_rauc_priv *priv;
+ const char *prefix = "/";
+ int ret;
+ int i;
+
+ if (!slot)
+ return log_msg_ret("slot", -EINVAL);
+
+ desc = dev_get_uclass_plat(bflow->blk);
+ priv = bflow->bootmeth_priv;
+
+ bflow->part = 0;
+ for (i = 0; priv->slots[i].name != NULL; i++) {
+ if (strcmp(priv->slots[i].name, slot) == 0) {
+ bflow->part = priv->slots[i].boot_part;
+ break;
+ }
+ }
+ if (!bflow->part)
+ return log_msg_ret("part", -ENOENT);
+
+ ret = bootmeth_setup_fs(bflow, desc);
+ if (ret)
+ return log_msg_ret("set", ret);
+
+ for (i = 0; script_names[i] != NULL; i++) {
+ if (!bootmeth_try_file(bflow, desc, prefix, script_names[i]))
+ break;
+ }
+ if (bflow->state != BOOTFLOWST_FILE)
+ return log_msg_ret("file", -ENOENT);
+
+ bflow->subdir = strdup(prefix);
+
+ ret = bootmeth_alloc_file(bflow, 0x10000, ARCH_DMA_MINALIGN,
+ (enum bootflow_img_t)IH_TYPE_SCRIPT);
+ if (ret)
+ return log_msg_ret("read", ret);
+
+ return 0;
+}
+
+static int decrement_slot_tries(const char *slot)
+{
+ ulong tries;
+ char boot_left[32];
+
+ sprintf(boot_left, "BOOT_%s_LEFT", slot);
+ tries = env_get_ulong(boot_left, 10, ULONG_MAX);
+ if (tries == ULONG_MAX)
+ return log_msg_ret("env", -ENOENT);
+ if (tries <= 0)
+ return 0;
+
+ return env_set_ulong(boot_left, tries - 1);
+}
+
+static int distro_rauc_boot(struct udevice *dev, struct bootflow *bflow)
+{
+ struct blk_desc *desc;
+ struct distro_rauc_priv *priv;
+ char *boot_order;
+ const char **boot_order_list;
+ const char *active_slot;
+ char raucargs[32];
+ ulong addr;
+ int ret = 0;
+ int i;
+
+ desc = dev_get_uclass_plat(bflow->blk);
+ if (desc->uclass_id != UCLASS_MMC)
+ return log_msg_ret("blk", -EINVAL);
+ priv = bflow->bootmeth_priv;
+
+ /* RAUC variables */
+ boot_order = env_get("BOOT_ORDER");
+ if (!boot_order)
+ return log_msg_ret("env", -ENOENT);
+ boot_order_list = str_to_list(boot_order);
+
+ /* Device info variables */
+ ret = env_set("devtype", blk_get_devtype(bflow->blk));
+ if (ret)
+ return log_msg_ret("env", ret);
+
+ ret = env_set_hex("devnum", desc->devnum);
+ if (ret)
+ return log_msg_ret("env", ret);
+
+ /* Kernel command line arguments */
+ active_slot = strdup(boot_order_list[0]);
+ if (!active_slot)
+ return log_msg_ret("env", -ENOENT);
+ sprintf(raucargs, "rauc.slot=%s", active_slot);
+ ret = env_set("raucargs", raucargs);
+ if (ret)
+ return log_msg_ret("env", ret);
+
+ /* TODO: If active_slot is in boot_order, but has 0 tries left, remove
+ * it from boot_order. Then, set active_slot to other, if available.
+ */
+
+ /* Partition info variables */
+ for (i = 0; priv->slots[i].name != NULL; i++) {
+ if (strcmp(priv->slots[i].name, active_slot) == 0) {
+ ret = env_set_hex("mmcroot", priv->slots[i].root_part);
+ if (ret)
+ return log_msg_ret("env", ret);
+ break;
+ }
+ }
+
+ /* Load distro boot script */
+ ret = distro_rauc_load_boot_script(bflow, active_slot);
+ if (ret)
+ return log_msg_ret("load", ret);
+ ret = env_set_hex("distro_bootpart", bflow->part);
+ if (ret)
+ return log_msg_ret("env", ret);
+
+ ret = decrement_slot_tries(active_slot);
+ if (ret)
+ return log_msg_ret("env", ret);
+ ret = env_save();
+ if (ret)
+ return log_msg_ret("env", ret);
+
+ log_debug("devtype: %s\n", env_get("devtype"));
+ log_debug("devnum: %s\n", env_get("devnum"));
+ log_debug("distro_bootpart: %s\n", env_get("distro_bootpart"));
+ log_debug("mmcroot: %s\n", env_get("mmcroot"));
+ log_debug("raucargs: %s\n", env_get("raucargs"));
+ log_debug("rauc_slots: %s\n", env_get("rauc_slots"));
+ log_debug("rauc_partitions: %s\n", env_get("rauc_partitions"));
+ log_debug("rauc_slot_default_tries: %s\n", env_get("rauc_slot_default_tries"));
+ log_debug("BOOT_ORDER: %s\n", env_get("BOOT_ORDER"));
+ for (i = 0; priv->slots[i].name != NULL; i++) {
+ log_debug("BOOT_%s_LEFT: %ld\n", priv->slots[i].name,
+ priv->slots[i].left);
+ }
+
+ /* Run distro boot script */
+ addr = map_to_sysmem(bflow->buf);
+ ret = cmd_source_script(addr, NULL, NULL);
+ if (ret)
+ return log_msg_ret("boot", ret);
+
+ return 0;
+}
+
+static int distro_rauc_bootmeth_bind(struct udevice *dev)
+{
+ struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
+
+ plat->desc = "RAUC distro boot from MMC";
+ plat->flags = BOOTMETHF_ANY_PART;
+
+ return 0;
+}
+
+static struct bootmeth_ops distro_rauc_bootmeth_ops = {
+ .check = distro_rauc_check,
+ .read_bootflow = distro_rauc_read_bootflow,
+ .read_file = distro_rauc_read_file,
+ .boot = distro_rauc_boot,
+};
+
+static const struct udevice_id distro_rauc_bootmeth_ids[] = {
+ { .compatible = "u-boot,distro-rauc" },
+ { }
+};
+
+U_BOOT_DRIVER(bootmeth_rauc) = {
+ .name = "bootmeth_rauc",
+ .id = UCLASS_BOOTMETH,
+ .of_match = distro_rauc_bootmeth_ids,
+ .ops = &distro_rauc_bootmeth_ops,
+ .bind = distro_rauc_bootmeth_bind,
+};
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 2/2] doc: Add description for bootmeth rauc
2025-01-29 14:25 [PATCH 0/2] bootstd: New bootmeth for RAUC A/B systems Martin Schwan
2025-01-29 14:25 ` [PATCH 1/2] bootstd: Add implementation for bootmeth rauc Martin Schwan
@ 2025-01-29 14:25 ` Martin Schwan
1 sibling, 0 replies; 20+ messages in thread
From: Martin Schwan @ 2025-01-29 14:25 UTC (permalink / raw)
To: Tom Rini, Simon Glass; +Cc: u-boot, upstream
Add documentation for the bootmeth "rauc", which boots an A/B system
with RAUC from MMC.
Signed-off-by: Martin Schwan <m.schwan@phytec.de>
---
doc/develop/bootstd/index.rst | 1 +
doc/develop/bootstd/overview.rst | 1 +
doc/develop/bootstd/rauc.rst | 55 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 57 insertions(+)
diff --git a/doc/develop/bootstd/index.rst b/doc/develop/bootstd/index.rst
index 4c4e26ccdb707e55f88660395f23d7e7cda6b78d..ec74fc2fb9d7cccc48f3d16e781537190b5b6ced 100644
--- a/doc/develop/bootstd/index.rst
+++ b/doc/develop/bootstd/index.rst
@@ -12,5 +12,6 @@ Standard Boot
qfw
android
cros
+ rauc
script
sandbox
diff --git a/doc/develop/bootstd/overview.rst b/doc/develop/bootstd/overview.rst
index e3ce97cc4f5fad8fc6a5ce3f5ea76c7b93697b32..c046889b7fb25653969a65cd3c7b80589b833466 100644
--- a/doc/develop/bootstd/overview.rst
+++ b/doc/develop/bootstd/overview.rst
@@ -442,6 +442,7 @@ Bootmeth drivers are provided for booting from various media:
- :doc:`extlinux / syslinux <extlinux>` boot from a storage device
- :doc:`extlinux / syslinux <extlinux>` boot from a network (PXE)
- :doc:`sandbox <sandbox>` used only for testing
+ - :doc:`RAUC distro <rauc>`: A/B system with RAUC from MMC
- :doc:`U-Boot scripts <script>` from disk, network or SPI flash
- :doc:`QFW <qfw>`: QEMU firmware interface
- :doc:`VBE </develop/vbe>`: Verified Boot for Embedded
diff --git a/doc/develop/bootstd/rauc.rst b/doc/develop/bootstd/rauc.rst
new file mode 100644
index 0000000000000000000000000000000000000000..74ce24e8570d5cbcba7ec2066c20ef4fb5481455
--- /dev/null
+++ b/doc/develop/bootstd/rauc.rst
@@ -0,0 +1,55 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+RAUC Bootmeth
+=============
+
+This bootmeth provides a way to locate and run a A/B system with RAUC as its
+update client. The booted distro must supply a script on an MMC device
+containing the final boot instructions necessary.
+
+The boot script must be located in the partition provided by the slot
+configuration in the environment variable ``rauc_slots``. The bootmeth searches
+for "boot.scr.uimg" first, then "boot.scr" if not found.
+
+In addition, the RAUC binary and system configuration file must be present in
+the specified root filesystem.
+
+The settings for configuring the layout and partitions are done through the
+following variables:
+
+rauc_slots
+ If ``BOOT_ORDER`` is not set, this variable is used to set the default boot
+ order. It also specifies the order in which partition indexes are specified
+ in ``rauc_partitions``.
+
+rauc_partitions
+ This variable configures the boot and root partitions for each slot. The
+ content must be a list of pairs, with the following syntax: ``1,2 3,4``,
+ where 1 and 3 are the slots' boot partition and 2 and 4 the slots' root
+ partition.
+
+rauc_slot_default_tries
+ If slots have no variable ``BOOT_*_LEFT`` set, they are set with the value
+ of this variable.
+
+When the bootflow is booted, the bootmeth sets these environment variables:
+
+devtype
+ device type (e.g. "mmc")
+
+devnum
+ device number, corresponding to the device 'sequence' number
+ ``dev_seq(dev)``
+
+distro_bootpart
+ partition number on the device (numbered from 1)
+
+raucargs
+ kernel command line arguments needed for RAUC to detect the currently booted
+ slot
+
+The script file must be a FIT or a legacy uImage. It is loaded into memory and
+executed.
+
+The compatible string "u-boot,distro-rauc" is used for the driver. It is present
+if ``CONFIG_BOOTMETH_RAUC`` is enabled.
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-01-29 14:25 ` [PATCH 1/2] bootstd: Add implementation for bootmeth rauc Martin Schwan
@ 2025-01-29 16:03 ` Tom Rini
2025-01-30 9:48 ` Martin Schwan
2025-04-14 11:32 ` Simon Glass
2025-05-06 7:05 ` [Upstream] " Wadim Egorov
2 siblings, 1 reply; 20+ messages in thread
From: Tom Rini @ 2025-01-29 16:03 UTC (permalink / raw)
To: Martin Schwan; +Cc: Simon Glass, u-boot, upstream
[-- Attachment #1: Type: text/plain, Size: 684 bytes --]
On Wed, Jan 29, 2025 at 03:25:25PM +0100, Martin Schwan wrote:
> Add a bootmeth driver which supports booting A/B system with RAUC as
> their update client.
>
> Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> ---
> boot/Kconfig | 11 ++
> boot/Makefile | 1 +
> boot/bootmeth_rauc.c | 408 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 420 insertions(+)
I'm curious, what would be required to have this work for any block
device, rather than just "mmc" ? Just a lack of time / testing / this is
v1 and that's a future idea? Or is there something more fundamental
required within bootstd/bootmeths ? Thanks!
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-01-29 16:03 ` Tom Rini
@ 2025-01-30 9:48 ` Martin Schwan
2025-01-30 14:51 ` Tom Rini
0 siblings, 1 reply; 20+ messages in thread
From: Martin Schwan @ 2025-01-30 9:48 UTC (permalink / raw)
To: trini@konsulko.com
Cc: sjg@chromium.org, u-boot@lists.denx.de, upstream@lists.phytec.de
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
On Wed, 2025-01-29 at 10:03 -0600, Tom Rini wrote:
> On Wed, Jan 29, 2025 at 03:25:25PM +0100, Martin Schwan wrote:
> > Add a bootmeth driver which supports booting A/B system with RAUC
> > as
> > their update client.
> >
> > Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> > ---
> > boot/Kconfig | 11 ++
> > boot/Makefile | 1 +
> > boot/bootmeth_rauc.c | 408
> > +++++++++++++++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 420 insertions(+)
>
> I'm curious, what would be required to have this work for any block
> device, rather than just "mmc" ? Just a lack of time / testing / this
> is
> v1 and that's a future idea? Or is there something more fundamental
> required within bootstd/bootmeths ? Thanks!
>
Besides MMC, RAUC supports updating SSDs and raw NAND flash [1].
I guess there should be very little to no adjustments necessary to
support SSDs (probably only adjust checks).
For raw NAND flash and using UBI volumes, this would require some
additional code calling the correct read operations, but is definitely
possible. I did not implement it yet because of lack of time and
verification, as you correctly guessed.
Network devices are not supported for obvious reasons.
Regards,
Martin
[1]:
https://rauc.readthedocs.io/en/latest/integration.html#partitioning-your-device
-----BEGIN PGP SIGNATURE-----
iQFHBAEBCAAxFiEEvRVVC1N5GoUWk9IrDQIuwQKeD4IFAmebSuITHG0uc2Nod2Fu
QHBoeXRlYy5kZQAKCRANAi7BAp4PgoiuB/0QYPrKrpo+1ev+PuKDwt2811zr0nP9
0HUmz4Nv56CJj8Qc9S4NL2yyYrHgFAQ0xPcuYem20NEZZYcctKzX5pYrtu4vYOBm
WUsoj1+3TVIbQ+c2i/4NuKBPAgsad1wZcQY04cTrtAXzBWzNxI56kGP0PfLYV4ls
/O/xF0QamnjXQRtHUrv4kQOnqi+RBvQIxD7ICZ/7oiNfV4vK7hU8Vu7TnoOSZKCG
qNr5znXZgT8axLSdkE9VjX2IwpTm+ihuDe94/BrLg4E/54yBBcfKwPeYszFyDoXV
o8HNd1eyT137B9e3EHK2PC2hVhc5C/1V6RKG0SRI1bTTrdYNlSL0rfci
=gPis
-----END PGP SIGNATURE-----
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-01-30 9:48 ` Martin Schwan
@ 2025-01-30 14:51 ` Tom Rini
2025-04-14 5:49 ` Wadim Egorov
0 siblings, 1 reply; 20+ messages in thread
From: Tom Rini @ 2025-01-30 14:51 UTC (permalink / raw)
To: Martin Schwan
Cc: sjg@chromium.org, u-boot@lists.denx.de, upstream@lists.phytec.de
[-- Attachment #1: Type: text/plain, Size: 1485 bytes --]
On Thu, Jan 30, 2025 at 09:48:19AM +0000, Martin Schwan wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> On Wed, 2025-01-29 at 10:03 -0600, Tom Rini wrote:
> > On Wed, Jan 29, 2025 at 03:25:25PM +0100, Martin Schwan wrote:
> > > Add a bootmeth driver which supports booting A/B system with RAUC
> > > as
> > > their update client.
> > >
> > > Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> > > ---
> > > boot/Kconfig | 11 ++
> > > boot/Makefile | 1 +
> > > boot/bootmeth_rauc.c | 408
> > > +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > 3 files changed, 420 insertions(+)
> >
> > I'm curious, what would be required to have this work for any block
> > device, rather than just "mmc" ? Just a lack of time / testing / this
> > is
> > v1 and that's a future idea? Or is there something more fundamental
> > required within bootstd/bootmeths ? Thanks!
> >
>
> Besides MMC, RAUC supports updating SSDs and raw NAND flash [1].
>
> I guess there should be very little to no adjustments necessary to
> support SSDs (probably only adjust checks).
>
> For raw NAND flash and using UBI volumes, this would require some
> additional code calling the correct read operations, but is definitely
> possible. I did not implement it yet because of lack of time and
> verification, as you correctly guessed.
>
> Network devices are not supported for obvious reasons.
Thanks for elaborating.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-01-30 14:51 ` Tom Rini
@ 2025-04-14 5:49 ` Wadim Egorov
0 siblings, 0 replies; 20+ messages in thread
From: Wadim Egorov @ 2025-04-14 5:49 UTC (permalink / raw)
To: Tom Rini, Martin Schwan
Cc: sjg@chromium.org, u-boot@lists.denx.de, upstream@lists.phytec.de
Am 30.01.25 um 16:51 schrieb Tom Rini:
> On Thu, Jan 30, 2025 at 09:48:19AM +0000, Martin Schwan wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA256
>>
>> On Wed, 2025-01-29 at 10:03 -0600, Tom Rini wrote:
>>> On Wed, Jan 29, 2025 at 03:25:25PM +0100, Martin Schwan wrote:
>>>> Add a bootmeth driver which supports booting A/B system with RAUC
>>>> as
>>>> their update client.
>>>>
>>>> Signed-off-by: Martin Schwan <m.schwan@phytec.de>
>>>> ---
>>>> boot/Kconfig | 11 ++
>>>> boot/Makefile | 1 +
>>>> boot/bootmeth_rauc.c | 408
>>>> +++++++++++++++++++++++++++++++++++++++++++++++++++
>>>> 3 files changed, 420 insertions(+)
>>>
>>> I'm curious, what would be required to have this work for any block
>>> device, rather than just "mmc" ? Just a lack of time / testing / this
>>> is
>>> v1 and that's a future idea? Or is there something more fundamental
>>> required within bootstd/bootmeths ? Thanks!
>>>
>>
>> Besides MMC, RAUC supports updating SSDs and raw NAND flash [1].
>>
>> I guess there should be very little to no adjustments necessary to
>> support SSDs (probably only adjust checks).
>>
>> For raw NAND flash and using UBI volumes, this would require some
>> additional code calling the correct read operations, but is definitely
>> possible. I did not implement it yet because of lack of time and
>> verification, as you correctly guessed.
>>
>> Network devices are not supported for obvious reasons.
>
> Thanks for elaborating.
>
Any other comments on the RAUC bootmeth idea?
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-01-29 14:25 ` [PATCH 1/2] bootstd: Add implementation for bootmeth rauc Martin Schwan
2025-01-29 16:03 ` Tom Rini
@ 2025-04-14 11:32 ` Simon Glass
2025-04-24 12:43 ` Martin Schwan
2025-05-06 7:05 ` [Upstream] " Wadim Egorov
2 siblings, 1 reply; 20+ messages in thread
From: Simon Glass @ 2025-04-14 11:32 UTC (permalink / raw)
To: Martin Schwan; +Cc: Tom Rini, u-boot, upstream
Hi Martin,
On Wed, 29 Jan 2025 at 07:25, Martin Schwan <m.schwan@phytec.de> wrote:
>
> Add a bootmeth driver which supports booting A/B system with RAUC as
> their update client.
>
> Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> ---
> boot/Kconfig | 11 ++
> boot/Makefile | 1 +
> boot/bootmeth_rauc.c | 408 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 420 insertions(+)
This looks fine to me. Just some nits below.
But this bootmeth does need documentation in doc/develop/bootstd/ and
also a test, e.g. in test/boot/
>
> diff --git a/boot/Kconfig b/boot/Kconfig
> index 20935a269c60dad53ce11ac7e58247dc23cf617e..966573d8eb7675d36f299c8c2fa6509bac147cae 100644
> --- a/boot/Kconfig
> +++ b/boot/Kconfig
> @@ -782,6 +782,17 @@ config EXPO
> The expo can be presented in graphics form using a vidconsole, or in
> text form on a serial console.
>
> +config BOOTMETH_RAUC
> + bool "Bootdev support for RAUC A/B systems"
> + default y if BOOTSTD_FULL
> + depends on CMDLINE
> + select BOOTMETH_GLOBAL
> + select HUSH_PARSER
> + help
> + Enables support for booting RAUC A/B systems from MMC devices. This
> + makes the bootdevs look for a 'boot.scr.uimg' or 'boot.scr' in the
> + respective boot partitions, describing how to boot the distro.
> +
> config BOOTMETH_SANDBOX
> def_bool y
> depends on SANDBOX
> diff --git a/boot/Makefile b/boot/Makefile
> index c2753de8163cf59b1abdc01149a856e2847960e6..427898449a8727747137ab1c7c571c473148c8c3 100644
> --- a/boot/Makefile
> +++ b/boot/Makefile
> @@ -32,6 +32,7 @@ obj-$(CONFIG_$(PHASE_)BOOTMETH_EXTLINUX_PXE) += bootmeth_pxe.o
> obj-$(CONFIG_$(PHASE_)BOOTMETH_EFILOADER) += bootmeth_efi.o
> obj-$(CONFIG_$(PHASE_)BOOTMETH_CROS) += bootm.o bootm_os.o bootmeth_cros.o
> obj-$(CONFIG_$(PHASE_)BOOTMETH_QFW) += bootmeth_qfw.o
> +obj-$(CONFIG_$(PHASE_)BOOTMETH_RAUC) += bootmeth_rauc.o
> obj-$(CONFIG_$(PHASE_)BOOTMETH_SANDBOX) += bootmeth_sandbox.o
> obj-$(CONFIG_$(PHASE_)BOOTMETH_SCRIPT) += bootmeth_script.o
> obj-$(CONFIG_$(PHASE_)CEDIT) += cedit.o
> diff --git a/boot/bootmeth_rauc.c b/boot/bootmeth_rauc.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..fcb7e8df4556710b160349f1dcc54cdda9b59c9d
> --- /dev/null
> +++ b/boot/bootmeth_rauc.c
> @@ -0,0 +1,408 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Bootmethod for distro boot with RAUC
> + *
> + * Copyright 2025 PHYTEC Messtechnik GmbH
> + * Written by Martin Schwan <m.schwan@phytec.de>
> + */
> +
> +#define LOG_CATEGORY UCLASS_BOOTSTD
> +#define LOG_DEBUG
> +
> +#include <asm/cache.h>
That should go last.
> +#include <blk.h>
> +#include <bootflow.h>
> +#include <bootmeth.h>
> +#include <bootstd.h>
> +#include <dm.h>
> +#include <env.h>
> +#include <fs.h>
> +#include <malloc.h>
> +#include <mapmem.h>
> +#include <string.h>
> +
> +static const char * const script_names[] = { "boot.scr.uimg", "boot.scr", NULL };
> +static const char * const rauc_files[] = { "/usr/bin/rauc", "/etc/rauc/system.conf", NULL };
> +
> +/**
> + * struct distro_rauc_slot - Slot information
> + *
> + * @name The slot name
> + * @left The number of boot tries left
> + * @boot_part The boot partition number on disk
> + * @root_part The boot partition number on disk
> + */
> +struct distro_rauc_slot {
> + char *name;
> + ulong left;
> + int boot_part;
> + int root_part;
> +};
> +
> +/**
> + * struct distro_rauc_priv - Private data
> + *
> + * @slots All slots of the device in default order
> + * @boot_order The current boot order string containing the active slot names
> + */
> +struct distro_rauc_priv {
> + struct distro_rauc_slot *slots;
> + char *boot_order;
> +};
> +
> +static int distro_rauc_check(struct udevice *dev, struct bootflow_iter *iter)
> +{
> + /* This distro only works on whole MMC devices, as multiple partitions
> + * are needed for an A/B system. */
> + if (bootflow_iter_check_mmc(iter))
> + return log_msg_ret("mmc", -EOPNOTSUPP);
> + if (iter->part != 0)
if (iter->part)
> + return log_msg_ret("part", -EOPNOTSUPP);
> +
> + return 0;
> +}
> +
> +static int distro_rauc_scan_boot_part(struct bootflow *bflow)
> +{
> + struct blk_desc *desc;
> + struct distro_rauc_priv *priv;
> + int exists;
> + int i;
> + int j;
> + int ret;
> +
> + desc = dev_get_uclass_plat(bflow->blk);
> + if (!desc)
> + return log_msg_ret("desc", -ENOMEM);
That can't happen as the driver would never be bound in this case,
please remove.
> +
> + priv = bflow->bootmeth_priv;
> + if (!priv || !priv->slots || !priv->boot_order)
> + return log_msg_ret("priv", -EINVAL);
> +
> + for (i = 0; priv->slots[i].name != NULL; i++) {
> + exists = 0;
> + for (j = 0; script_names[j] != NULL; j++) {
> + ret = fs_set_blk_dev_with_part(desc, priv->slots[i].boot_part);
> + if (ret)
> + return log_msg_ret("blk", ret);
> + exists |= fs_exists(script_names[j]);
> + }
> + if (!exists)
> + return log_msg_ret("fs", -ENOENT);
> + }
> +
> + return 0;
> +}
> +
> +static int distro_rauc_scan_root_part(struct bootflow *bflow)
> +{
> + struct blk_desc *desc;
> + struct distro_rauc_priv *priv;
> + int exists;
> + int i;
> + int j;
> + int ret;
> +
> + desc = dev_get_uclass_plat(bflow->blk);
> + if (!desc)
> + return log_msg_ret("desc", -ENOMEM);
> +
> + priv = bflow->bootmeth_priv;
> + if (!priv || !priv->slots || !priv->boot_order)
> + return log_msg_ret("priv", -EINVAL);
> +
> + for (i = 0; priv->slots[i].name != NULL; i++) {
> + exists = 0;
bool exists = false; ?
> + for (j = 0; rauc_files[j] != NULL; j++) {
> + ret = fs_set_blk_dev_with_part(desc,
> + priv->slots[i].root_part);
> + if (ret)
> + return log_msg_ret("set", ret);
> + if (!fs_exists(rauc_files[j]))
> + return log_msg_ret("fs", -ENOENT);
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int distro_rauc_read_bootflow(struct udevice *dev, struct bootflow *bflow)
> +{
> + struct distro_rauc_priv *priv;
> + int ret;
> + char *slot;
> + int i;
> + char *boot_order;
> + char *partitions;
> + const char **partitions_list;
> + char *slots;
> + const char **slots_list;
> + char boot_left[32];
> + char *parts;
> + ulong default_tries;
> +
> + bflow->state = BOOTFLOWST_MEDIA;
> +
> + priv = malloc(sizeof(struct distro_rauc_priv));
> + if (!priv)
> + return log_msg_ret("buf", -ENOMEM);
> +
Please run checkpatch or patman to check this patch.
> +
> + partitions = env_get("rauc_partitions");
> + if (!partitions)
> + return log_msg_ret("env", -ENOENT);
> + partitions_list = str_to_list(partitions);
> +
> + slots = env_get("rauc_slots");
> + if (!slots)
> + return log_msg_ret("env", -ENOENT);
> + slots_list = str_to_list(slots);
> +
> + boot_order = env_get("BOOT_ORDER");
Environment variables should be in lower case.
> + if (!boot_order) {
> + if (env_set("BOOT_ORDER", slots))
> + return log_msg_ret("env", -EPERM);
> + }
> + priv->boot_order = strdup(boot_order);
> +
> + default_tries = env_get_ulong("rauc_slot_default_tries", 10, 3);
> + for (i = 0; slots_list[i] != NULL; i++) {
> + sprintf(boot_left, "BOOT_%s_LEFT", slots_list[i]);
same here
> + if (!env_get(boot_left))
> + env_set_ulong(boot_left, default_tries);
check error
> + }
> +
> + for (i = 0; slots_list[i] != NULL && partitions_list[i] != NULL; i++);
> + priv->slots = malloc((i + 1) * sizeof(struct distro_rauc_slot));
calloc?
> + if (!priv->slots)
> + return log_msg_ret("priv", -ENOMEM);
> + for (i = 0; slots_list[i] != NULL && partitions_list[i] != NULL; i++) {
> + priv->slots[i].name = strdup(slots_list[i]);
> + sprintf(boot_left, "BOOT_%s_LEFT", slot);
> + priv->slots[i].left = env_get_ulong(boot_left, 10, default_tries);
> + parts = strdup(partitions_list[i]);
> + priv->slots[i].boot_part = simple_strtoul(strsep(&parts, ","), NULL, 10);
> + priv->slots[i].root_part = simple_strtoul(strsep(&parts, ","), NULL, 10);
> + free(parts);
> + parts = NULL;
> + }
> + priv->slots[i].name = NULL;
> + priv->slots[i].left = 0;
> + priv->slots[i].boot_part = 0;
> + priv->slots[i].root_part = 0;
> +
> + bflow->bootmeth_priv = priv;
> + bflow->state = BOOTFLOWST_FS;
> +
> + ret = distro_rauc_scan_boot_part(bflow);
> + if (ret < 0)
> + goto free_priv;
> + ret = distro_rauc_scan_root_part(bflow);
> + if (ret < 0)
> + goto free_priv;
> +
> + bflow->state = BOOTFLOWST_READY;
> +
> + return 0;
> +
> +free_priv:
> + for (i = 0; priv->slots[i].name != NULL; i++)
> + free(priv->slots[i].name);
> + free(priv->slots);
> + free(priv);
> + bflow->bootmeth_priv = NULL;
blank line here
> + return ret;
> +}
> +
> +static int distro_rauc_read_file(struct udevice *dev, struct bootflow *bflow,
> + const char *file_path, ulong addr,
> + enum bootflow_img_t type, ulong *sizep)
> +{
> + /* Reading individual files is not supported since we only operate on
> + * whole MMC devices (because we require multiple partitions)
> + */
> + return log_msg_ret("Unsupported", -ENOSYS);
> +}
> +
> +static int distro_rauc_load_boot_script(struct bootflow *bflow, const char *slot)
please as a comment, as I'm not sure what a slot is
> +{
> + struct blk_desc *desc;
> + struct distro_rauc_priv *priv;
> + const char *prefix = "/";
> + int ret;
> + int i;
> +
> + if (!slot)
> + return log_msg_ret("slot", -EINVAL);
> +
> + desc = dev_get_uclass_plat(bflow->blk);
> + priv = bflow->bootmeth_priv;
> +
> + bflow->part = 0;
Isn't it already 0 ?
> + for (i = 0; priv->slots[i].name != NULL; i++) {
> + if (strcmp(priv->slots[i].name, slot) == 0) {
> + bflow->part = priv->slots[i].boot_part;
> + break;
> + }
> + }
> + if (!bflow->part)
> + return log_msg_ret("part", -ENOENT);
> +
> + ret = bootmeth_setup_fs(bflow, desc);
> + if (ret)
> + return log_msg_ret("set", ret);
> +
> + for (i = 0; script_names[i] != NULL; i++) {
Drop the '!= NULL' here and above
> + if (!bootmeth_try_file(bflow, desc, prefix, script_names[i]))
> + break;
> + }
> + if (bflow->state != BOOTFLOWST_FILE)
> + return log_msg_ret("file", -ENOENT);
> +
> + bflow->subdir = strdup(prefix);
> +
> + ret = bootmeth_alloc_file(bflow, 0x10000, ARCH_DMA_MINALIGN,
> + (enum bootflow_img_t)IH_TYPE_SCRIPT);
> + if (ret)
> + return log_msg_ret("read", ret);
> +
> + return 0;
> +}
> +
> +static int decrement_slot_tries(const char *slot)
> +{
> + ulong tries;
> + char boot_left[32];
> +
> + sprintf(boot_left, "BOOT_%s_LEFT", slot);
lower case
> + tries = env_get_ulong(boot_left, 10, ULONG_MAX);
> + if (tries == ULONG_MAX)
> + return log_msg_ret("env", -ENOENT);
> + if (tries <= 0)
> + return 0;
> +
> + return env_set_ulong(boot_left, tries - 1);
> +}
> +
> +static int distro_rauc_boot(struct udevice *dev, struct bootflow *bflow)
> +{
> + struct blk_desc *desc;
> + struct distro_rauc_priv *priv;
> + char *boot_order;
> + const char **boot_order_list;
> + const char *active_slot;
> + char raucargs[32];
> + ulong addr;
> + int ret = 0;
> + int i;
> +
> + desc = dev_get_uclass_plat(bflow->blk);
> + if (desc->uclass_id != UCLASS_MMC)
> + return log_msg_ret("blk", -EINVAL);
> + priv = bflow->bootmeth_priv;
> +
> + /* RAUC variables */
> + boot_order = env_get("BOOT_ORDER");
> + if (!boot_order)
> + return log_msg_ret("env", -ENOENT);
> + boot_order_list = str_to_list(boot_order);
> +
> + /* Device info variables */
> + ret = env_set("devtype", blk_get_devtype(bflow->blk));
> + if (ret)
> + return log_msg_ret("env", ret);
> +
> + ret = env_set_hex("devnum", desc->devnum);
> + if (ret)
> + return log_msg_ret("env", ret);
> +
> + /* Kernel command line arguments */
> + active_slot = strdup(boot_order_list[0]);
> + if (!active_slot)
> + return log_msg_ret("env", -ENOENT);
> + sprintf(raucargs, "rauc.slot=%s", active_slot);
> + ret = env_set("raucargs", raucargs);
> + if (ret)
> + return log_msg_ret("env", ret);
> +
> + /* TODO: If active_slot is in boot_order, but has 0 tries left, remove
/*
* TODO: ...
> + * it from boot_order. Then, set active_slot to other, if available.
> + */
> +
> + /* Partition info variables */
> + for (i = 0; priv->slots[i].name != NULL; i++) {
> + if (strcmp(priv->slots[i].name, active_slot) == 0) {
> + ret = env_set_hex("mmcroot", priv->slots[i].root_part);
> + if (ret)
> + return log_msg_ret("env", ret);
> + break;
> + }
> + }
> +
> + /* Load distro boot script */
> + ret = distro_rauc_load_boot_script(bflow, active_slot);
> + if (ret)
> + return log_msg_ret("load", ret);
> + ret = env_set_hex("distro_bootpart", bflow->part);
> + if (ret)
> + return log_msg_ret("env", ret);
> +
> + ret = decrement_slot_tries(active_slot);
> + if (ret)
> + return log_msg_ret("env", ret);
> + ret = env_save();
> + if (ret)
> + return log_msg_ret("env", ret);
> +
> + log_debug("devtype: %s\n", env_get("devtype"));
> + log_debug("devnum: %s\n", env_get("devnum"));
> + log_debug("distro_bootpart: %s\n", env_get("distro_bootpart"));
> + log_debug("mmcroot: %s\n", env_get("mmcroot"));
> + log_debug("raucargs: %s\n", env_get("raucargs"));
> + log_debug("rauc_slots: %s\n", env_get("rauc_slots"));
> + log_debug("rauc_partitions: %s\n", env_get("rauc_partitions"));
> + log_debug("rauc_slot_default_tries: %s\n", env_get("rauc_slot_default_tries"));
> + log_debug("BOOT_ORDER: %s\n", env_get("BOOT_ORDER"));
> + for (i = 0; priv->slots[i].name != NULL; i++) {
> + log_debug("BOOT_%s_LEFT: %ld\n", priv->slots[i].name,
> + priv->slots[i].left);
> + }
> +
> + /* Run distro boot script */
> + addr = map_to_sysmem(bflow->buf);
> + ret = cmd_source_script(addr, NULL, NULL);
> + if (ret)
> + return log_msg_ret("boot", ret);
> +
> + return 0;
> +}
> +
> +static int distro_rauc_bootmeth_bind(struct udevice *dev)
> +{
> + struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
> +
> + plat->desc = "RAUC distro boot from MMC";
> + plat->flags = BOOTMETHF_ANY_PART;
> +
> + return 0;
> +}
> +
> +static struct bootmeth_ops distro_rauc_bootmeth_ops = {
> + .check = distro_rauc_check,
> + .read_bootflow = distro_rauc_read_bootflow,
> + .read_file = distro_rauc_read_file,
> + .boot = distro_rauc_boot,
> +};
> +
> +static const struct udevice_id distro_rauc_bootmeth_ids[] = {
> + { .compatible = "u-boot,distro-rauc" },
> + { }
> +};
> +
> +U_BOOT_DRIVER(bootmeth_rauc) = {
> + .name = "bootmeth_rauc",
> + .id = UCLASS_BOOTMETH,
> + .of_match = distro_rauc_bootmeth_ids,
> + .ops = &distro_rauc_bootmeth_ops,
> + .bind = distro_rauc_bootmeth_bind,
> +};
>
> --
> 2.48.1
>
Regards,
SImon
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-04-14 11:32 ` Simon Glass
@ 2025-04-24 12:43 ` Martin Schwan
2025-04-24 18:31 ` Simon Glass
0 siblings, 1 reply; 20+ messages in thread
From: Martin Schwan @ 2025-04-24 12:43 UTC (permalink / raw)
To: Simon Glass; +Cc: Tom Rini, u-boot@lists.denx.de, upstream@lists.phytec.de
Hi Simon,
thanks for the review and sorry for my delayed reply.
On Mon, 2025-04-14 at 05:32 -0600, Simon Glass wrote:
> Hi Martin,
>
> On Wed, 29 Jan 2025 at 07:25, Martin Schwan <m.schwan@phytec.de>
> wrote:
> >
> > Add a bootmeth driver which supports booting A/B system with RAUC
> > as
> > their update client.
> >
> > Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> > ---
> > boot/Kconfig | 11 ++
> > boot/Makefile | 1 +
> > boot/bootmeth_rauc.c | 408
> > +++++++++++++++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 420 insertions(+)
>
> This looks fine to me. Just some nits below.
>
> But this bootmeth does need documentation in doc/develop/bootstd/ and
Have a look at the second patch in this series, which exactly adds this
documentation:
[PATCH 2/2] doc: Add description for bootmeth rauc
> also a test, e.g. in test/boot/
Thanks, I will look into it.
>
> >
> > diff --git a/boot/Kconfig b/boot/Kconfig
> > index
> > 20935a269c60dad53ce11ac7e58247dc23cf617e..966573d8eb7675d36f299c8c2
> > fa6509bac147cae 100644
> > --- a/boot/Kconfig
> > +++ b/boot/Kconfig
> > @@ -782,6 +782,17 @@ config EXPO
> > The expo can be presented in graphics form using a
> > vidconsole, or in
> > text form on a serial console.
> >
> > +config BOOTMETH_RAUC
> > + bool "Bootdev support for RAUC A/B systems"
> > + default y if BOOTSTD_FULL
> > + depends on CMDLINE
> > + select BOOTMETH_GLOBAL
> > + select HUSH_PARSER
> > + help
> > + Enables support for booting RAUC A/B systems from MMC
> > devices. This
> > + makes the bootdevs look for a 'boot.scr.uimg' or
> > 'boot.scr' in the
> > + respective boot partitions, describing how to boot the
> > distro.
> > +
> > config BOOTMETH_SANDBOX
> > def_bool y
> > depends on SANDBOX
> > diff --git a/boot/Makefile b/boot/Makefile
> > index
> > c2753de8163cf59b1abdc01149a856e2847960e6..427898449a8727747137ab1c7
> > c571c473148c8c3 100644
> > --- a/boot/Makefile
> > +++ b/boot/Makefile
> > @@ -32,6 +32,7 @@ obj-$(CONFIG_$(PHASE_)BOOTMETH_EXTLINUX_PXE) +=
> > bootmeth_pxe.o
> > obj-$(CONFIG_$(PHASE_)BOOTMETH_EFILOADER) += bootmeth_efi.o
> > obj-$(CONFIG_$(PHASE_)BOOTMETH_CROS) += bootm.o bootm_os.o
> > bootmeth_cros.o
> > obj-$(CONFIG_$(PHASE_)BOOTMETH_QFW) += bootmeth_qfw.o
> > +obj-$(CONFIG_$(PHASE_)BOOTMETH_RAUC) += bootmeth_rauc.o
> > obj-$(CONFIG_$(PHASE_)BOOTMETH_SANDBOX) += bootmeth_sandbox.o
> > obj-$(CONFIG_$(PHASE_)BOOTMETH_SCRIPT) += bootmeth_script.o
> > obj-$(CONFIG_$(PHASE_)CEDIT) += cedit.o
> > diff --git a/boot/bootmeth_rauc.c b/boot/bootmeth_rauc.c
> > new file mode 100644
> > index
> > 0000000000000000000000000000000000000000..fcb7e8df4556710b160349f1d
> > cc54cdda9b59c9d
> > --- /dev/null
> > +++ b/boot/bootmeth_rauc.c
> > @@ -0,0 +1,408 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Bootmethod for distro boot with RAUC
> > + *
> > + * Copyright 2025 PHYTEC Messtechnik GmbH
> > + * Written by Martin Schwan <m.schwan@phytec.de>
> > + */
> > +
> > +#define LOG_CATEGORY UCLASS_BOOTSTD
> > +#define LOG_DEBUG
> > +
> > +#include <asm/cache.h>
>
> That should go last.
Okay, will do so in a v2.
>
> > +#include <blk.h>
> > +#include <bootflow.h>
> > +#include <bootmeth.h>
> > +#include <bootstd.h>
> > +#include <dm.h>
> > +#include <env.h>
> > +#include <fs.h>
> > +#include <malloc.h>
> > +#include <mapmem.h>
> > +#include <string.h>
> > +
> > +static const char * const script_names[] = { "boot.scr.uimg",
> > "boot.scr", NULL };
> > +static const char * const rauc_files[] = { "/usr/bin/rauc",
> > "/etc/rauc/system.conf", NULL };
> > +
> > +/**
> > + * struct distro_rauc_slot - Slot information
> > + *
> > + * @name The slot name
> > + * @left The number of boot tries left
> > + * @boot_part The boot partition number on disk
> > + * @root_part The boot partition number on disk
> > + */
> > +struct distro_rauc_slot {
> > + char *name;
> > + ulong left;
> > + int boot_part;
> > + int root_part;
> > +};
> > +
> > +/**
> > + * struct distro_rauc_priv - Private data
> > + *
> > + * @slots All slots of the device in default order
> > + * @boot_order The current boot order string containing the active
> > slot names
> > + */
> > +struct distro_rauc_priv {
> > + struct distro_rauc_slot *slots;
> > + char *boot_order;
> > +};
> > +
> > +static int distro_rauc_check(struct udevice *dev, struct
> > bootflow_iter *iter)
> > +{
> > + /* This distro only works on whole MMC devices, as multiple
> > partitions
> > + * are needed for an A/B system. */
> > + if (bootflow_iter_check_mmc(iter))
> > + return log_msg_ret("mmc", -EOPNOTSUPP);
> > + if (iter->part != 0)
>
> if (iter->part)
Okay!
>
> > + return log_msg_ret("part", -EOPNOTSUPP);
> > +
> > + return 0;
> > +}
> > +
> > +static int distro_rauc_scan_boot_part(struct bootflow *bflow)
> > +{
> > + struct blk_desc *desc;
> > + struct distro_rauc_priv *priv;
> > + int exists;
> > + int i;
> > + int j;
> > + int ret;
> > +
> > + desc = dev_get_uclass_plat(bflow->blk);
> > + if (!desc)
> > + return log_msg_ret("desc", -ENOMEM);
>
> That can't happen as the driver would never be bound in this case,
> please remove.
Will do.
>
> > +
> > + priv = bflow->bootmeth_priv;
> > + if (!priv || !priv->slots || !priv->boot_order)
> > + return log_msg_ret("priv", -EINVAL);
> > +
> > + for (i = 0; priv->slots[i].name != NULL; i++) {
> > + exists = 0;
> > + for (j = 0; script_names[j] != NULL; j++) {
> > + ret = fs_set_blk_dev_with_part(desc, priv-
> > >slots[i].boot_part);
> > + if (ret)
> > + return log_msg_ret("blk", ret);
> > + exists |= fs_exists(script_names[j]);
> > + }
> > + if (!exists)
> > + return log_msg_ret("fs", -ENOENT);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int distro_rauc_scan_root_part(struct bootflow *bflow)
> > +{
> > + struct blk_desc *desc;
> > + struct distro_rauc_priv *priv;
> > + int exists;
> > + int i;
> > + int j;
> > + int ret;
> > +
> > + desc = dev_get_uclass_plat(bflow->blk);
> > + if (!desc)
> > + return log_msg_ret("desc", -ENOMEM);
> > +
> > + priv = bflow->bootmeth_priv;
> > + if (!priv || !priv->slots || !priv->boot_order)
> > + return log_msg_ret("priv", -EINVAL);
> > +
> > + for (i = 0; priv->slots[i].name != NULL; i++) {
> > + exists = 0;
>
> bool exists = false; ?
"exists" is set from fs_exists(), which returns an int and I did not
want to alter the type. Though in this case, that wouldn't do much
harm, as int is the same as bool.
Though I noticed, "exists" seems to be a leftover in the root scanning
part. I will remove it from there.
>
> > + for (j = 0; rauc_files[j] != NULL; j++) {
> > + ret = fs_set_blk_dev_with_part(desc,
> > + priv->slots[i].root_part);
> > + if (ret)
> > + return log_msg_ret("set", ret);
> > + if (!fs_exists(rauc_files[j]))
> > + return log_msg_ret("fs", -ENOENT);
> > + }
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int distro_rauc_read_bootflow(struct udevice *dev, struct
> > bootflow *bflow)
> > +{
> > + struct distro_rauc_priv *priv;
> > + int ret;
> > + char *slot;
> > + int i;
> > + char *boot_order;
> > + char *partitions;
> > + const char **partitions_list;
> > + char *slots;
> > + const char **slots_list;
> > + char boot_left[32];
> > + char *parts;
> > + ulong default_tries;
> > +
> > + bflow->state = BOOTFLOWST_MEDIA;
> > +
> > + priv = malloc(sizeof(struct distro_rauc_priv));
> > + if (!priv)
> > + return log_msg_ret("buf", -ENOMEM);
> > +
>
> Please run checkpatch or patman to check this patch.
Will do.
>
> > +
> > + partitions = env_get("rauc_partitions");
> > + if (!partitions)
> > + return log_msg_ret("env", -ENOENT);
> > + partitions_list = str_to_list(partitions);
> > +
> > + slots = env_get("rauc_slots");
> > + if (!slots)
> > + return log_msg_ret("env", -ENOENT);
> > + slots_list = str_to_list(slots);
> > +
> > + boot_order = env_get("BOOT_ORDER");
>
> Environment variables should be in lower case.
Unfortunately, we are bound to the naming RAUC uses for these
environment variables, which is upper case. See
https://rauc.readthedocs.io/en/latest/integration.html#set-up-u-boot-boot-script-for-rauc
>
> > + if (!boot_order) {
> > + if (env_set("BOOT_ORDER", slots))
> > + return log_msg_ret("env", -EPERM);
> > + }
> > + priv->boot_order = strdup(boot_order);
> > +
> > + default_tries = env_get_ulong("rauc_slot_default_tries",
> > 10, 3);
> > + for (i = 0; slots_list[i] != NULL; i++) {
> > + sprintf(boot_left, "BOOT_%s_LEFT", slots_list[i]);
>
> same here
>
> > + if (!env_get(boot_left))
> > + env_set_ulong(boot_left, default_tries);
>
> check error
Will do.
>
> > + }
> > +
> > + for (i = 0; slots_list[i] != NULL && partitions_list[i] !=
> > NULL; i++);
> > + priv->slots = malloc((i + 1) * sizeof(struct
> > distro_rauc_slot));
>
> calloc?
Yes, that's better in this situation indeed and would simplify things.
>
> > + if (!priv->slots)
> > + return log_msg_ret("priv", -ENOMEM);
> > + for (i = 0; slots_list[i] != NULL && partitions_list[i] !=
> > NULL; i++) {
> > + priv->slots[i].name = strdup(slots_list[i]);
> > + sprintf(boot_left, "BOOT_%s_LEFT", slot);
> > + priv->slots[i].left = env_get_ulong(boot_left, 10,
> > default_tries);
> > + parts = strdup(partitions_list[i]);
> > + priv->slots[i].boot_part =
> > simple_strtoul(strsep(&parts, ","), NULL, 10);
> > + priv->slots[i].root_part =
> > simple_strtoul(strsep(&parts, ","), NULL, 10);
> > + free(parts);
> > + parts = NULL;
> > + }
> > + priv->slots[i].name = NULL;
> > + priv->slots[i].left = 0;
> > + priv->slots[i].boot_part = 0;
> > + priv->slots[i].root_part = 0;
> > +
> > + bflow->bootmeth_priv = priv;
> > + bflow->state = BOOTFLOWST_FS;
> > +
> > + ret = distro_rauc_scan_boot_part(bflow);
> > + if (ret < 0)
> > + goto free_priv;
> > + ret = distro_rauc_scan_root_part(bflow);
> > + if (ret < 0)
> > + goto free_priv;
> > +
> > + bflow->state = BOOTFLOWST_READY;
> > +
> > + return 0;
> > +
> > +free_priv:
> > + for (i = 0; priv->slots[i].name != NULL; i++)
> > + free(priv->slots[i].name);
> > + free(priv->slots);
> > + free(priv);
> > + bflow->bootmeth_priv = NULL;
>
> blank line here
Okay!
>
> > + return ret;
> > +}
> > +
> > +static int distro_rauc_read_file(struct udevice *dev, struct
> > bootflow *bflow,
> > + const char *file_path, ulong addr,
> > + enum bootflow_img_t type, ulong
> > *sizep)
> > +{
> > + /* Reading individual files is not supported since we only
> > operate on
> > + * whole MMC devices (because we require multiple
> > partitions)
> > + */
> > + return log_msg_ret("Unsupported", -ENOSYS);
> > +}
> > +
> > +static int distro_rauc_load_boot_script(struct bootflow *bflow,
> > const char *slot)
>
> please as a comment, as I'm not sure what a slot is
In short, this refers to RAUC's definition of a "slot". I will add a
comment in v2.
>
> > +{
> > + struct blk_desc *desc;
> > + struct distro_rauc_priv *priv;
> > + const char *prefix = "/";
> > + int ret;
> > + int i;
> > +
> > + if (!slot)
> > + return log_msg_ret("slot", -EINVAL);
> > +
> > + desc = dev_get_uclass_plat(bflow->blk);
> > + priv = bflow->bootmeth_priv;
> > +
> > + bflow->part = 0;
>
> Isn't it already 0 ?
Seems so. I will check again and remove it, if not needed.
>
> > + for (i = 0; priv->slots[i].name != NULL; i++) {
> > + if (strcmp(priv->slots[i].name, slot) == 0) {
> > + bflow->part = priv->slots[i].boot_part;
> > + break;
> > + }
> > + }
> > + if (!bflow->part)
> > + return log_msg_ret("part", -ENOENT);
> > +
> > + ret = bootmeth_setup_fs(bflow, desc);
> > + if (ret)
> > + return log_msg_ret("set", ret);
> > +
> > + for (i = 0; script_names[i] != NULL; i++) {
>
> Drop the '!= NULL' here and above
Will do.
>
> > + if (!bootmeth_try_file(bflow, desc, prefix,
> > script_names[i]))
> > + break;
> > + }
> > + if (bflow->state != BOOTFLOWST_FILE)
> > + return log_msg_ret("file", -ENOENT);
> > +
> > + bflow->subdir = strdup(prefix);
> > +
> > + ret = bootmeth_alloc_file(bflow, 0x10000,
> > ARCH_DMA_MINALIGN,
> > + (enum
> > bootflow_img_t)IH_TYPE_SCRIPT);
> > + if (ret)
> > + return log_msg_ret("read", ret);
> > +
> > + return 0;
> > +}
> > +
> > +static int decrement_slot_tries(const char *slot)
> > +{
> > + ulong tries;
> > + char boot_left[32];
> > +
> > + sprintf(boot_left, "BOOT_%s_LEFT", slot);
>
> lower case
>
> > + tries = env_get_ulong(boot_left, 10, ULONG_MAX);
> > + if (tries == ULONG_MAX)
> > + return log_msg_ret("env", -ENOENT);
> > + if (tries <= 0)
> > + return 0;
> > +
> > + return env_set_ulong(boot_left, tries - 1);
> > +}
> > +
> > +static int distro_rauc_boot(struct udevice *dev, struct bootflow
> > *bflow)
> > +{
> > + struct blk_desc *desc;
> > + struct distro_rauc_priv *priv;
> > + char *boot_order;
> > + const char **boot_order_list;
> > + const char *active_slot;
> > + char raucargs[32];
> > + ulong addr;
> > + int ret = 0;
> > + int i;
> > +
> > + desc = dev_get_uclass_plat(bflow->blk);
> > + if (desc->uclass_id != UCLASS_MMC)
> > + return log_msg_ret("blk", -EINVAL);
> > + priv = bflow->bootmeth_priv;
> > +
> > + /* RAUC variables */
> > + boot_order = env_get("BOOT_ORDER");
> > + if (!boot_order)
> > + return log_msg_ret("env", -ENOENT);
> > + boot_order_list = str_to_list(boot_order);
> > +
> > + /* Device info variables */
> > + ret = env_set("devtype", blk_get_devtype(bflow->blk));
> > + if (ret)
> > + return log_msg_ret("env", ret);
> > +
> > + ret = env_set_hex("devnum", desc->devnum);
> > + if (ret)
> > + return log_msg_ret("env", ret);
> > +
> > + /* Kernel command line arguments */
> > + active_slot = strdup(boot_order_list[0]);
> > + if (!active_slot)
> > + return log_msg_ret("env", -ENOENT);
> > + sprintf(raucargs, "rauc.slot=%s", active_slot);
> > + ret = env_set("raucargs", raucargs);
> > + if (ret)
> > + return log_msg_ret("env", ret);
> > +
> > + /* TODO: If active_slot is in boot_order, but has 0 tries
> > left, remove
>
> /*
> * TODO: ...
Okay!
Thanks again!
Regards,
Martin
>
> > + * it from boot_order. Then, set active_slot to other, if
> > available.
> > + */
> > +
> > + /* Partition info variables */
> > + for (i = 0; priv->slots[i].name != NULL; i++) {
> > + if (strcmp(priv->slots[i].name, active_slot) == 0)
> > {
> > + ret = env_set_hex("mmcroot", priv-
> > >slots[i].root_part);
> > + if (ret)
> > + return log_msg_ret("env", ret);
> > + break;
> > + }
> > + }
> > +
> > + /* Load distro boot script */
> > + ret = distro_rauc_load_boot_script(bflow, active_slot);
> > + if (ret)
> > + return log_msg_ret("load", ret);
> > + ret = env_set_hex("distro_bootpart", bflow->part);
> > + if (ret)
> > + return log_msg_ret("env", ret);
> > +
> > + ret = decrement_slot_tries(active_slot);
> > + if (ret)
> > + return log_msg_ret("env", ret);
> > + ret = env_save();
> > + if (ret)
> > + return log_msg_ret("env", ret);
> > +
> > + log_debug("devtype: %s\n", env_get("devtype"));
> > + log_debug("devnum: %s\n", env_get("devnum"));
> > + log_debug("distro_bootpart: %s\n",
> > env_get("distro_bootpart"));
> > + log_debug("mmcroot: %s\n", env_get("mmcroot"));
> > + log_debug("raucargs: %s\n", env_get("raucargs"));
> > + log_debug("rauc_slots: %s\n", env_get("rauc_slots"));
> > + log_debug("rauc_partitions: %s\n",
> > env_get("rauc_partitions"));
> > + log_debug("rauc_slot_default_tries: %s\n",
> > env_get("rauc_slot_default_tries"));
> > + log_debug("BOOT_ORDER: %s\n", env_get("BOOT_ORDER"));
> > + for (i = 0; priv->slots[i].name != NULL; i++) {
> > + log_debug("BOOT_%s_LEFT: %ld\n", priv-
> > >slots[i].name,
> > + priv->slots[i].left);
> > + }
> > +
> > + /* Run distro boot script */
> > + addr = map_to_sysmem(bflow->buf);
> > + ret = cmd_source_script(addr, NULL, NULL);
> > + if (ret)
> > + return log_msg_ret("boot", ret);
> > +
> > + return 0;
> > +}
> > +
> > +static int distro_rauc_bootmeth_bind(struct udevice *dev)
> > +{
> > + struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
> > +
> > + plat->desc = "RAUC distro boot from MMC";
> > + plat->flags = BOOTMETHF_ANY_PART;
> > +
> > + return 0;
> > +}
> > +
> > +static struct bootmeth_ops distro_rauc_bootmeth_ops = {
> > + .check = distro_rauc_check,
> > + .read_bootflow = distro_rauc_read_bootflow,
> > + .read_file = distro_rauc_read_file,
> > + .boot = distro_rauc_boot,
> > +};
> > +
> > +static const struct udevice_id distro_rauc_bootmeth_ids[] = {
> > + { .compatible = "u-boot,distro-rauc" },
> > + { }
> > +};
> > +
> > +U_BOOT_DRIVER(bootmeth_rauc) = {
> > + .name = "bootmeth_rauc",
> > + .id = UCLASS_BOOTMETH,
> > + .of_match = distro_rauc_bootmeth_ids,
> > + .ops = &distro_rauc_bootmeth_ops,
> > + .bind = distro_rauc_bootmeth_bind,
> > +};
> >
> > --
> > 2.48.1
> >
>
> Regards,
> SImon
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-04-24 12:43 ` Martin Schwan
@ 2025-04-24 18:31 ` Simon Glass
2025-04-24 18:49 ` Tom Rini
0 siblings, 1 reply; 20+ messages in thread
From: Simon Glass @ 2025-04-24 18:31 UTC (permalink / raw)
To: Martin Schwan; +Cc: Tom Rini, u-boot@lists.denx.de, upstream@lists.phytec.de
Hi Martin,
On Thu, 24 Apr 2025 at 06:43, Martin Schwan <M.Schwan@phytec.de> wrote:
>
> Hi Simon,
>
> thanks for the review and sorry for my delayed reply.
>
> On Mon, 2025-04-14 at 05:32 -0600, Simon Glass wrote:
> > Hi Martin,
> >
> > On Wed, 29 Jan 2025 at 07:25, Martin Schwan <m.schwan@phytec.de>
> > wrote:
> > >
> > > Add a bootmeth driver which supports booting A/B system with RAUC
> > > as
> > > their update client.
> > >
> > > Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> > > ---
> > > boot/Kconfig | 11 ++
> > > boot/Makefile | 1 +
> > > boot/bootmeth_rauc.c | 408
> > > +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > 3 files changed, 420 insertions(+)
> >
> > This looks fine to me. Just some nits below.
> >
[..]
> > > +
> > > + partitions = env_get("rauc_partitions");
> > > + if (!partitions)
> > > + return log_msg_ret("env", -ENOENT);
> > > + partitions_list = str_to_list(partitions);
> > > +
> > > + slots = env_get("rauc_slots");
> > > + if (!slots)
> > > + return log_msg_ret("env", -ENOENT);
> > > + slots_list = str_to_list(slots);
> > > +
> > > + boot_order = env_get("BOOT_ORDER");
> >
> > Environment variables should be in lower case.
>
> Unfortunately, we are bound to the naming RAUC uses for these
> environment variables, which is upper case. See
> https://rauc.readthedocs.io/en/latest/integration.html#set-up-u-boot-boot-script-for-rauc
Can't you change it, since you are introducing new support here?
If not, then you could perhaps set the env variables to lowercase when
you find uppercase variables? I suppose that would require updating
the client to do the same thing too?
It would be very confusing for a user to have upper-case variables for
some things.
>
> >
> > > + if (!boot_order) {
> > > + if (env_set("BOOT_ORDER", slots))
> > > + return log_msg_ret("env", -EPERM);
> > > + }
> > > + priv->boot_order = strdup(boot_order);
> > > +
> > > + default_tries = env_get_ulong("rauc_slot_default_tries",
> > > 10, 3);
> > > + for (i = 0; slots_list[i] != NULL; i++) {
> > > + sprintf(boot_left, "BOOT_%s_LEFT", slots_list[i]);
> >
> > same here
[..]
Regards,
Simon
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-04-24 18:31 ` Simon Glass
@ 2025-04-24 18:49 ` Tom Rini
2025-04-25 14:35 ` Simon Glass
0 siblings, 1 reply; 20+ messages in thread
From: Tom Rini @ 2025-04-24 18:49 UTC (permalink / raw)
To: Simon Glass; +Cc: Martin Schwan, u-boot@lists.denx.de, upstream@lists.phytec.de
[-- Attachment #1: Type: text/plain, Size: 2273 bytes --]
On Thu, Apr 24, 2025 at 12:31:38PM -0600, Simon Glass wrote:
> Hi Martin,
>
> On Thu, 24 Apr 2025 at 06:43, Martin Schwan <M.Schwan@phytec.de> wrote:
> >
> > Hi Simon,
> >
> > thanks for the review and sorry for my delayed reply.
> >
> > On Mon, 2025-04-14 at 05:32 -0600, Simon Glass wrote:
> > > Hi Martin,
> > >
> > > On Wed, 29 Jan 2025 at 07:25, Martin Schwan <m.schwan@phytec.de>
> > > wrote:
> > > >
> > > > Add a bootmeth driver which supports booting A/B system with RAUC
> > > > as
> > > > their update client.
> > > >
> > > > Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> > > > ---
> > > > boot/Kconfig | 11 ++
> > > > boot/Makefile | 1 +
> > > > boot/bootmeth_rauc.c | 408
> > > > +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > 3 files changed, 420 insertions(+)
> > >
> > > This looks fine to me. Just some nits below.
> > >
>
> [..]
>
> > > > +
> > > > + partitions = env_get("rauc_partitions");
> > > > + if (!partitions)
> > > > + return log_msg_ret("env", -ENOENT);
> > > > + partitions_list = str_to_list(partitions);
> > > > +
> > > > + slots = env_get("rauc_slots");
> > > > + if (!slots)
> > > > + return log_msg_ret("env", -ENOENT);
> > > > + slots_list = str_to_list(slots);
> > > > +
> > > > + boot_order = env_get("BOOT_ORDER");
> > >
> > > Environment variables should be in lower case.
> >
> > Unfortunately, we are bound to the naming RAUC uses for these
> > environment variables, which is upper case. See
> > https://rauc.readthedocs.io/en/latest/integration.html#set-up-u-boot-boot-script-for-rauc
>
> Can't you change it, since you are introducing new support here?
>
> If not, then you could perhaps set the env variables to lowercase when
> you find uppercase variables? I suppose that would require updating
> the client to do the same thing too?
>
> It would be very confusing for a user to have upper-case variables for
> some things.
Simon, this is an unreasonable request. This is how RAUC has been
working and deployed for years and years. It would be a nightmare trying
to handle migration of existing deployments for an aesthetic change.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-04-24 18:49 ` Tom Rini
@ 2025-04-25 14:35 ` Simon Glass
2025-04-25 14:37 ` Tom Rini
0 siblings, 1 reply; 20+ messages in thread
From: Simon Glass @ 2025-04-25 14:35 UTC (permalink / raw)
To: Tom Rini; +Cc: Martin Schwan, u-boot@lists.denx.de, upstream@lists.phytec.de
Hi Tom,
On Thu, 24 Apr 2025 at 12:49, Tom Rini <trini@konsulko.com> wrote:
>
> On Thu, Apr 24, 2025 at 12:31:38PM -0600, Simon Glass wrote:
> > Hi Martin,
> >
> > On Thu, 24 Apr 2025 at 06:43, Martin Schwan <M.Schwan@phytec.de> wrote:
> > >
> > > Hi Simon,
> > >
> > > thanks for the review and sorry for my delayed reply.
> > >
> > > On Mon, 2025-04-14 at 05:32 -0600, Simon Glass wrote:
> > > > Hi Martin,
> > > >
> > > > On Wed, 29 Jan 2025 at 07:25, Martin Schwan <m.schwan@phytec.de>
> > > > wrote:
> > > > >
> > > > > Add a bootmeth driver which supports booting A/B system with RAUC
> > > > > as
> > > > > their update client.
> > > > >
> > > > > Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> > > > > ---
> > > > > boot/Kconfig | 11 ++
> > > > > boot/Makefile | 1 +
> > > > > boot/bootmeth_rauc.c | 408
> > > > > +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > 3 files changed, 420 insertions(+)
> > > >
> > > > This looks fine to me. Just some nits below.
> > > >
> >
> > [..]
> >
> > > > > +
> > > > > + partitions = env_get("rauc_partitions");
> > > > > + if (!partitions)
> > > > > + return log_msg_ret("env", -ENOENT);
> > > > > + partitions_list = str_to_list(partitions);
> > > > > +
> > > > > + slots = env_get("rauc_slots");
> > > > > + if (!slots)
> > > > > + return log_msg_ret("env", -ENOENT);
> > > > > + slots_list = str_to_list(slots);
> > > > > +
> > > > > + boot_order = env_get("BOOT_ORDER");
> > > >
> > > > Environment variables should be in lower case.
> > >
> > > Unfortunately, we are bound to the naming RAUC uses for these
> > > environment variables, which is upper case. See
> > > https://rauc.readthedocs.io/en/latest/integration.html#set-up-u-boot-boot-script-for-rauc
> >
> > Can't you change it, since you are introducing new support here?
> >
> > If not, then you could perhaps set the env variables to lowercase when
> > you find uppercase variables? I suppose that would require updating
> > the client to do the same thing too?
> >
> > It would be very confusing for a user to have upper-case variables for
> > some things.
>
> Simon, this is an unreasonable request. This is how RAUC has been
> working and deployed for years and years. It would be a nightmare trying
> to handle migration of existing deployments for an aesthetic change.
Yes, I figured. Perhaps it could support lower case in future? This is
the first I have seen on RAUC in U-Boot, although I do see this file
which has both lower and upper case:
include/env/phytec/rauc.env
Regards,
Simon
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-04-25 14:35 ` Simon Glass
@ 2025-04-25 14:37 ` Tom Rini
2025-04-25 15:03 ` Simon Glass
0 siblings, 1 reply; 20+ messages in thread
From: Tom Rini @ 2025-04-25 14:37 UTC (permalink / raw)
To: Simon Glass; +Cc: Martin Schwan, u-boot@lists.denx.de, upstream@lists.phytec.de
[-- Attachment #1: Type: text/plain, Size: 3122 bytes --]
On Fri, Apr 25, 2025 at 08:35:52AM -0600, Simon Glass wrote:
> Hi Tom,
>
> On Thu, 24 Apr 2025 at 12:49, Tom Rini <trini@konsulko.com> wrote:
> >
> > On Thu, Apr 24, 2025 at 12:31:38PM -0600, Simon Glass wrote:
> > > Hi Martin,
> > >
> > > On Thu, 24 Apr 2025 at 06:43, Martin Schwan <M.Schwan@phytec.de> wrote:
> > > >
> > > > Hi Simon,
> > > >
> > > > thanks for the review and sorry for my delayed reply.
> > > >
> > > > On Mon, 2025-04-14 at 05:32 -0600, Simon Glass wrote:
> > > > > Hi Martin,
> > > > >
> > > > > On Wed, 29 Jan 2025 at 07:25, Martin Schwan <m.schwan@phytec.de>
> > > > > wrote:
> > > > > >
> > > > > > Add a bootmeth driver which supports booting A/B system with RAUC
> > > > > > as
> > > > > > their update client.
> > > > > >
> > > > > > Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> > > > > > ---
> > > > > > boot/Kconfig | 11 ++
> > > > > > boot/Makefile | 1 +
> > > > > > boot/bootmeth_rauc.c | 408
> > > > > > +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > > 3 files changed, 420 insertions(+)
> > > > >
> > > > > This looks fine to me. Just some nits below.
> > > > >
> > >
> > > [..]
> > >
> > > > > > +
> > > > > > + partitions = env_get("rauc_partitions");
> > > > > > + if (!partitions)
> > > > > > + return log_msg_ret("env", -ENOENT);
> > > > > > + partitions_list = str_to_list(partitions);
> > > > > > +
> > > > > > + slots = env_get("rauc_slots");
> > > > > > + if (!slots)
> > > > > > + return log_msg_ret("env", -ENOENT);
> > > > > > + slots_list = str_to_list(slots);
> > > > > > +
> > > > > > + boot_order = env_get("BOOT_ORDER");
> > > > >
> > > > > Environment variables should be in lower case.
> > > >
> > > > Unfortunately, we are bound to the naming RAUC uses for these
> > > > environment variables, which is upper case. See
> > > > https://rauc.readthedocs.io/en/latest/integration.html#set-up-u-boot-boot-script-for-rauc
> > >
> > > Can't you change it, since you are introducing new support here?
> > >
> > > If not, then you could perhaps set the env variables to lowercase when
> > > you find uppercase variables? I suppose that would require updating
> > > the client to do the same thing too?
> > >
> > > It would be very confusing for a user to have upper-case variables for
> > > some things.
> >
> > Simon, this is an unreasonable request. This is how RAUC has been
> > working and deployed for years and years. It would be a nightmare trying
> > to handle migration of existing deployments for an aesthetic change.
>
> Yes, I figured. Perhaps it could support lower case in future? This is
> the first I have seen on RAUC in U-Boot, although I do see this file
> which has both lower and upper case:
>
> include/env/phytec/rauc.env
I don't think there's any need to complicate RAUC support here (nor
in the future Mender nor swupdate nor any other long standing OTA
mechanism that might be more easily integrated via bootstd than
environment patching).
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-04-25 14:37 ` Tom Rini
@ 2025-04-25 15:03 ` Simon Glass
2025-04-25 16:19 ` Tom Rini
2025-04-28 8:35 ` Alexander Dahl
0 siblings, 2 replies; 20+ messages in thread
From: Simon Glass @ 2025-04-25 15:03 UTC (permalink / raw)
To: Tom Rini; +Cc: Martin Schwan, u-boot@lists.denx.de, upstream@lists.phytec.de
Hi Tom,
On Fri, 25 Apr 2025 at 08:37, Tom Rini <trini@konsulko.com> wrote:
>
> On Fri, Apr 25, 2025 at 08:35:52AM -0600, Simon Glass wrote:
> > Hi Tom,
> >
> > On Thu, 24 Apr 2025 at 12:49, Tom Rini <trini@konsulko.com> wrote:
> > >
> > > On Thu, Apr 24, 2025 at 12:31:38PM -0600, Simon Glass wrote:
> > > > Hi Martin,
> > > >
> > > > On Thu, 24 Apr 2025 at 06:43, Martin Schwan <M.Schwan@phytec.de> wrote:
> > > > >
> > > > > Hi Simon,
> > > > >
> > > > > thanks for the review and sorry for my delayed reply.
> > > > >
> > > > > On Mon, 2025-04-14 at 05:32 -0600, Simon Glass wrote:
> > > > > > Hi Martin,
> > > > > >
> > > > > > On Wed, 29 Jan 2025 at 07:25, Martin Schwan <m.schwan@phytec.de>
> > > > > > wrote:
> > > > > > >
> > > > > > > Add a bootmeth driver which supports booting A/B system with RAUC
> > > > > > > as
> > > > > > > their update client.
> > > > > > >
> > > > > > > Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> > > > > > > ---
> > > > > > > boot/Kconfig | 11 ++
> > > > > > > boot/Makefile | 1 +
> > > > > > > boot/bootmeth_rauc.c | 408
> > > > > > > +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > > > 3 files changed, 420 insertions(+)
> > > > > >
> > > > > > This looks fine to me. Just some nits below.
> > > > > >
> > > >
> > > > [..]
> > > >
> > > > > > > +
> > > > > > > + partitions = env_get("rauc_partitions");
> > > > > > > + if (!partitions)
> > > > > > > + return log_msg_ret("env", -ENOENT);
> > > > > > > + partitions_list = str_to_list(partitions);
> > > > > > > +
> > > > > > > + slots = env_get("rauc_slots");
> > > > > > > + if (!slots)
> > > > > > > + return log_msg_ret("env", -ENOENT);
> > > > > > > + slots_list = str_to_list(slots);
> > > > > > > +
> > > > > > > + boot_order = env_get("BOOT_ORDER");
> > > > > >
> > > > > > Environment variables should be in lower case.
> > > > >
> > > > > Unfortunately, we are bound to the naming RAUC uses for these
> > > > > environment variables, which is upper case. See
> > > > > https://rauc.readthedocs.io/en/latest/integration.html#set-up-u-boot-boot-script-for-rauc
> > > >
> > > > Can't you change it, since you are introducing new support here?
> > > >
> > > > If not, then you could perhaps set the env variables to lowercase when
> > > > you find uppercase variables? I suppose that would require updating
> > > > the client to do the same thing too?
> > > >
> > > > It would be very confusing for a user to have upper-case variables for
> > > > some things.
> > >
> > > Simon, this is an unreasonable request. This is how RAUC has been
> > > working and deployed for years and years. It would be a nightmare trying
> > > to handle migration of existing deployments for an aesthetic change.
> >
> > Yes, I figured. Perhaps it could support lower case in future? This is
> > the first I have seen on RAUC in U-Boot, although I do see this file
> > which has both lower and upper case:
> >
> > include/env/phytec/rauc.env
>
> I don't think there's any need to complicate RAUC support here (nor
> in the future Mender nor swupdate nor any other long standing OTA
> mechanism that might be more easily integrated via bootstd than
> environment patching).
Let's see what the author says. I assume that U-Boot has its own code
in RAUC so it might not be too bad.
Regards,
Simon
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-04-25 15:03 ` Simon Glass
@ 2025-04-25 16:19 ` Tom Rini
2025-04-28 8:25 ` Martin Schwan
2025-04-29 14:19 ` Simon Glass
2025-04-28 8:35 ` Alexander Dahl
1 sibling, 2 replies; 20+ messages in thread
From: Tom Rini @ 2025-04-25 16:19 UTC (permalink / raw)
To: Simon Glass; +Cc: Martin Schwan, u-boot@lists.denx.de, upstream@lists.phytec.de
[-- Attachment #1: Type: text/plain, Size: 4058 bytes --]
On Fri, Apr 25, 2025 at 09:03:17AM -0600, Simon Glass wrote:
> Hi Tom,
>
> On Fri, 25 Apr 2025 at 08:37, Tom Rini <trini@konsulko.com> wrote:
> >
> > On Fri, Apr 25, 2025 at 08:35:52AM -0600, Simon Glass wrote:
> > > Hi Tom,
> > >
> > > On Thu, 24 Apr 2025 at 12:49, Tom Rini <trini@konsulko.com> wrote:
> > > >
> > > > On Thu, Apr 24, 2025 at 12:31:38PM -0600, Simon Glass wrote:
> > > > > Hi Martin,
> > > > >
> > > > > On Thu, 24 Apr 2025 at 06:43, Martin Schwan <M.Schwan@phytec.de> wrote:
> > > > > >
> > > > > > Hi Simon,
> > > > > >
> > > > > > thanks for the review and sorry for my delayed reply.
> > > > > >
> > > > > > On Mon, 2025-04-14 at 05:32 -0600, Simon Glass wrote:
> > > > > > > Hi Martin,
> > > > > > >
> > > > > > > On Wed, 29 Jan 2025 at 07:25, Martin Schwan <m.schwan@phytec.de>
> > > > > > > wrote:
> > > > > > > >
> > > > > > > > Add a bootmeth driver which supports booting A/B system with RAUC
> > > > > > > > as
> > > > > > > > their update client.
> > > > > > > >
> > > > > > > > Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> > > > > > > > ---
> > > > > > > > boot/Kconfig | 11 ++
> > > > > > > > boot/Makefile | 1 +
> > > > > > > > boot/bootmeth_rauc.c | 408
> > > > > > > > +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > > > > 3 files changed, 420 insertions(+)
> > > > > > >
> > > > > > > This looks fine to me. Just some nits below.
> > > > > > >
> > > > >
> > > > > [..]
> > > > >
> > > > > > > > +
> > > > > > > > + partitions = env_get("rauc_partitions");
> > > > > > > > + if (!partitions)
> > > > > > > > + return log_msg_ret("env", -ENOENT);
> > > > > > > > + partitions_list = str_to_list(partitions);
> > > > > > > > +
> > > > > > > > + slots = env_get("rauc_slots");
> > > > > > > > + if (!slots)
> > > > > > > > + return log_msg_ret("env", -ENOENT);
> > > > > > > > + slots_list = str_to_list(slots);
> > > > > > > > +
> > > > > > > > + boot_order = env_get("BOOT_ORDER");
> > > > > > >
> > > > > > > Environment variables should be in lower case.
> > > > > >
> > > > > > Unfortunately, we are bound to the naming RAUC uses for these
> > > > > > environment variables, which is upper case. See
> > > > > > https://rauc.readthedocs.io/en/latest/integration.html#set-up-u-boot-boot-script-for-rauc
> > > > >
> > > > > Can't you change it, since you are introducing new support here?
> > > > >
> > > > > If not, then you could perhaps set the env variables to lowercase when
> > > > > you find uppercase variables? I suppose that would require updating
> > > > > the client to do the same thing too?
> > > > >
> > > > > It would be very confusing for a user to have upper-case variables for
> > > > > some things.
> > > >
> > > > Simon, this is an unreasonable request. This is how RAUC has been
> > > > working and deployed for years and years. It would be a nightmare trying
> > > > to handle migration of existing deployments for an aesthetic change.
> > >
> > > Yes, I figured. Perhaps it could support lower case in future? This is
> > > the first I have seen on RAUC in U-Boot, although I do see this file
> > > which has both lower and upper case:
> > >
> > > include/env/phytec/rauc.env
> >
> > I don't think there's any need to complicate RAUC support here (nor
> > in the future Mender nor swupdate nor any other long standing OTA
> > mechanism that might be more easily integrated via bootstd than
> > environment patching).
>
> Let's see what the author says. I assume that U-Boot has its own code
> in RAUC so it might not be too bad.
I mean, sure? But "should" is not "must" and I have zero desire to
make supporting existing use cases harder. That will make migration to
bootstd less attractive, not more. We don't want people to decide that
can't upstream platform X or feature Y because they've already developed
and deployed it using capitals or camel case in their environment.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-04-25 16:19 ` Tom Rini
@ 2025-04-28 8:25 ` Martin Schwan
2025-04-28 15:39 ` Tom Rini
2025-04-29 14:19 ` Simon Glass
1 sibling, 1 reply; 20+ messages in thread
From: Martin Schwan @ 2025-04-28 8:25 UTC (permalink / raw)
To: Tom Rini, Simon Glass; +Cc: u-boot@lists.denx.de, upstream@lists.phytec.de
Hi Simon,
Hi Tom,
On Fri, 2025-04-25 at 10:19 -0600, Tom Rini wrote:
> On Fri, Apr 25, 2025 at 09:03:17AM -0600, Simon Glass wrote:
> > Hi Tom,
> >
> > On Fri, 25 Apr 2025 at 08:37, Tom Rini <trini@konsulko.com> wrote:
> > >
> > > On Fri, Apr 25, 2025 at 08:35:52AM -0600, Simon Glass wrote:
> > > > Hi Tom,
> > > >
> > > > On Thu, 24 Apr 2025 at 12:49, Tom Rini <trini@konsulko.com>
> > > > wrote:
> > > > >
> > > > > On Thu, Apr 24, 2025 at 12:31:38PM -0600, Simon Glass wrote:
> > > > > > Hi Martin,
> > > > > >
> > > > > > On Thu, 24 Apr 2025 at 06:43, Martin Schwan
> > > > > > <M.Schwan@phytec.de> wrote:
> > > > > > >
> > > > > > > Hi Simon,
> > > > > > >
> > > > > > > thanks for the review and sorry for my delayed reply.
> > > > > > >
> > > > > > > On Mon, 2025-04-14 at 05:32 -0600, Simon Glass wrote:
> > > > > > > > Hi Martin,
> > > > > > > >
> > > > > > > > On Wed, 29 Jan 2025 at 07:25, Martin Schwan
> > > > > > > > <m.schwan@phytec.de>
> > > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > Add a bootmeth driver which supports booting A/B
> > > > > > > > > system with RAUC
> > > > > > > > > as
> > > > > > > > > their update client.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> > > > > > > > > ---
> > > > > > > > > boot/Kconfig | 11 ++
> > > > > > > > > boot/Makefile | 1 +
> > > > > > > > > boot/bootmeth_rauc.c | 408
> > > > > > > > > +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > > > > > 3 files changed, 420 insertions(+)
> > > > > > > >
> > > > > > > > This looks fine to me. Just some nits below.
> > > > > > > >
> > > > > >
> > > > > > [..]
> > > > > >
> > > > > > > > > +
> > > > > > > > > + partitions = env_get("rauc_partitions");
> > > > > > > > > + if (!partitions)
> > > > > > > > > + return log_msg_ret("env", -ENOENT);
> > > > > > > > > + partitions_list = str_to_list(partitions);
> > > > > > > > > +
> > > > > > > > > + slots = env_get("rauc_slots");
> > > > > > > > > + if (!slots)
> > > > > > > > > + return log_msg_ret("env", -ENOENT);
> > > > > > > > > + slots_list = str_to_list(slots);
> > > > > > > > > +
> > > > > > > > > + boot_order = env_get("BOOT_ORDER");
> > > > > > > >
> > > > > > > > Environment variables should be in lower case.
> > > > > > >
> > > > > > > Unfortunately, we are bound to the naming RAUC uses for
> > > > > > > these
> > > > > > > environment variables, which is upper case. See
> > > > > > > https://rauc.readthedocs.io/en/latest/integration.html#set-up-u-boot-boot-script-for-rauc
> > > > > >
> > > > > > Can't you change it, since you are introducing new support
> > > > > > here?
> > > > > >
> > > > > > If not, then you could perhaps set the env variables to
> > > > > > lowercase when
> > > > > > you find uppercase variables? I suppose that would require
> > > > > > updating
> > > > > > the client to do the same thing too?
> > > > > >
> > > > > > It would be very confusing for a user to have upper-case
> > > > > > variables for
> > > > > > some things.
> > > > >
> > > > > Simon, this is an unreasonable request. This is how RAUC has
> > > > > been
> > > > > working and deployed for years and years. It would be a
> > > > > nightmare trying
> > > > > to handle migration of existing deployments for an aesthetic
> > > > > change.
> > > >
> > > > Yes, I figured. Perhaps it could support lower case in future?
> > > > This is
> > > > the first I have seen on RAUC in U-Boot, although I do see this
> > > > file
> > > > which has both lower and upper case:
> > > >
> > > > include/env/phytec/rauc.env
> > >
> > > I don't think there's any need to complicate RAUC support here
> > > (nor
> > > in the future Mender nor swupdate nor any other long standing OTA
> > > mechanism that might be more easily integrated via bootstd than
> > > environment patching).
> >
> > Let's see what the author says. I assume that U-Boot has its own
> > code
> > in RAUC so it might not be too bad.
>
> I mean, sure? But "should" is not "must" and I have zero desire to
> make supporting existing use cases harder. That will make migration
> to
> bootstd less attractive, not more. We don't want people to decide
> that
> can't upstream platform X or feature Y because they've already
> developed
> and deployed it using capitals or camel case in their environment.
I am not a core RAUC developer, but it should be theoretically possible
to change it to lower-case variable names. The problem is that this
creates incompatibilities with at least older versions of RAUC, which
only use upper-case. And that's something I honestly don't want to deal
with, as it makes the U-Boot and RAUC codebase bloated. After all,
changing the variable naming now wouldn't be very *robust* for the
update client. It is a key feature of such update clients to update
without complicated migration precedures and I don't want to break
that.
So yes, it would be nice to keep the naming in line with the existing
U-Boot convention, but no, I also see too many serious downsides that
would justify such a change.
Kind Regards,
Martin
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-04-25 15:03 ` Simon Glass
2025-04-25 16:19 ` Tom Rini
@ 2025-04-28 8:35 ` Alexander Dahl
1 sibling, 0 replies; 20+ messages in thread
From: Alexander Dahl @ 2025-04-28 8:35 UTC (permalink / raw)
To: Simon Glass
Cc: Tom Rini, Martin Schwan, u-boot@lists.denx.de,
upstream@lists.phytec.de, Jan Lübbe
Hei hei,
some references, see below.
Am Fri, Apr 25, 2025 at 09:03:17AM -0600 schrieb Simon Glass:
> Hi Tom,
>
> On Fri, 25 Apr 2025 at 08:37, Tom Rini <trini@konsulko.com> wrote:
> >
> > On Fri, Apr 25, 2025 at 08:35:52AM -0600, Simon Glass wrote:
> > > Hi Tom,
> > >
> > > On Thu, 24 Apr 2025 at 12:49, Tom Rini <trini@konsulko.com> wrote:
> > > >
> > > > On Thu, Apr 24, 2025 at 12:31:38PM -0600, Simon Glass wrote:
> > > > > Hi Martin,
> > > > >
[…]
> > > > >
> > > > > Can't you change it, since you are introducing new support here?
> > > > >
> > > > > If not, then you could perhaps set the env variables to lowercase when
> > > > > you find uppercase variables? I suppose that would require updating
> > > > > the client to do the same thing too?
> > > > >
> > > > > It would be very confusing for a user to have upper-case variables for
> > > > > some things.
> > > >
> > > > Simon, this is an unreasonable request. This is how RAUC has been
> > > > working and deployed for years and years. It would be a nightmare trying
> > > > to handle migration of existing deployments for an aesthetic change.
> > >
> > > Yes, I figured. Perhaps it could support lower case in future? This is
> > > the first I have seen on RAUC in U-Boot, although I do see this file
> > > which has both lower and upper case:
> > >
> > > include/env/phytec/rauc.env
> >
> > I don't think there's any need to complicate RAUC support here (nor
> > in the future Mender nor swupdate nor any other long standing OTA
> > mechanism that might be more easily integrated via bootstd than
> > environment patching).
>
> Let's see what the author says. I assume that U-Boot has its own code
> in RAUC so it might not be too bad.
It has:
https://github.com/rauc/rauc/blob/master/src/bootloaders/uboot.c
These env variable are names are hardcoded:
BOOT_ORDER
BOOT_A_LEFT
BOOT_B_LEFT
I played with RAUC and U-Boot back in 2021/2022, and if I remember
correctly these variable names did not change since initial support
for U-Boot in RAUC. That probably was back in 2016 and done by Jan
Lübbe: https://github.com/rauc/rauc/pull/45
(I used a custom boot script based on the example coming with RAUC and
hooked that into distroboot for my usecase back then.)
In retrospect it might have been better from RAUC side to hook into
the bootcount feature of U-Boot, which was already present at the
time? But now it's like Tom said: these env variables are the
interface for years. It would require at least coordination with RAUC
devs if there should be used any other interface.
Adding Jan in Cc, maybe he wants to add some context from RAUC side.
Greets
Alex
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-04-28 8:25 ` Martin Schwan
@ 2025-04-28 15:39 ` Tom Rini
0 siblings, 0 replies; 20+ messages in thread
From: Tom Rini @ 2025-04-28 15:39 UTC (permalink / raw)
To: Martin Schwan; +Cc: Simon Glass, u-boot@lists.denx.de, upstream@lists.phytec.de
[-- Attachment #1: Type: text/plain, Size: 5707 bytes --]
On Mon, Apr 28, 2025 at 08:25:37AM +0000, Martin Schwan wrote:
> Hi Simon,
> Hi Tom,
>
> On Fri, 2025-04-25 at 10:19 -0600, Tom Rini wrote:
> > On Fri, Apr 25, 2025 at 09:03:17AM -0600, Simon Glass wrote:
> > > Hi Tom,
> > >
> > > On Fri, 25 Apr 2025 at 08:37, Tom Rini <trini@konsulko.com> wrote:
> > > >
> > > > On Fri, Apr 25, 2025 at 08:35:52AM -0600, Simon Glass wrote:
> > > > > Hi Tom,
> > > > >
> > > > > On Thu, 24 Apr 2025 at 12:49, Tom Rini <trini@konsulko.com>
> > > > > wrote:
> > > > > >
> > > > > > On Thu, Apr 24, 2025 at 12:31:38PM -0600, Simon Glass wrote:
> > > > > > > Hi Martin,
> > > > > > >
> > > > > > > On Thu, 24 Apr 2025 at 06:43, Martin Schwan
> > > > > > > <M.Schwan@phytec.de> wrote:
> > > > > > > >
> > > > > > > > Hi Simon,
> > > > > > > >
> > > > > > > > thanks for the review and sorry for my delayed reply.
> > > > > > > >
> > > > > > > > On Mon, 2025-04-14 at 05:32 -0600, Simon Glass wrote:
> > > > > > > > > Hi Martin,
> > > > > > > > >
> > > > > > > > > On Wed, 29 Jan 2025 at 07:25, Martin Schwan
> > > > > > > > > <m.schwan@phytec.de>
> > > > > > > > > wrote:
> > > > > > > > > >
> > > > > > > > > > Add a bootmeth driver which supports booting A/B
> > > > > > > > > > system with RAUC
> > > > > > > > > > as
> > > > > > > > > > their update client.
> > > > > > > > > >
> > > > > > > > > > Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> > > > > > > > > > ---
> > > > > > > > > > boot/Kconfig | 11 ++
> > > > > > > > > > boot/Makefile | 1 +
> > > > > > > > > > boot/bootmeth_rauc.c | 408
> > > > > > > > > > +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > > > > > > 3 files changed, 420 insertions(+)
> > > > > > > > >
> > > > > > > > > This looks fine to me. Just some nits below.
> > > > > > > > >
> > > > > > >
> > > > > > > [..]
> > > > > > >
> > > > > > > > > > +
> > > > > > > > > > + partitions = env_get("rauc_partitions");
> > > > > > > > > > + if (!partitions)
> > > > > > > > > > + return log_msg_ret("env", -ENOENT);
> > > > > > > > > > + partitions_list = str_to_list(partitions);
> > > > > > > > > > +
> > > > > > > > > > + slots = env_get("rauc_slots");
> > > > > > > > > > + if (!slots)
> > > > > > > > > > + return log_msg_ret("env", -ENOENT);
> > > > > > > > > > + slots_list = str_to_list(slots);
> > > > > > > > > > +
> > > > > > > > > > + boot_order = env_get("BOOT_ORDER");
> > > > > > > > >
> > > > > > > > > Environment variables should be in lower case.
> > > > > > > >
> > > > > > > > Unfortunately, we are bound to the naming RAUC uses for
> > > > > > > > these
> > > > > > > > environment variables, which is upper case. See
> > > > > > > > https://rauc.readthedocs.io/en/latest/integration.html#set-up-u-boot-boot-script-for-rauc
> > > > > > >
> > > > > > > Can't you change it, since you are introducing new support
> > > > > > > here?
> > > > > > >
> > > > > > > If not, then you could perhaps set the env variables to
> > > > > > > lowercase when
> > > > > > > you find uppercase variables? I suppose that would require
> > > > > > > updating
> > > > > > > the client to do the same thing too?
> > > > > > >
> > > > > > > It would be very confusing for a user to have upper-case
> > > > > > > variables for
> > > > > > > some things.
> > > > > >
> > > > > > Simon, this is an unreasonable request. This is how RAUC has
> > > > > > been
> > > > > > working and deployed for years and years. It would be a
> > > > > > nightmare trying
> > > > > > to handle migration of existing deployments for an aesthetic
> > > > > > change.
> > > > >
> > > > > Yes, I figured. Perhaps it could support lower case in future?
> > > > > This is
> > > > > the first I have seen on RAUC in U-Boot, although I do see this
> > > > > file
> > > > > which has both lower and upper case:
> > > > >
> > > > > include/env/phytec/rauc.env
> > > >
> > > > I don't think there's any need to complicate RAUC support here
> > > > (nor
> > > > in the future Mender nor swupdate nor any other long standing OTA
> > > > mechanism that might be more easily integrated via bootstd than
> > > > environment patching).
> > >
> > > Let's see what the author says. I assume that U-Boot has its own
> > > code
> > > in RAUC so it might not be too bad.
> >
> > I mean, sure? But "should" is not "must" and I have zero desire to
> > make supporting existing use cases harder. That will make migration
> > to
> > bootstd less attractive, not more. We don't want people to decide
> > that
> > can't upstream platform X or feature Y because they've already
> > developed
> > and deployed it using capitals or camel case in their environment.
>
> I am not a core RAUC developer, but it should be theoretically possible
> to change it to lower-case variable names. The problem is that this
> creates incompatibilities with at least older versions of RAUC, which
> only use upper-case. And that's something I honestly don't want to deal
> with, as it makes the U-Boot and RAUC codebase bloated. After all,
> changing the variable naming now wouldn't be very *robust* for the
> update client. It is a key feature of such update clients to update
> without complicated migration precedures and I don't want to break
> that.
>
> So yes, it would be nice to keep the naming in line with the existing
> U-Boot convention, but no, I also see too many serious downsides that
> would justify such a change.
Thanks. It's really fine to not worry about changing the environment
variable names at this point.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-04-25 16:19 ` Tom Rini
2025-04-28 8:25 ` Martin Schwan
@ 2025-04-29 14:19 ` Simon Glass
1 sibling, 0 replies; 20+ messages in thread
From: Simon Glass @ 2025-04-29 14:19 UTC (permalink / raw)
To: Tom Rini; +Cc: Martin Schwan, u-boot@lists.denx.de, upstream@lists.phytec.de
Hi Tom,
On Fri, 25 Apr 2025 at 10:19, Tom Rini <trini@konsulko.com> wrote:
>
> On Fri, Apr 25, 2025 at 09:03:17AM -0600, Simon Glass wrote:
> > Hi Tom,
> >
> > On Fri, 25 Apr 2025 at 08:37, Tom Rini <trini@konsulko.com> wrote:
> > >
> > > On Fri, Apr 25, 2025 at 08:35:52AM -0600, Simon Glass wrote:
> > > > Hi Tom,
> > > >
> > > > On Thu, 24 Apr 2025 at 12:49, Tom Rini <trini@konsulko.com> wrote:
> > > > >
> > > > > On Thu, Apr 24, 2025 at 12:31:38PM -0600, Simon Glass wrote:
> > > > > > Hi Martin,
> > > > > >
> > > > > > On Thu, 24 Apr 2025 at 06:43, Martin Schwan <M.Schwan@phytec.de> wrote:
> > > > > > >
> > > > > > > Hi Simon,
> > > > > > >
> > > > > > > thanks for the review and sorry for my delayed reply.
> > > > > > >
> > > > > > > On Mon, 2025-04-14 at 05:32 -0600, Simon Glass wrote:
> > > > > > > > Hi Martin,
> > > > > > > >
> > > > > > > > On Wed, 29 Jan 2025 at 07:25, Martin Schwan <m.schwan@phytec.de>
> > > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > Add a bootmeth driver which supports booting A/B system with RAUC
> > > > > > > > > as
> > > > > > > > > their update client.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> > > > > > > > > ---
> > > > > > > > > boot/Kconfig | 11 ++
> > > > > > > > > boot/Makefile | 1 +
> > > > > > > > > boot/bootmeth_rauc.c | 408
> > > > > > > > > +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > > > > > 3 files changed, 420 insertions(+)
> > > > > > > >
> > > > > > > > This looks fine to me. Just some nits below.
> > > > > > > >
> > > > > >
> > > > > > [..]
> > > > > >
> > > > > > > > > +
> > > > > > > > > + partitions = env_get("rauc_partitions");
> > > > > > > > > + if (!partitions)
> > > > > > > > > + return log_msg_ret("env", -ENOENT);
> > > > > > > > > + partitions_list = str_to_list(partitions);
> > > > > > > > > +
> > > > > > > > > + slots = env_get("rauc_slots");
> > > > > > > > > + if (!slots)
> > > > > > > > > + return log_msg_ret("env", -ENOENT);
> > > > > > > > > + slots_list = str_to_list(slots);
> > > > > > > > > +
> > > > > > > > > + boot_order = env_get("BOOT_ORDER");
> > > > > > > >
> > > > > > > > Environment variables should be in lower case.
> > > > > > >
> > > > > > > Unfortunately, we are bound to the naming RAUC uses for these
> > > > > > > environment variables, which is upper case. See
> > > > > > > https://rauc.readthedocs.io/en/latest/integration.html#set-up-u-boot-boot-script-for-rauc
> > > > > >
> > > > > > Can't you change it, since you are introducing new support here?
> > > > > >
> > > > > > If not, then you could perhaps set the env variables to lowercase when
> > > > > > you find uppercase variables? I suppose that would require updating
> > > > > > the client to do the same thing too?
> > > > > >
> > > > > > It would be very confusing for a user to have upper-case variables for
> > > > > > some things.
> > > > >
> > > > > Simon, this is an unreasonable request. This is how RAUC has been
> > > > > working and deployed for years and years. It would be a nightmare trying
> > > > > to handle migration of existing deployments for an aesthetic change.
> > > >
> > > > Yes, I figured. Perhaps it could support lower case in future? This is
> > > > the first I have seen on RAUC in U-Boot, although I do see this file
> > > > which has both lower and upper case:
> > > >
> > > > include/env/phytec/rauc.env
> > >
> > > I don't think there's any need to complicate RAUC support here (nor
> > > in the future Mender nor swupdate nor any other long standing OTA
> > > mechanism that might be more easily integrated via bootstd than
> > > environment patching).
> >
> > Let's see what the author says. I assume that U-Boot has its own code
> > in RAUC so it might not be too bad.
>
> I mean, sure? But "should" is not "must" and I have zero desire to
> make supporting existing use cases harder. That will make migration to
> bootstd less attractive, not more. We don't want people to decide that
> can't upstream platform X or feature Y because they've already developed
> and deployed it using capitals or camel case in their environment.
Yes, agreed.
Regards,
Simon
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Upstream] [PATCH 1/2] bootstd: Add implementation for bootmeth rauc
2025-01-29 14:25 ` [PATCH 1/2] bootstd: Add implementation for bootmeth rauc Martin Schwan
2025-01-29 16:03 ` Tom Rini
2025-04-14 11:32 ` Simon Glass
@ 2025-05-06 7:05 ` Wadim Egorov
2 siblings, 0 replies; 20+ messages in thread
From: Wadim Egorov @ 2025-05-06 7:05 UTC (permalink / raw)
To: Martin Schwan, Tom Rini, Simon Glass; +Cc: u-boot, upstream
Hi Martin,
Am 29.01.25 um 16:25 schrieb Martin Schwan:
> Add a bootmeth driver which supports booting A/B system with RAUC as
> their update client.
>
> Signed-off-by: Martin Schwan <m.schwan@phytec.de>
> ---
> boot/Kconfig | 11 ++
> boot/Makefile | 1 +
> boot/bootmeth_rauc.c | 408 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 420 insertions(+)
>
> diff --git a/boot/Kconfig b/boot/Kconfig
> index 20935a269c60dad53ce11ac7e58247dc23cf617e..966573d8eb7675d36f299c8c2fa6509bac147cae 100644
> --- a/boot/Kconfig
> +++ b/boot/Kconfig
> @@ -782,6 +782,17 @@ config EXPO
> The expo can be presented in graphics form using a vidconsole, or in
> text form on a serial console.
>
> +config BOOTMETH_RAUC
> + bool "Bootdev support for RAUC A/B systems"
> + default y if BOOTSTD_FULL
> + depends on CMDLINE
> + select BOOTMETH_GLOBAL
> + select HUSH_PARSER
> + help
> + Enables support for booting RAUC A/B systems from MMC devices. This
> + makes the bootdevs look for a 'boot.scr.uimg' or 'boot.scr' in the
> + respective boot partitions, describing how to boot the distro.
> +
> config BOOTMETH_SANDBOX
> def_bool y
> depends on SANDBOX
> diff --git a/boot/Makefile b/boot/Makefile
> index c2753de8163cf59b1abdc01149a856e2847960e6..427898449a8727747137ab1c7c571c473148c8c3 100644
> --- a/boot/Makefile
> +++ b/boot/Makefile
> @@ -32,6 +32,7 @@ obj-$(CONFIG_$(PHASE_)BOOTMETH_EXTLINUX_PXE) += bootmeth_pxe.o
> obj-$(CONFIG_$(PHASE_)BOOTMETH_EFILOADER) += bootmeth_efi.o
> obj-$(CONFIG_$(PHASE_)BOOTMETH_CROS) += bootm.o bootm_os.o bootmeth_cros.o
> obj-$(CONFIG_$(PHASE_)BOOTMETH_QFW) += bootmeth_qfw.o
> +obj-$(CONFIG_$(PHASE_)BOOTMETH_RAUC) += bootmeth_rauc.o
> obj-$(CONFIG_$(PHASE_)BOOTMETH_SANDBOX) += bootmeth_sandbox.o
> obj-$(CONFIG_$(PHASE_)BOOTMETH_SCRIPT) += bootmeth_script.o
> obj-$(CONFIG_$(PHASE_)CEDIT) += cedit.o
> diff --git a/boot/bootmeth_rauc.c b/boot/bootmeth_rauc.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..fcb7e8df4556710b160349f1dcc54cdda9b59c9d
> --- /dev/null
> +++ b/boot/bootmeth_rauc.c
> @@ -0,0 +1,408 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Bootmethod for distro boot with RAUC
> + *
> + * Copyright 2025 PHYTEC Messtechnik GmbH
> + * Written by Martin Schwan <m.schwan@phytec.de>
> + */
> +
> +#define LOG_CATEGORY UCLASS_BOOTSTD
> +#define LOG_DEBUG
> +
> +#include <asm/cache.h>
> +#include <blk.h>
> +#include <bootflow.h>
> +#include <bootmeth.h>
> +#include <bootstd.h>
> +#include <dm.h>
> +#include <env.h>
> +#include <fs.h>
> +#include <malloc.h>
> +#include <mapmem.h>
> +#include <string.h>
> +
> +static const char * const script_names[] = { "boot.scr.uimg", "boot.scr", NULL };
> +static const char * const rauc_files[] = { "/usr/bin/rauc", "/etc/rauc/system.conf", NULL };
> +
> +/**
> + * struct distro_rauc_slot - Slot information
> + *
> + * @name The slot name
> + * @left The number of boot tries left
> + * @boot_part The boot partition number on disk
> + * @root_part The boot partition number on disk
> + */
> +struct distro_rauc_slot {
> + char *name;
> + ulong left;
> + int boot_part;
> + int root_part;
> +};
> +
> +/**
> + * struct distro_rauc_priv - Private data
> + *
> + * @slots All slots of the device in default order
> + * @boot_order The current boot order string containing the active slot names
> + */
> +struct distro_rauc_priv {
> + struct distro_rauc_slot *slots;
> + char *boot_order;
> +};
> +
> +static int distro_rauc_check(struct udevice *dev, struct bootflow_iter *iter)
> +{
> + /* This distro only works on whole MMC devices, as multiple partitions
> + * are needed for an A/B system. */
> + if (bootflow_iter_check_mmc(iter))
> + return log_msg_ret("mmc", -EOPNOTSUPP);
> + if (iter->part != 0)
> + return log_msg_ret("part", -EOPNOTSUPP);
> +
> + return 0;
> +}
> +
> +static int distro_rauc_scan_boot_part(struct bootflow *bflow)
> +{
> + struct blk_desc *desc;
> + struct distro_rauc_priv *priv;
> + int exists;
> + int i;
> + int j;
> + int ret;
> +
> + desc = dev_get_uclass_plat(bflow->blk);
> + if (!desc)
> + return log_msg_ret("desc", -ENOMEM);
> +
> + priv = bflow->bootmeth_priv;
> + if (!priv || !priv->slots || !priv->boot_order)
> + return log_msg_ret("priv", -EINVAL);
> +
> + for (i = 0; priv->slots[i].name != NULL; i++) {
> + exists = 0;
> + for (j = 0; script_names[j] != NULL; j++) {
> + ret = fs_set_blk_dev_with_part(desc, priv->slots[i].boot_part);
> + if (ret)
> + return log_msg_ret("blk", ret);
> + exists |= fs_exists(script_names[j]);
> + }
> + if (!exists)
> + return log_msg_ret("fs", -ENOENT);
> + }
> +
> + return 0;
> +}
> +
> +static int distro_rauc_scan_root_part(struct bootflow *bflow)
> +{
> + struct blk_desc *desc;
> + struct distro_rauc_priv *priv;
> + int exists;
> + int i;
> + int j;
> + int ret;
> +
> + desc = dev_get_uclass_plat(bflow->blk);
> + if (!desc)
> + return log_msg_ret("desc", -ENOMEM);
> +
> + priv = bflow->bootmeth_priv;
> + if (!priv || !priv->slots || !priv->boot_order)
> + return log_msg_ret("priv", -EINVAL);
> +
> + for (i = 0; priv->slots[i].name != NULL; i++) {
> + exists = 0;
> + for (j = 0; rauc_files[j] != NULL; j++) {
> + ret = fs_set_blk_dev_with_part(desc,
> + priv->slots[i].root_part);
> + if (ret)
> + return log_msg_ret("set", ret);
> + if (!fs_exists(rauc_files[j]))
> + return log_msg_ret("fs", -ENOENT);
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int distro_rauc_read_bootflow(struct udevice *dev, struct bootflow *bflow)
> +{
> + struct distro_rauc_priv *priv;
> + int ret;
> + char *slot;
> + int i;
> + char *boot_order;
> + char *partitions;
> + const char **partitions_list;
> + char *slots;
> + const char **slots_list;
> + char boot_left[32];
> + char *parts;
> + ulong default_tries;
> +
> + bflow->state = BOOTFLOWST_MEDIA;
> +
> + priv = malloc(sizeof(struct distro_rauc_priv));
> + if (!priv)
> + return log_msg_ret("buf", -ENOMEM);
> +
> +
> + partitions = env_get("rauc_partitions");
> + if (!partitions)
> + return log_msg_ret("env", -ENOENT);
> + partitions_list = str_to_list(partitions);
> +
> + slots = env_get("rauc_slots");
> + if (!slots)
> + return log_msg_ret("env", -ENOENT);
> + slots_list = str_to_list(slots);
> +
> + boot_order = env_get("BOOT_ORDER");
> + if (!boot_order) {
> + if (env_set("BOOT_ORDER", slots))
> + return log_msg_ret("env", -EPERM);
> + }
> + priv->boot_order = strdup(boot_order);
> +
> + default_tries = env_get_ulong("rauc_slot_default_tries", 10, 3);
> + for (i = 0; slots_list[i] != NULL; i++) {
> + sprintf(boot_left, "BOOT_%s_LEFT", slots_list[i]);
> + if (!env_get(boot_left))
> + env_set_ulong(boot_left, default_tries);
> + }
> +
> + for (i = 0; slots_list[i] != NULL && partitions_list[i] != NULL; i++);
> + priv->slots = malloc((i + 1) * sizeof(struct distro_rauc_slot));
> + if (!priv->slots)
> + return log_msg_ret("priv", -ENOMEM);
> + for (i = 0; slots_list[i] != NULL && partitions_list[i] != NULL; i++) {
> + priv->slots[i].name = strdup(slots_list[i]);
> + sprintf(boot_left, "BOOT_%s_LEFT", slot);
> + priv->slots[i].left = env_get_ulong(boot_left, 10, default_tries);
> + parts = strdup(partitions_list[i]);
> + priv->slots[i].boot_part = simple_strtoul(strsep(&parts, ","), NULL, 10);
> + priv->slots[i].root_part = simple_strtoul(strsep(&parts, ","), NULL, 10);
> + free(parts);
> + parts = NULL;
> + }
> + priv->slots[i].name = NULL;
> + priv->slots[i].left = 0;
> + priv->slots[i].boot_part = 0;
> + priv->slots[i].root_part = 0;
> +
> + bflow->bootmeth_priv = priv;
> + bflow->state = BOOTFLOWST_FS;
> +
> + ret = distro_rauc_scan_boot_part(bflow);
> + if (ret < 0)
> + goto free_priv;
> + ret = distro_rauc_scan_root_part(bflow);
> + if (ret < 0)
> + goto free_priv;
> +
> + bflow->state = BOOTFLOWST_READY;
> +
> + return 0;
> +
> +free_priv:
> + for (i = 0; priv->slots[i].name != NULL; i++)
> + free(priv->slots[i].name);
> + free(priv->slots);
> + free(priv);
> + bflow->bootmeth_priv = NULL;
> + return ret;
> +}
> +
> +static int distro_rauc_read_file(struct udevice *dev, struct bootflow *bflow,
> + const char *file_path, ulong addr,
> + enum bootflow_img_t type, ulong *sizep)
> +{
> + /* Reading individual files is not supported since we only operate on
> + * whole MMC devices (because we require multiple partitions)
> + */
> + return log_msg_ret("Unsupported", -ENOSYS);
> +}
> +
> +static int distro_rauc_load_boot_script(struct bootflow *bflow, const char *slot)
> +{
> + struct blk_desc *desc;
> + struct distro_rauc_priv *priv;
> + const char *prefix = "/";
> + int ret;
> + int i;
> +
> + if (!slot)
> + return log_msg_ret("slot", -EINVAL);
> +
> + desc = dev_get_uclass_plat(bflow->blk);
> + priv = bflow->bootmeth_priv;
> +
> + bflow->part = 0;
> + for (i = 0; priv->slots[i].name != NULL; i++) {
> + if (strcmp(priv->slots[i].name, slot) == 0) {
> + bflow->part = priv->slots[i].boot_part;
> + break;
> + }
> + }
> + if (!bflow->part)
> + return log_msg_ret("part", -ENOENT);
> +
> + ret = bootmeth_setup_fs(bflow, desc);
> + if (ret)
> + return log_msg_ret("set", ret);
> +
> + for (i = 0; script_names[i] != NULL; i++) {
> + if (!bootmeth_try_file(bflow, desc, prefix, script_names[i]))
> + break;
> + }
> + if (bflow->state != BOOTFLOWST_FILE)
> + return log_msg_ret("file", -ENOENT);
> +
> + bflow->subdir = strdup(prefix);
> +
> + ret = bootmeth_alloc_file(bflow, 0x10000, ARCH_DMA_MINALIGN,
> + (enum bootflow_img_t)IH_TYPE_SCRIPT);
> + if (ret)
> + return log_msg_ret("read", ret);
> +
> + return 0;
> +}
> +
> +static int decrement_slot_tries(const char *slot)
> +{
> + ulong tries;
> + char boot_left[32];
> +
> + sprintf(boot_left, "BOOT_%s_LEFT", slot);
> + tries = env_get_ulong(boot_left, 10, ULONG_MAX);
> + if (tries == ULONG_MAX)
> + return log_msg_ret("env", -ENOENT);
> + if (tries <= 0)
> + return 0;
> +
> + return env_set_ulong(boot_left, tries - 1);
> +}
> +
> +static int distro_rauc_boot(struct udevice *dev, struct bootflow *bflow)
> +{
> + struct blk_desc *desc;
> + struct distro_rauc_priv *priv;
> + char *boot_order;
> + const char **boot_order_list;
> + const char *active_slot;
> + char raucargs[32];
> + ulong addr;
> + int ret = 0;
> + int i;
> +
> + desc = dev_get_uclass_plat(bflow->blk);
> + if (desc->uclass_id != UCLASS_MMC)
> + return log_msg_ret("blk", -EINVAL);
> + priv = bflow->bootmeth_priv;
> +
> + /* RAUC variables */
> + boot_order = env_get("BOOT_ORDER");
> + if (!boot_order)
> + return log_msg_ret("env", -ENOENT);
> + boot_order_list = str_to_list(boot_order);
> +
> + /* Device info variables */
> + ret = env_set("devtype", blk_get_devtype(bflow->blk));
> + if (ret)
> + return log_msg_ret("env", ret);
> +
> + ret = env_set_hex("devnum", desc->devnum);
> + if (ret)
> + return log_msg_ret("env", ret);
> +
> + /* Kernel command line arguments */
> + active_slot = strdup(boot_order_list[0]);
> + if (!active_slot)
> + return log_msg_ret("env", -ENOENT);
> + sprintf(raucargs, "rauc.slot=%s", active_slot);
> + ret = env_set("raucargs", raucargs);
> + if (ret)
> + return log_msg_ret("env", ret);
> +
> + /* TODO: If active_slot is in boot_order, but has 0 tries left, remove
> + * it from boot_order. Then, set active_slot to other, if available.
> + */
> +
> + /* Partition info variables */
> + for (i = 0; priv->slots[i].name != NULL; i++) {
> + if (strcmp(priv->slots[i].name, active_slot) == 0) {
> + ret = env_set_hex("mmcroot", priv->slots[i].root_part);
The 'mmcroot' description is missing in your docs patch. You might also
consider renaming it to something more descriptive, like mmc_root_part.
Do we really want to use env_set_hex for it?
Regards,
Wadim
> + if (ret)
> + return log_msg_ret("env", ret);
> + break;
> + }
> + }
> +
> + /* Load distro boot script */
> + ret = distro_rauc_load_boot_script(bflow, active_slot);
> + if (ret)
> + return log_msg_ret("load", ret);
> + ret = env_set_hex("distro_bootpart", bflow->part);
> + if (ret)
> + return log_msg_ret("env", ret);
> +
> + ret = decrement_slot_tries(active_slot);
> + if (ret)
> + return log_msg_ret("env", ret);
> + ret = env_save();
> + if (ret)
> + return log_msg_ret("env", ret);
> +
> + log_debug("devtype: %s\n", env_get("devtype"));
> + log_debug("devnum: %s\n", env_get("devnum"));
> + log_debug("distro_bootpart: %s\n", env_get("distro_bootpart"));
> + log_debug("mmcroot: %s\n", env_get("mmcroot"));
> + log_debug("raucargs: %s\n", env_get("raucargs"));
> + log_debug("rauc_slots: %s\n", env_get("rauc_slots"));
> + log_debug("rauc_partitions: %s\n", env_get("rauc_partitions"));
> + log_debug("rauc_slot_default_tries: %s\n", env_get("rauc_slot_default_tries"));
> + log_debug("BOOT_ORDER: %s\n", env_get("BOOT_ORDER"));
> + for (i = 0; priv->slots[i].name != NULL; i++) {
> + log_debug("BOOT_%s_LEFT: %ld\n", priv->slots[i].name,
> + priv->slots[i].left);
> + }
> +
> + /* Run distro boot script */
> + addr = map_to_sysmem(bflow->buf);
> + ret = cmd_source_script(addr, NULL, NULL);
> + if (ret)
> + return log_msg_ret("boot", ret);
> +
> + return 0;
> +}
> +
> +static int distro_rauc_bootmeth_bind(struct udevice *dev)
> +{
> + struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
> +
> + plat->desc = "RAUC distro boot from MMC";
> + plat->flags = BOOTMETHF_ANY_PART;
> +
> + return 0;
> +}
> +
> +static struct bootmeth_ops distro_rauc_bootmeth_ops = {
> + .check = distro_rauc_check,
> + .read_bootflow = distro_rauc_read_bootflow,
> + .read_file = distro_rauc_read_file,
> + .boot = distro_rauc_boot,
> +};
> +
> +static const struct udevice_id distro_rauc_bootmeth_ids[] = {
> + { .compatible = "u-boot,distro-rauc" },
> + { }
> +};
> +
> +U_BOOT_DRIVER(bootmeth_rauc) = {
> + .name = "bootmeth_rauc",
> + .id = UCLASS_BOOTMETH,
> + .of_match = distro_rauc_bootmeth_ids,
> + .ops = &distro_rauc_bootmeth_ops,
> + .bind = distro_rauc_bootmeth_bind,
> +};
>
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2025-05-06 7:05 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-29 14:25 [PATCH 0/2] bootstd: New bootmeth for RAUC A/B systems Martin Schwan
2025-01-29 14:25 ` [PATCH 1/2] bootstd: Add implementation for bootmeth rauc Martin Schwan
2025-01-29 16:03 ` Tom Rini
2025-01-30 9:48 ` Martin Schwan
2025-01-30 14:51 ` Tom Rini
2025-04-14 5:49 ` Wadim Egorov
2025-04-14 11:32 ` Simon Glass
2025-04-24 12:43 ` Martin Schwan
2025-04-24 18:31 ` Simon Glass
2025-04-24 18:49 ` Tom Rini
2025-04-25 14:35 ` Simon Glass
2025-04-25 14:37 ` Tom Rini
2025-04-25 15:03 ` Simon Glass
2025-04-25 16:19 ` Tom Rini
2025-04-28 8:25 ` Martin Schwan
2025-04-28 15:39 ` Tom Rini
2025-04-29 14:19 ` Simon Glass
2025-04-28 8:35 ` Alexander Dahl
2025-05-06 7:05 ` [Upstream] " Wadim Egorov
2025-01-29 14:25 ` [PATCH 2/2] doc: Add description " Martin Schwan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.