| Message ID | 20260429140130.615536-2-dario.binacchi@amarulasolutions.com |
|---|---|
| State | New |
| Headers | show |
| Series |
|
| Related | show |
Hi Dario, On 4/29/26 16:01, Dario Binacchi wrote: > Add a handler to manage the boot selection process according to > the Firmware Update (FWU) metadata specification using the > libfwumdata library. This seems that the specification is something generic, but this is really just for STM32MP2, as described in the cover. Then an according documentation should be added. Nevertheless, I will raise a basic issue about the concept. I cannot find the patches sent to openembedded-core, too. According to the related patches merged into U-Boot, this is a ST replacement for fw_setenv / fw_printenv. The configuration file, at least the one pushed to U-Boot, has the same old format as U-Boot's tools. So I am just asking why we should have a separate tool (yes, I saw in U-Boot, too) instead of integrating into the current ecosystem. From a concept view, the tool is used to select which is the active image to be booted, and select also some parms (flags) for it. In SWUpdate, this is the "bootloader" interface, and not a "script" handler. That can be implemented also as script, as here, is clear, but from the logical point of view, it does not belong to. And the second main aspect: if this is just to choose the active software set, and the fwumdata.c is poushed as replacement for FWU metadata of fw_setenv, and also taken into account that its code seems to me pretty simple, whhy shouldn't be integrated as storage into libubootenv, instead ? Then SWUpdate hasn't another interface, there is still the bootloader interface, and under the hood the FMU is written instead of U-Boot env. Best regards, Stefano > > The handler is a script handler that updates the active_index > and marks the selected bank as valid during the post-install phase. > > Example in sw-description: > > scripts: ( > { > type = "fwumdata"; > properties: { > active = "1"; > } > } > ); > > Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com> > --- > Kconfig | 4 ++ > Makefile.deps | 4 ++ > Makefile.flags | 3 + > bootloader/Kconfig | 7 ++ > configs/all_handlers_defconfig | 1 + > doc/source/handlers.rst | 37 ++++++++++ > handlers/Kconfig | 17 +++++ > handlers/Makefile | 1 + > handlers/fwumdata_handler.c | 125 +++++++++++++++++++++++++++++++++ > 9 files changed, 199 insertions(+) > create mode 100644 handlers/fwumdata_handler.c > > diff --git a/Kconfig b/Kconfig > index 2cf68eb890b0..fcb60f900b3f 100644 > --- a/Kconfig > +++ b/Kconfig > @@ -129,6 +129,10 @@ config HAVE_ZCK > bool > option env="HAVE_ZCK" > > +config HAVE_LIBFWUMDATA > + bool > + option env="HAVE_LIBFWUMDATA" > + > menu "SWUpdate Settings" > > menu "General Configuration" > diff --git a/Makefile.deps b/Makefile.deps > index c759f6876dea..313d5af6230c 100644 > --- a/Makefile.deps > +++ b/Makefile.deps > @@ -121,3 +121,7 @@ endif > ifeq ($(HAVE_ZCK),) > export HAVE_ZCK = y > endif > + > +ifeq ($(HAVE_LIBFWUMDATA),) > +export HAVE_LIBFWUMDATA = y > +endif > diff --git a/Makefile.flags b/Makefile.flags > index 40dd3b66856e..76b87e67fe67 100644 > --- a/Makefile.flags > +++ b/Makefile.flags > @@ -233,6 +233,9 @@ ifeq ($(CONFIG_UCFWHANDLER),y) > LDLIBS += gpiod > endif > > +ifeq ($(CONFIG_FWUMDATA_HANDLER),y) > +LDLIBS += fwumdata > +endif > > ifeq ($(CONFIG_BOOTLOADER_STATIC_LINKED),y) > ifeq ($(CONFIG_BOOTLOADER_EBG),y) > diff --git a/bootloader/Kconfig b/bootloader/Kconfig > index edc02d99b2d1..36f856507356 100644 > --- a/bootloader/Kconfig > +++ b/bootloader/Kconfig > @@ -158,3 +158,10 @@ config UPDATE_STATE_BOOTLOADER > help > Store update information in Bootloader's environment. > > +config FWUMDATA_CONFIG_FILE > + string "FWU Metadata Configuration file" > + depends on HAVE_LIBFWUMDATA > + default "/etc/fwumdata.config" > + help > + It tells where the FWU metadata are saved. > + > diff --git a/configs/all_handlers_defconfig b/configs/all_handlers_defconfig > index 16cd9b6b98f1..63299bd223ae 100644 > --- a/configs/all_handlers_defconfig > +++ b/configs/all_handlers_defconfig > @@ -20,6 +20,7 @@ CONFIG_DISKPART=y > CONFIG_DISKPART_FORMAT=y > CONFIG_DISKFORMAT_HANDLER=y > CONFIG_FAT_FILESYSTEM=y > +CONFIG_FWUMDATA_HANDLER=y > CONFIG_EXT_FILESYSTEM=y > CONFIG_LUASCRIPTHANDLER=y > CONFIG_RAW=y > diff --git a/doc/source/handlers.rst b/doc/source/handlers.rst > index 6742c10a58c3..cbfb146f099c 100644 > --- a/doc/source/handlers.rst > +++ b/doc/source/handlers.rst > @@ -1710,3 +1710,40 @@ Examples: > name = "helloworld"; > }; > }); > + > +FWU Metadata Handler > +-------------------- > + > +This is a script handler used to manage the boot selection process according to > +the Firmware Update (FWU) metadata specification. > + > +The handler implements a post-install script that updates the metadata to switch > +the active bank and marks it as valid, ensuring the system boots from the new > +bank at the next reset. The ``active`` property defines which bank must be > +selected. > + > +Example selecting boot bank 1 (bank A in A/B schema): > + > +:: > + > + scripts: ( > + { > + type = "fwumdata"; > + properties: { > + active = "1"; > + } > + } > + ); > + > +Example selecting boot bank 2 (bank B in A/B schema): > + > +:: > + > + scripts: ( > + { > + type = "fwumdata"; > + properties: { > + active = "2"; > + } > + } > + ); > diff --git a/handlers/Kconfig b/handlers/Kconfig > index 152bc08074a1..b7d9e51a20c9 100644 > --- a/handlers/Kconfig > +++ b/handlers/Kconfig > @@ -151,6 +151,23 @@ config EMMC_HANDLER > with a dual-copy concept. This guarantees that the upgrade > is power-cut safe. > > +config FWUMDATA_HANDLER > + bool "FWU metadata update" > + depends on HAVE_LIBFWUMDATA > + default n > + help > + This handler allows to manage the boot selection process using > + firmware update (FWU) metadata via libfwumdata. > + > + Selecting the new boot bank automatically triggers the handler to > + set the current bank for rollback and mark the selected boot-up > + bank as 'valid'. > + > + This ensures the system is ready to boot from the updated > + partition while maintaining a safe path to revert to the previous > + working state if the new firmware fails to reach the 'accepted' > + state > + > config RAW > bool "raw" > default n > diff --git a/handlers/Makefile b/handlers/Makefile > index 8490172a10a3..45fcb525e461 100644 > --- a/handlers/Makefile > +++ b/handlers/Makefile > @@ -30,3 +30,4 @@ obj-$(CONFIG_SWUFORWARDER_HANDLER) += swuforward_handler.o swuforward-ws.o > obj-$(CONFIG_UBIVOL) += ubivol_handler.o > obj-$(CONFIG_UCFWHANDLER) += ucfw_handler.o > obj-$(CONFIG_DOCKER) += docker_handler.o > +obj-$(CONFIG_FWUMDATA_HANDLER) += fwumdata_handler.o > diff --git a/handlers/fwumdata_handler.c b/handlers/fwumdata_handler.c > new file mode 100644 > index 000000000000..1331fe64aa74 > --- /dev/null > +++ b/handlers/fwumdata_handler.c > @@ -0,0 +1,125 @@ > +#include <stdio.h> > +#include <unistd.h> > +#include <fcntl.h> > +#include <stdlib.h> > +#include <stdbool.h> > +#include <errno.h> > +#include <linux/version.h> > +#include <sys/ioctl.h> > +#include <stddef.h> > + > +#include "swupdate_image.h" > +#include "handler.h" > +#include "util.h" > + > +#include <libfwumdata.h> > + > +static int _fwumdata_set(uint32_t active_index, uint32_t previous_index, > + uint8_t bank_state) > +{ > + int mdd; > + int ret; > + > + mdd = fwumdata_init(); > + if (mdd < 0) { > + ERROR("Cannot initialize libfwumdata\n"); > + return mdd; > + } > + > + ret = fwumdata_read_config(mdd, CONFIG_FWUMDATA_CONFIG_FILE); > + if (ret) { > + ERROR("Cannot read %s\n", CONFIG_FWUMDATA_CONFIG_FILE); > + goto exit; > + } > + > + ret = fwumdata_open(mdd, 0); > + if (ret) { > + ERROR("Cannot open %s\n", CONFIG_FWUMDATA_CONFIG_FILE); > + goto exit; > + } > + > + ret = fwumdata_set_active_index(mdd, active_index); > + if (ret) { > + ERROR("Cannot set active index\n"); > + goto close; > + } > + > + fwumdata_set_previous_index(mdd, previous_index); > + if (ret) { > + ERROR("Cannot set previous index\n"); > + goto close; > + } > + > + ret = fwumdata_set_bank_state(mdd, active_index, bank_state); > + if (ret) { > + ERROR("Cannot set bank state\n"); > + goto close; > + } > + > + ret = fwumdata_store(mdd); > + if (ret) { > + ERROR("Cannot store fwu metadata\n"); > + goto close; > + } > + > + DEBUG("fwumdata: active: %d, previous: %d, state: 0x%x", > + active_index, previous_index, bank_state); > + > +close: > + fwumdata_close(mdd); > +exit: > + fwumdata_exit(mdd); > + return ret; > +} > + > +static int fwumdata_set(struct img_type *img, void *data) > +{ > + struct script_handler_data *script_data; > + char *value; > + int active_index = -1; > + int previous_index; > + > + > + if (!data) > + return -EINVAL; > + > + script_data = data; > + > + /* > + * Call only in case of postinstall > + */ > + if (script_data->scriptfn != POSTINSTALL) > + return 0; > + > + value = dict_get_value(&img->properties, "active"); > + if (!value) { > + ERROR("active: cannot find in sw-description"); > + return -EINVAL; > + } > + > + active_index = ustrtoull(value, NULL, 10); > + if (errno) { > + ERROR("active %s: ustrotull failed", value); > + return -EINVAL; > + } > + > + active_index--; > + if (active_index == 0) { > + previous_index = 1; > + } else if (active_index == 1) { > + previous_index = 0; > + } else { > + ERROR("active %s: invalid value", value); > + return -EINVAL; > + > + } > + > + return _fwumdata_set(active_index, previous_index, FWUMDATA_BANK_VALID); > +} > + > +__attribute__((constructor)) > +void fwumdata_handler(void) > +{ > + register_handler("fwumdata", fwumdata_set, > + SCRIPT_HANDLER | NO_DATA_HANDLER, NULL); > +}
Hi Dario, On 4/29/26 16:01, Dario Binacchi wrote: > Add a handler to manage the boot selection process according to > the Firmware Update (FWU) metadata specification using the > libfwumdata library. This seems that the specification is something generic, but this is really just for STM32MP2, as described in the cover. Then an according documentation should be added. Nevertheless, I will raise a basic issue about the concept. I cannot find the patches sent to openembedded-core, too. According to the related patches merged into U-Boot, this is a ST replacement for fw_setenv / fw_printenv. The configuration file, at least the one pushed to U-Boot, has the same old format as U-Boot's tools. So I am just asking why we should have a separate tool (yes, I saw in U-Boot, too) instead of integrating into the current ecosystem. From a concept view, the tool is used to select which is the active image to be booted, and select also some parms (flags) for it. In SWUpdate, this is the "bootloader" interface, and not a "script" handler. That can be implemented also as script, as here, is clear, but from the logical point of view, it does not belong to. And the second main aspect: if this is just to choose the active software set, and the fwumdata.c is poushed as replacement for FWU metadata of fw_setenv, and also taken into account that its code seems to me pretty simple, whhy shouldn't be integrated as storage into libubootenv, instead ? Then SWUpdate hasn't another interface, there is still the bootloader interface, and under the hood the FMU is written instead of U-Boot env. Best regards, Stefano > > The handler is a script handler that updates the active_index > and marks the selected bank as valid during the post-install phase. > > Example in sw-description: > > scripts: ( > { > type = "fwumdata"; > properties: { > active = "1"; > } > } > ); > > Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com> > --- > Kconfig | 4 ++ > Makefile.deps | 4 ++ > Makefile.flags | 3 + > bootloader/Kconfig | 7 ++ > configs/all_handlers_defconfig | 1 + > doc/source/handlers.rst | 37 ++++++++++ > handlers/Kconfig | 17 +++++ > handlers/Makefile | 1 + > handlers/fwumdata_handler.c | 125 +++++++++++++++++++++++++++++++++ > 9 files changed, 199 insertions(+) > create mode 100644 handlers/fwumdata_handler.c > > diff --git a/Kconfig b/Kconfig > index 2cf68eb890b0..fcb60f900b3f 100644 > --- a/Kconfig > +++ b/Kconfig > @@ -129,6 +129,10 @@ config HAVE_ZCK > bool > option env="HAVE_ZCK" > > +config HAVE_LIBFWUMDATA > + bool > + option env="HAVE_LIBFWUMDATA" > + > menu "SWUpdate Settings" > > menu "General Configuration" > diff --git a/Makefile.deps b/Makefile.deps > index c759f6876dea..313d5af6230c 100644 > --- a/Makefile.deps > +++ b/Makefile.deps > @@ -121,3 +121,7 @@ endif > ifeq ($(HAVE_ZCK),) > export HAVE_ZCK = y > endif > + > +ifeq ($(HAVE_LIBFWUMDATA),) > +export HAVE_LIBFWUMDATA = y > +endif > diff --git a/Makefile.flags b/Makefile.flags > index 40dd3b66856e..76b87e67fe67 100644 > --- a/Makefile.flags > +++ b/Makefile.flags > @@ -233,6 +233,9 @@ ifeq ($(CONFIG_UCFWHANDLER),y) > LDLIBS += gpiod > endif > > +ifeq ($(CONFIG_FWUMDATA_HANDLER),y) > +LDLIBS += fwumdata > +endif > > ifeq ($(CONFIG_BOOTLOADER_STATIC_LINKED),y) > ifeq ($(CONFIG_BOOTLOADER_EBG),y) > diff --git a/bootloader/Kconfig b/bootloader/Kconfig > index edc02d99b2d1..36f856507356 100644 > --- a/bootloader/Kconfig > +++ b/bootloader/Kconfig > @@ -158,3 +158,10 @@ config UPDATE_STATE_BOOTLOADER > help > Store update information in Bootloader's environment. > > +config FWUMDATA_CONFIG_FILE > + string "FWU Metadata Configuration file" > + depends on HAVE_LIBFWUMDATA > + default "/etc/fwumdata.config" > + help > + It tells where the FWU metadata are saved. > + > diff --git a/configs/all_handlers_defconfig b/configs/all_handlers_defconfig > index 16cd9b6b98f1..63299bd223ae 100644 > --- a/configs/all_handlers_defconfig > +++ b/configs/all_handlers_defconfig > @@ -20,6 +20,7 @@ CONFIG_DISKPART=y > CONFIG_DISKPART_FORMAT=y > CONFIG_DISKFORMAT_HANDLER=y > CONFIG_FAT_FILESYSTEM=y > +CONFIG_FWUMDATA_HANDLER=y > CONFIG_EXT_FILESYSTEM=y > CONFIG_LUASCRIPTHANDLER=y > CONFIG_RAW=y > diff --git a/doc/source/handlers.rst b/doc/source/handlers.rst > index 6742c10a58c3..cbfb146f099c 100644 > --- a/doc/source/handlers.rst > +++ b/doc/source/handlers.rst > @@ -1710,3 +1710,40 @@ Examples: > name = "helloworld"; > }; > }); > + > +FWU Metadata Handler > +-------------------- > + > +This is a script handler used to manage the boot selection process according to > +the Firmware Update (FWU) metadata specification. > + > +The handler implements a post-install script that updates the metadata to switch > +the active bank and marks it as valid, ensuring the system boots from the new > +bank at the next reset. The ``active`` property defines which bank must be > +selected. > + > +Example selecting boot bank 1 (bank A in A/B schema): > + > +:: > + > + scripts: ( > + { > + type = "fwumdata"; > + properties: { > + active = "1"; > + } > + } > + ); > + > +Example selecting boot bank 2 (bank B in A/B schema): > + > +:: > + > + scripts: ( > + { > + type = "fwumdata"; > + properties: { > + active = "2"; > + } > + } > + ); > diff --git a/handlers/Kconfig b/handlers/Kconfig > index 152bc08074a1..b7d9e51a20c9 100644 > --- a/handlers/Kconfig > +++ b/handlers/Kconfig > @@ -151,6 +151,23 @@ config EMMC_HANDLER > with a dual-copy concept. This guarantees that the upgrade > is power-cut safe. > > +config FWUMDATA_HANDLER > + bool "FWU metadata update" > + depends on HAVE_LIBFWUMDATA > + default n > + help > + This handler allows to manage the boot selection process using > + firmware update (FWU) metadata via libfwumdata. > + > + Selecting the new boot bank automatically triggers the handler to > + set the current bank for rollback and mark the selected boot-up > + bank as 'valid'. > + > + This ensures the system is ready to boot from the updated > + partition while maintaining a safe path to revert to the previous > + working state if the new firmware fails to reach the 'accepted' > + state > + > config RAW > bool "raw" > default n > diff --git a/handlers/Makefile b/handlers/Makefile > index 8490172a10a3..45fcb525e461 100644 > --- a/handlers/Makefile > +++ b/handlers/Makefile > @@ -30,3 +30,4 @@ obj-$(CONFIG_SWUFORWARDER_HANDLER) += swuforward_handler.o swuforward-ws.o > obj-$(CONFIG_UBIVOL) += ubivol_handler.o > obj-$(CONFIG_UCFWHANDLER) += ucfw_handler.o > obj-$(CONFIG_DOCKER) += docker_handler.o > +obj-$(CONFIG_FWUMDATA_HANDLER) += fwumdata_handler.o > diff --git a/handlers/fwumdata_handler.c b/handlers/fwumdata_handler.c > new file mode 100644 > index 000000000000..1331fe64aa74 > --- /dev/null > +++ b/handlers/fwumdata_handler.c > @@ -0,0 +1,125 @@ > +#include <stdio.h> > +#include <unistd.h> > +#include <fcntl.h> > +#include <stdlib.h> > +#include <stdbool.h> > +#include <errno.h> > +#include <linux/version.h> > +#include <sys/ioctl.h> > +#include <stddef.h> > + > +#include "swupdate_image.h" > +#include "handler.h" > +#include "util.h" > + > +#include <libfwumdata.h> > + > +static int _fwumdata_set(uint32_t active_index, uint32_t previous_index, > + uint8_t bank_state) > +{ > + int mdd; > + int ret; > + > + mdd = fwumdata_init(); > + if (mdd < 0) { > + ERROR("Cannot initialize libfwumdata\n"); > + return mdd; > + } > + > + ret = fwumdata_read_config(mdd, CONFIG_FWUMDATA_CONFIG_FILE); > + if (ret) { > + ERROR("Cannot read %s\n", CONFIG_FWUMDATA_CONFIG_FILE); > + goto exit; > + } > + > + ret = fwumdata_open(mdd, 0); > + if (ret) { > + ERROR("Cannot open %s\n", CONFIG_FWUMDATA_CONFIG_FILE); > + goto exit; > + } > + > + ret = fwumdata_set_active_index(mdd, active_index); > + if (ret) { > + ERROR("Cannot set active index\n"); > + goto close; > + } > + > + fwumdata_set_previous_index(mdd, previous_index); > + if (ret) { > + ERROR("Cannot set previous index\n"); > + goto close; > + } > + > + ret = fwumdata_set_bank_state(mdd, active_index, bank_state); > + if (ret) { > + ERROR("Cannot set bank state\n"); > + goto close; > + } > + > + ret = fwumdata_store(mdd); > + if (ret) { > + ERROR("Cannot store fwu metadata\n"); > + goto close; > + } > + > + DEBUG("fwumdata: active: %d, previous: %d, state: 0x%x", > + active_index, previous_index, bank_state); > + > +close: > + fwumdata_close(mdd); > +exit: > + fwumdata_exit(mdd); > + return ret; > +} > + > +static int fwumdata_set(struct img_type *img, void *data) > +{ > + struct script_handler_data *script_data; > + char *value; > + int active_index = -1; > + int previous_index; > + > + > + if (!data) > + return -EINVAL; > + > + script_data = data; > + > + /* > + * Call only in case of postinstall > + */ > + if (script_data->scriptfn != POSTINSTALL) > + return 0; > + > + value = dict_get_value(&img->properties, "active"); > + if (!value) { > + ERROR("active: cannot find in sw-description"); > + return -EINVAL; > + } > + > + active_index = ustrtoull(value, NULL, 10); > + if (errno) { > + ERROR("active %s: ustrotull failed", value); > + return -EINVAL; > + } > + > + active_index--; > + if (active_index == 0) { > + previous_index = 1; > + } else if (active_index == 1) { > + previous_index = 0; > + } else { > + ERROR("active %s: invalid value", value); > + return -EINVAL; > + > + } > + > + return _fwumdata_set(active_index, previous_index, FWUMDATA_BANK_VALID); > +} > + > +__attribute__((constructor)) > +void fwumdata_handler(void) > +{ > + register_handler("fwumdata", fwumdata_set, > + SCRIPT_HANDLER | NO_DATA_HANDLER, NULL); > +}
Hi Stefano, On Wed, Apr 29, 2026 at 5:12 PM Stefano Babic <stefano.babic@swupdate.org> wrote: > Hi Dario, > > On 4/29/26 16:01, Dario Binacchi wrote: > > Add a handler to manage the boot selection process according to > > the Firmware Update (FWU) metadata specification using the > > libfwumdata library. > > This seems that the specification is something generic, but this is > really just for STM32MP2, as described in the cover. Then an according > documentation should be added. > AFAIK the FWU (Firmware Update) metadata is a fully generic specification (part of the Arm FWU specification). While the STM32MP2 is my use case and the reason I wrote this patch, the standard and this implementation are not ST-specific. Other platforms already implement and use FWU metadata in U-Boot, so the handler is meant to be completely platform-agnostic. > > Nevertheless, I will raise a basic issue about the concept. I cannot > find the patches sent to openembedded-core, too. > You can find the patch submitted to oe-core here: https://patchwork.yoctoproject.org/project/oe-core/patch/20260429145136.618168-1-dario.binacchi@amarulasolutions.com/ > > According to the related patches merged into U-Boot, this is a ST > replacement for fw_setenv / fw_printenv. The configuration file, at > least the one pushed to U-Boot, has the same old format as U-Boot's > tools. So I am just asking why we should have a separate tool (yes, I > saw in U-Boot, too) instead of integrating into the current ecosystem. > > From a concept view, the tool is used to select which is the active > image to be booted, and select also some parms (flags) for it. In > SWUpdate, this is the "bootloader" interface, and not a "script" > handler. That can be implemented also as script, as here, is clear, but > from the logical point of view, it does not belong to. > Implementing it as a "script" handler was simply the easiest and fastest path for me to validate the concept, and I should have probably tagged the patch as an RFC for this reason. I agree that, from a logical point of view, this belongs in the "bootloader" interface. > > And the second main aspect: if this is just to choose the active > software set, and the fwumdata.c is poushed as replacement for FWU > metadata of fw_setenv, and also taken into account that its code seems > to me pretty simple, whhy shouldn't be integrated as storage into > libubootenv, instead ? I believe it should remain a separate library (libfwumdata) for a couple of reasons: Conceptual separation: U-Boot itself keeps the standard environment and FWU metadata separated. They serve different purposes and have entirely different structures (a flexible key-value store vs. a rigidly defined A/B state structure). Merging FWU metadata handling into libubootenv could lead to conceptual misunderstandings. Dedicated API: I think it's correct to have a dedicated, minimal C library specifically designed to allow any userspace application - not just SWUpdate, but also other OTA managers or proprietary system services - to easily switch boot banks. It differs from U-Boot's mkfwumdata (which generates the metadata image from scratch at build time) and fwumdata (the CLI tool for targeted updates). libfwumdata provides a strictly limited, safe C API to update just the 3 fields needed for a bank switch. So, can we meet halfway? We could integrate the management of FWU variables inside bootloader/uboot.c. If a variable has the fwu- prefix (e.g., fwu-active), it will be saved using libfwumdata; otherwise, it will be handled by libubootenv as usual. Keeping libfwumdata separate avoids forcing FWU metadata management inside the libubootenv library. This approach gives users a seamless bootenv: interface while keeping the underlying architectures clean. Would this compromise be acceptable to you for v2? Thanks and regards, Dario > Then SWUpdate hasn't another interface, there is > still the bootloader interface, and under the hood the FMU is written > instead of U-Boot env. > > Best regards, > Stefano > > > > > The handler is a script handler that updates the active_index > > and marks the selected bank as valid during the post-install phase. > > > > Example in sw-description: > > > > scripts: ( > > { > > type = "fwumdata"; > > properties: { > > active = "1"; > > } > > } > > ); > > > > Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com> > > --- > > Kconfig | 4 ++ > > Makefile.deps | 4 ++ > > Makefile.flags | 3 + > > bootloader/Kconfig | 7 ++ > > configs/all_handlers_defconfig | 1 + > > doc/source/handlers.rst | 37 ++++++++++ > > handlers/Kconfig | 17 +++++ > > handlers/Makefile | 1 + > > handlers/fwumdata_handler.c | 125 +++++++++++++++++++++++++++++++++ > > 9 files changed, 199 insertions(+) > > create mode 100644 handlers/fwumdata_handler.c > > > > diff --git a/Kconfig b/Kconfig > > index 2cf68eb890b0..fcb60f900b3f 100644 > > --- a/Kconfig > > +++ b/Kconfig > > @@ -129,6 +129,10 @@ config HAVE_ZCK > > bool > > option env="HAVE_ZCK" > > > > +config HAVE_LIBFWUMDATA > > + bool > > + option env="HAVE_LIBFWUMDATA" > > + > > menu "SWUpdate Settings" > > > > menu "General Configuration" > > diff --git a/Makefile.deps b/Makefile.deps > > index c759f6876dea..313d5af6230c 100644 > > --- a/Makefile.deps > > +++ b/Makefile.deps > > @@ -121,3 +121,7 @@ endif > > ifeq ($(HAVE_ZCK),) > > export HAVE_ZCK = y > > endif > > + > > +ifeq ($(HAVE_LIBFWUMDATA),) > > +export HAVE_LIBFWUMDATA = y > > +endif > > diff --git a/Makefile.flags b/Makefile.flags > > index 40dd3b66856e..76b87e67fe67 100644 > > --- a/Makefile.flags > > +++ b/Makefile.flags > > @@ -233,6 +233,9 @@ ifeq ($(CONFIG_UCFWHANDLER),y) > > LDLIBS += gpiod > > endif > > > > +ifeq ($(CONFIG_FWUMDATA_HANDLER),y) > > +LDLIBS += fwumdata > > +endif > > > > ifeq ($(CONFIG_BOOTLOADER_STATIC_LINKED),y) > > ifeq ($(CONFIG_BOOTLOADER_EBG),y) > > diff --git a/bootloader/Kconfig b/bootloader/Kconfig > > index edc02d99b2d1..36f856507356 100644 > > --- a/bootloader/Kconfig > > +++ b/bootloader/Kconfig > > @@ -158,3 +158,10 @@ config UPDATE_STATE_BOOTLOADER > > help > > Store update information in Bootloader's environment. > > > > +config FWUMDATA_CONFIG_FILE > > + string "FWU Metadata Configuration file" > > + depends on HAVE_LIBFWUMDATA > > + default "/etc/fwumdata.config" > > + help > > + It tells where the FWU metadata are saved. > > + > > diff --git a/configs/all_handlers_defconfig > b/configs/all_handlers_defconfig > > index 16cd9b6b98f1..63299bd223ae 100644 > > --- a/configs/all_handlers_defconfig > > +++ b/configs/all_handlers_defconfig > > @@ -20,6 +20,7 @@ CONFIG_DISKPART=y > > CONFIG_DISKPART_FORMAT=y > > CONFIG_DISKFORMAT_HANDLER=y > > CONFIG_FAT_FILESYSTEM=y > > +CONFIG_FWUMDATA_HANDLER=y > > CONFIG_EXT_FILESYSTEM=y > > CONFIG_LUASCRIPTHANDLER=y > > CONFIG_RAW=y > > diff --git a/doc/source/handlers.rst b/doc/source/handlers.rst > > index 6742c10a58c3..cbfb146f099c 100644 > > --- a/doc/source/handlers.rst > > +++ b/doc/source/handlers.rst > > @@ -1710,3 +1710,40 @@ Examples: > > name = "helloworld"; > > }; > > }); > > + > > +FWU Metadata Handler > > +-------------------- > > + > > +This is a script handler used to manage the boot selection process > according to > > +the Firmware Update (FWU) metadata specification. > > + > > +The handler implements a post-install script that updates the metadata > to switch > > +the active bank and marks it as valid, ensuring the system boots from > the new > > +bank at the next reset. The ``active`` property defines which bank must > be > > +selected. > > + > > +Example selecting boot bank 1 (bank A in A/B schema): > > + > > +:: > > + > > + scripts: ( > > + { > > + type = "fwumdata"; > > + properties: { > > + active = "1"; > > + } > > + } > > + ); > > + > > +Example selecting boot bank 2 (bank B in A/B schema): > > + > > +:: > > + > > + scripts: ( > > + { > > + type = "fwumdata"; > > + properties: { > > + active = "2"; > > + } > > + } > > + ); > > diff --git a/handlers/Kconfig b/handlers/Kconfig > > index 152bc08074a1..b7d9e51a20c9 100644 > > --- a/handlers/Kconfig > > +++ b/handlers/Kconfig > > @@ -151,6 +151,23 @@ config EMMC_HANDLER > > with a dual-copy concept. This guarantees that the upgrade > > is power-cut safe. > > > > +config FWUMDATA_HANDLER > > + bool "FWU metadata update" > > + depends on HAVE_LIBFWUMDATA > > + default n > > + help > > + This handler allows to manage the boot selection process using > > + firmware update (FWU) metadata via libfwumdata. > > + > > + Selecting the new boot bank automatically triggers the handler to > > + set the current bank for rollback and mark the selected boot-up > > + bank as 'valid'. > > + > > + This ensures the system is ready to boot from the updated > > + partition while maintaining a safe path to revert to the previous > > + working state if the new firmware fails to reach the 'accepted' > > + state > > + > > config RAW > > bool "raw" > > default n > > diff --git a/handlers/Makefile b/handlers/Makefile > > index 8490172a10a3..45fcb525e461 100644 > > --- a/handlers/Makefile > > +++ b/handlers/Makefile > > @@ -30,3 +30,4 @@ obj-$(CONFIG_SWUFORWARDER_HANDLER) += > swuforward_handler.o swuforward-ws.o > > obj-$(CONFIG_UBIVOL) += ubivol_handler.o > > obj-$(CONFIG_UCFWHANDLER) += ucfw_handler.o > > obj-$(CONFIG_DOCKER) += docker_handler.o > > +obj-$(CONFIG_FWUMDATA_HANDLER) += fwumdata_handler.o > > diff --git a/handlers/fwumdata_handler.c b/handlers/fwumdata_handler.c > > new file mode 100644 > > index 000000000000..1331fe64aa74 > > --- /dev/null > > +++ b/handlers/fwumdata_handler.c > > @@ -0,0 +1,125 @@ > > +#include <stdio.h> > > +#include <unistd.h> > > +#include <fcntl.h> > > +#include <stdlib.h> > > +#include <stdbool.h> > > +#include <errno.h> > > +#include <linux/version.h> > > +#include <sys/ioctl.h> > > +#include <stddef.h> > > + > > +#include "swupdate_image.h" > > +#include "handler.h" > > +#include "util.h" > > + > > +#include <libfwumdata.h> > > + > > +static int _fwumdata_set(uint32_t active_index, uint32_t previous_index, > > + uint8_t bank_state) > > +{ > > + int mdd; > > + int ret; > > + > > + mdd = fwumdata_init(); > > + if (mdd < 0) { > > + ERROR("Cannot initialize libfwumdata\n"); > > + return mdd; > > + } > > + > > + ret = fwumdata_read_config(mdd, CONFIG_FWUMDATA_CONFIG_FILE); > > + if (ret) { > > + ERROR("Cannot read %s\n", CONFIG_FWUMDATA_CONFIG_FILE); > > + goto exit; > > + } > > + > > + ret = fwumdata_open(mdd, 0); > > + if (ret) { > > + ERROR("Cannot open %s\n", CONFIG_FWUMDATA_CONFIG_FILE); > > + goto exit; > > + } > > + > > + ret = fwumdata_set_active_index(mdd, active_index); > > + if (ret) { > > + ERROR("Cannot set active index\n"); > > + goto close; > > + } > > + > > + fwumdata_set_previous_index(mdd, previous_index); > > + if (ret) { > > + ERROR("Cannot set previous index\n"); > > + goto close; > > + } > > + > > + ret = fwumdata_set_bank_state(mdd, active_index, bank_state); > > + if (ret) { > > + ERROR("Cannot set bank state\n"); > > + goto close; > > + } > > + > > + ret = fwumdata_store(mdd); > > + if (ret) { > > + ERROR("Cannot store fwu metadata\n"); > > + goto close; > > + } > > + > > + DEBUG("fwumdata: active: %d, previous: %d, state: 0x%x", > > + active_index, previous_index, bank_state); > > + > > +close: > > + fwumdata_close(mdd); > > +exit: > > + fwumdata_exit(mdd); > > + return ret; > > +} > > + > > +static int fwumdata_set(struct img_type *img, void *data) > > +{ > > + struct script_handler_data *script_data; > > + char *value; > > + int active_index = -1; > > + int previous_index; > > + > > + > > + if (!data) > > + return -EINVAL; > > + > > + script_data = data; > > + > > + /* > > + * Call only in case of postinstall > > + */ > > + if (script_data->scriptfn != POSTINSTALL) > > + return 0; > > + > > + value = dict_get_value(&img->properties, "active"); > > + if (!value) { > > + ERROR("active: cannot find in sw-description"); > > + return -EINVAL; > > + } > > + > > + active_index = ustrtoull(value, NULL, 10); > > + if (errno) { > > + ERROR("active %s: ustrotull failed", value); > > + return -EINVAL; > > + } > > + > > + active_index--; > > + if (active_index == 0) { > > + previous_index = 1; > > + } else if (active_index == 1) { > > + previous_index = 0; > > + } else { > > + ERROR("active %s: invalid value", value); > > + return -EINVAL; > > + > > + } > > + > > + return _fwumdata_set(active_index, previous_index, > FWUMDATA_BANK_VALID); > > +} > > + > > +__attribute__((constructor)) > > +void fwumdata_handler(void) > > +{ > > + register_handler("fwumdata", fwumdata_set, > > + SCRIPT_HANDLER | NO_DATA_HANDLER, NULL); > > +} > > -- > _______________________________________________________________________ > Nabla Software Engineering GmbH > Hirschstr. 111A | 86156 Augsburg | Tel: +49 821 45592596 > Geschäftsführer : Stefano Babic | HRB 40522 Augsburg > E-Mail: sbabic@nabladev.com > > > -- > _______________________________________________________________________ > Nabla Software Engineering GmbH > Hirschstr. 111A | 86156 Augsburg | Tel: +49 821 45592596 > Geschäftsführer : Stefano Babic | HRB 40522 Augsburg > E-Mail: sbabic@nabladev.com >
Hi Stefano, On Thu, Apr 30, 2026 at 3:24 PM Stefano Babic <stefano.babic@swupdate.org> wrote: > Hi Dario, > > On 4/30/26 14:52, Dario Binacchi wrote: > > Hi Stefano, > > > > On Wed, Apr 29, 2026 at 5:12 PM Stefano Babic > > <stefano.babic@swupdate.org <mailto:stefano.babic@swupdate.org>> wrote: > > > > Hi Dario, > > > > On 4/29/26 16:01, Dario Binacchi wrote: > > > Add a handler to manage the boot selection process according to > > > the Firmware Update (FWU) metadata specification using the > > > libfwumdata library. > > > > This seems that the specification is something generic, but this is > > really just for STM32MP2, as described in the cover. Then an > according > > documentation should be added. > > > > > > AFAIK the FWU (Firmware Update) metadata is a fully generic specification > > (part of the Arm FWU specification). While the STM32MP2 is my use case > > and the > > reason I wrote this patch, the standard and this implementation are not > > ST-specific. Other platforms already implement and use FWU metadata in > > U-Boot, > > so the handler is meant to be completely platform-agnostic. > > > > > > Nevertheless, I will raise a basic issue about the concept. I cannot > > find the patches sent to openembedded-core, too. > > > > > > You can find the patch submitted to oe-core here: > > https://patchwork.yoctoproject.org/project/oe-core/ > > patch/20260429145136.618168-1-dario.binacchi@amarulasolutions.com/ > > <https://patchwork.yoctoproject.org/project/oe-core/ > > patch/20260429145136.618168-1-dario.binacchi@amarulasolutions.com/> > > Thanks ! > > > > > > > According to the related patches merged into U-Boot, this is a ST > > replacement for fw_setenv / fw_printenv. The configuration file, at > > least the one pushed to U-Boot, has the same old format as U-Boot's > > tools. So I am just asking why we should have a separate tool (yes, I > > saw in U-Boot, too) instead of integrating into the current > ecosystem. > > > > From a concept view, the tool is used to select which is the active > > image to be booted, and select also some parms (flags) for it. In > > SWUpdate, this is the "bootloader" interface, and not a "script" > > handler. That can be implemented also as script, as here, is clear, > but > > from the logical point of view, it does not belong to. > > > > > > Implementing it as a "script" handler was simply the easiest and fastest > > path for me to validate the concept, and I should have probably tagged > > the patch as an RFC for this reason. I agree that, from a logical > point of > > view, this belongs in the "bootloader" interface. > > > > Ok > > > > > And the second main aspect: if this is just to choose the active > > software set, and the fwumdata.c is poushed as replacement for FWU > > metadata of fw_setenv, and also taken into account that its code > seems > > to me pretty simple, whhy shouldn't be integrated as storage into > > libubootenv, instead ? > > > > > > I believe it should remain a separate library (libfwumdata) for a couple > > of reasons: > > > > Conceptual separation: U-Boot itself keeps the standard environment and > > FWU metadata separated. They serve different purposes and have > > entirely different structures (a flexible key-value store vs. a rigidly > > defined A/B state structure). Merging FWU metadata handling into > > libubootenv could lead to conceptual misunderstandings. > > But libubootenv maintains the name, but it is already not only thought > for U-Boot. Currently, it is used to store persistently tuple FWU metadata is fundamentally not a collection of arbitrary tuples (key-value pairs). It is a rigidly defined binary structure. I think that forcing the FWU metadata to be accessed and managed through a generic tuple-based interface is an architectural stretch. It would artificially limit the correct management of the data and any future implementation of the FWU specification features just to fit into a key-value paradigm. > that must > survive an update. Namespaces allow to set vars into different domains > than U-Boot (bootloader vars vs application vars is the most typical use > case). A FWU will be just a different namespace, but interface remains > coherent. > > > > > Dedicated API: I think it's correct to have a dedicated, minimal C > library > > specifically designed to allow any userspace application - not just > > SWUpdate, > > but also other OTA managers or proprietary system services - to > easily > switch > > Well, this was one reason for the libubootenv, and it is used by other > OTA updater, too. It is not bound to SWUpdate, SWUpdate is just an user > of the library. > > So checking inside your libfwumdata, and seeing the analogies with > libubootenv, and you have already stated in the header that there are > parts taken from libubootenv, I am even less convinced that adding > another additional library is the best way to go. The similarities you noticed with libubootenv are absolutely intentional, but they are strictly limited to the API design pattern (the init, open, store, close flow) and the configuration file parsing. I adopted this pattern because it is a familiar and robust approach for the ecosystem, not because the underlying data models are compatible. Furthermore, there are specific FWU API functions that simply cannot be implemented as standard get/set functions due to this completely different data structure. A clear proof of this structural divergence is the implementation of the yafwumdata tool itself, which mimics the U-Boot tool but is specifically tailored to handle the unique logic of the FWU standard. Since you know SWUpdate's architecture inside out, I want to leave the ball in your court. Is there really no other way to implement this cleanly without shoehorning a fixed binary structure into a string dictionary like libubootenv? Is it possible to find a design compromise that respects the nature of the FWU standard and doesn't leave either of us completely dissatisfied? Thanks and regards, Dario If I can agree about > the separation from U-B0oot environment (and this is already provided > via name3space), why is this not simply done by adding to libubootenv ? > It can be still used by any OTA, it is still separated by U-Boot's env > (ok, not the name..), configuration is already in a more modern and > flexible way as in old U-Boot and in libfwumdata, that takes over from > U-Boot (YAML). > > The most practical way seems to extend the current library instead of > creating a new one. > > > boot banks. It differs from U-Boot's mkfwumdata (which generates the > > metadata > > image from scratch at build time) and fwumdata (the CLI tool for > > targeted updates). > > libfwumdata provides a strictly limited, safe C API to update just the 3 > > fields needed for a bank switch. > > > > So, can we meet halfway? We could integrate the management of FWU > variables > > inside bootloader/uboot.c. > > Not at all. It is a bad solution for you, too. We agree that is > separated by U-Boot, then this mixes all up. > > > If a variable has the fwu- prefix (e.g., fwu- > > active), > > it will be saved using libfwumdata; otherwise, it will be handled by > > libubootenv as usual. > > This is just a hack - I fully disagree here. > > And be sure, there will be some user early or later who starts to set > U-Boot variables starting with "fwu" ("Fair World Unit", maybe ?) and he > will complain it does not work. > > > > > Keeping libfwumdata separate avoids forcing FWU metadata management > inside > > the libubootenv library. This approach gives users a seamless bootenv: > > interface > > while keeping the underlying architectures clean. > > I do not see the advantage here - on the opposite, if it is integrated, > user has the same interface. > > > > > Would this compromise be acceptable to you for v2? > > > > Sorry, not. > > Best regards, > Stefano > > > Thanks and regards, > > Dario > > > > Then SWUpdate hasn't another interface, there is > > still the bootloader interface, and under the hood the FMU is written > > instead of U-Boot env. > > > > Best regards, > > Stefano > > > > > > > > The handler is a script handler that updates the active_index > > > and marks the selected bank as valid during the post-install > phase. > > > > > > Example in sw-description: > > > > > > scripts: ( > > > { > > > type = "fwumdata"; > > > properties: { > > > active = "1"; > > > } > > > } > > > ); > > > > > > Signed-off-by: Dario Binacchi > > <dario.binacchi@amarulasolutions.com > > <mailto:dario.binacchi@amarulasolutions.com>> > > > --- > > > Kconfig | 4 ++ > > > Makefile.deps | 4 ++ > > > Makefile.flags | 3 + > > > bootloader/Kconfig | 7 ++ > > > configs/all_handlers_defconfig | 1 + > > > doc/source/handlers.rst | 37 ++++++++++ > > > handlers/Kconfig | 17 +++++ > > > handlers/Makefile | 1 + > > > handlers/fwumdata_handler.c | 125 ++++++++++++++++++++++++++ > > +++++++ > > > 9 files changed, 199 insertions(+) > > > create mode 100644 handlers/fwumdata_handler.c > > > > > > diff --git a/Kconfig b/Kconfig > > > index 2cf68eb890b0..fcb60f900b3f 100644 > > > --- a/Kconfig > > > +++ b/Kconfig > > > @@ -129,6 +129,10 @@ config HAVE_ZCK > > > bool > > > option env="HAVE_ZCK" > > > > > > +config HAVE_LIBFWUMDATA > > > + bool > > > + option env="HAVE_LIBFWUMDATA" > > > + > > > menu "SWUpdate Settings" > > > > > > menu "General Configuration" > > > diff --git a/Makefile.deps b/Makefile.deps > > > index c759f6876dea..313d5af6230c 100644 > > > --- a/Makefile.deps > > > +++ b/Makefile.deps > > > @@ -121,3 +121,7 @@ endif > > > ifeq ($(HAVE_ZCK),) > > > export HAVE_ZCK = y > > > endif > > > + > > > +ifeq ($(HAVE_LIBFWUMDATA),) > > > +export HAVE_LIBFWUMDATA = y > > > +endif > > > diff --git a/Makefile.flags b/Makefile.flags > > > index 40dd3b66856e..76b87e67fe67 100644 > > > --- a/Makefile.flags > > > +++ b/Makefile.flags > > > @@ -233,6 +233,9 @@ ifeq ($(CONFIG_UCFWHANDLER),y) > > > LDLIBS += gpiod > > > endif > > > > > > +ifeq ($(CONFIG_FWUMDATA_HANDLER),y) > > > +LDLIBS += fwumdata > > > +endif > > > > > > ifeq ($(CONFIG_BOOTLOADER_STATIC_LINKED),y) > > > ifeq ($(CONFIG_BOOTLOADER_EBG),y) > > > diff --git a/bootloader/Kconfig b/bootloader/Kconfig > > > index edc02d99b2d1..36f856507356 100644 > > > --- a/bootloader/Kconfig > > > +++ b/bootloader/Kconfig > > > @@ -158,3 +158,10 @@ config UPDATE_STATE_BOOTLOADER > > > help > > > Store update information in Bootloader's environment. > > > > > > +config FWUMDATA_CONFIG_FILE > > > + string "FWU Metadata Configuration file" > > > + depends on HAVE_LIBFWUMDATA > > > + default "/etc/fwumdata.config" > > > + help > > > + It tells where the FWU metadata are saved. > > > + > > > diff --git a/configs/all_handlers_defconfig b/configs/ > > all_handlers_defconfig > > > index 16cd9b6b98f1..63299bd223ae 100644 > > > --- a/configs/all_handlers_defconfig > > > +++ b/configs/all_handlers_defconfig > > > @@ -20,6 +20,7 @@ CONFIG_DISKPART=y > > > CONFIG_DISKPART_FORMAT=y > > > CONFIG_DISKFORMAT_HANDLER=y > > > CONFIG_FAT_FILESYSTEM=y > > > +CONFIG_FWUMDATA_HANDLER=y > > > CONFIG_EXT_FILESYSTEM=y > > > CONFIG_LUASCRIPTHANDLER=y > > > CONFIG_RAW=y > > > diff --git a/doc/source/handlers.rst b/doc/source/handlers.rst > > > index 6742c10a58c3..cbfb146f099c 100644 > > > --- a/doc/source/handlers.rst > > > +++ b/doc/source/handlers.rst > > > @@ -1710,3 +1710,40 @@ Examples: > > > name = "helloworld"; > > > }; > > > }); > > > + > > > +FWU Metadata Handler > > > +-------------------- > > > + > > > +This is a script handler used to manage the boot selection > > process according to > > > +the Firmware Update (FWU) metadata specification. > > > + > > > +The handler implements a post-install script that updates the > > metadata to switch > > > +the active bank and marks it as valid, ensuring the system boots > > from the new > > > +bank at the next reset. The ``active`` property defines which > > bank must be > > > +selected. > > > + > > > +Example selecting boot bank 1 (bank A in A/B schema): > > > + > > > +:: > > > + > > > + scripts: ( > > > + { > > > + type = "fwumdata"; > > > + properties: { > > > + active = "1"; > > > + } > > > + } > > > + ); > > > + > > > +Example selecting boot bank 2 (bank B in A/B schema): > > > + > > > +:: > > > + > > > + scripts: ( > > > + { > > > + type = "fwumdata"; > > > + properties: { > > > + active = "2"; > > > + } > > > + } > > > + ); > > > diff --git a/handlers/Kconfig b/handlers/Kconfig > > > index 152bc08074a1..b7d9e51a20c9 100644 > > > --- a/handlers/Kconfig > > > +++ b/handlers/Kconfig > > > @@ -151,6 +151,23 @@ config EMMC_HANDLER > > > with a dual-copy concept. This guarantees that the upgrade > > > is power-cut safe. > > > > > > +config FWUMDATA_HANDLER > > > + bool "FWU metadata update" > > > + depends on HAVE_LIBFWUMDATA > > > + default n > > > + help > > > + This handler allows to manage the boot selection process > > using > > > + firmware update (FWU) metadata via libfwumdata. > > > + > > > + Selecting the new boot bank automatically triggers the > > handler to > > > + set the current bank for rollback and mark the selected > > boot-up > > > + bank as 'valid'. > > > + > > > + This ensures the system is ready to boot from the updated > > > + partition while maintaining a safe path to revert to the > > previous > > > + working state if the new firmware fails to reach the > > 'accepted' > > > + state > > > + > > > config RAW > > > bool "raw" > > > default n > > > diff --git a/handlers/Makefile b/handlers/Makefile > > > index 8490172a10a3..45fcb525e461 100644 > > > --- a/handlers/Makefile > > > +++ b/handlers/Makefile > > > @@ -30,3 +30,4 @@ obj-$(CONFIG_SWUFORWARDER_HANDLER) += > > swuforward_handler.o swuforward-ws.o > > > obj-$(CONFIG_UBIVOL) += ubivol_handler.o > > > obj-$(CONFIG_UCFWHANDLER) += ucfw_handler.o > > > obj-$(CONFIG_DOCKER) += docker_handler.o > > > +obj-$(CONFIG_FWUMDATA_HANDLER) += fwumdata_handler.o > > > diff --git a/handlers/fwumdata_handler.c b/handlers/ > > fwumdata_handler.c > > > new file mode 100644 > > > index 000000000000..1331fe64aa74 > > > --- /dev/null > > > +++ b/handlers/fwumdata_handler.c > > > @@ -0,0 +1,125 @@ > > > +#include <stdio.h> > > > +#include <unistd.h> > > > +#include <fcntl.h> > > > +#include <stdlib.h> > > > +#include <stdbool.h> > > > +#include <errno.h> > > > +#include <linux/version.h> > > > +#include <sys/ioctl.h> > > > +#include <stddef.h> > > > + > > > +#include "swupdate_image.h" > > > +#include "handler.h" > > > +#include "util.h" > > > + > > > +#include <libfwumdata.h> > > > + > > > +static int _fwumdata_set(uint32_t active_index, uint32_t > > previous_index, > > > + uint8_t bank_state) > > > +{ > > > + int mdd; > > > + int ret; > > > + > > > + mdd = fwumdata_init(); > > > + if (mdd < 0) { > > > + ERROR("Cannot initialize libfwumdata\n"); > > > + return mdd; > > > + } > > > + > > > + ret = fwumdata_read_config(mdd, > CONFIG_FWUMDATA_CONFIG_FILE); > > > + if (ret) { > > > + ERROR("Cannot read %s\n", > CONFIG_FWUMDATA_CONFIG_FILE); > > > + goto exit; > > > + } > > > + > > > + ret = fwumdata_open(mdd, 0); > > > + if (ret) { > > > + ERROR("Cannot open %s\n", > CONFIG_FWUMDATA_CONFIG_FILE); > > > + goto exit; > > > + } > > > + > > > + ret = fwumdata_set_active_index(mdd, active_index); > > > + if (ret) { > > > + ERROR("Cannot set active index\n"); > > > + goto close; > > > + } > > > + > > > + fwumdata_set_previous_index(mdd, previous_index); > > > + if (ret) { > > > + ERROR("Cannot set previous index\n"); > > > + goto close; > > > + } > > > + > > > + ret = fwumdata_set_bank_state(mdd, active_index, > bank_state); > > > + if (ret) { > > > + ERROR("Cannot set bank state\n"); > > > + goto close; > > > + } > > > + > > > + ret = fwumdata_store(mdd); > > > + if (ret) { > > > + ERROR("Cannot store fwu metadata\n"); > > > + goto close; > > > + } > > > + > > > + DEBUG("fwumdata: active: %d, previous: %d, state: 0x%x", > > > + active_index, previous_index, bank_state); > > > + > > > +close: > > > + fwumdata_close(mdd); > > > +exit: > > > + fwumdata_exit(mdd); > > > + return ret; > > > +} > > > + > > > +static int fwumdata_set(struct img_type *img, void *data) > > > +{ > > > + struct script_handler_data *script_data; > > > + char *value; > > > + int active_index = -1; > > > + int previous_index; > > > + > > > + > > > + if (!data) > > > + return -EINVAL; > > > + > > > + script_data = data; > > > + > > > + /* > > > + * Call only in case of postinstall > > > + */ > > > + if (script_data->scriptfn != POSTINSTALL) > > > + return 0; > > > + > > > + value = dict_get_value(&img->properties, "active"); > > > + if (!value) { > > > + ERROR("active: cannot find in sw-description"); > > > + return -EINVAL; > > > + } > > > + > > > + active_index = ustrtoull(value, NULL, 10); > > > + if (errno) { > > > + ERROR("active %s: ustrotull failed", value); > > > + return -EINVAL; > > > + } > > > + > > > + active_index--; > > > + if (active_index == 0) { > > > + previous_index = 1; > > > + } else if (active_index == 1) { > > > + previous_index = 0; > > > + } else { > > > + ERROR("active %s: invalid value", value); > > > + return -EINVAL; > > > + > > > + } > > > + > > > + return _fwumdata_set(active_index, previous_index, > > FWUMDATA_BANK_VALID); > > > +} > > > + > > > +__attribute__((constructor)) > > > +void fwumdata_handler(void) > > > +{ > > > + register_handler("fwumdata", fwumdata_set, > > > + SCRIPT_HANDLER | NO_DATA_HANDLER, NULL); > > > +} > > > > -- > > > _______________________________________________________________________ > > Nabla Software Engineering GmbH > > Hirschstr. 111A | 86156 Augsburg | Tel: +49 821 45592596 > > Geschäftsführer : Stefano Babic | HRB 40522 Augsburg > > E-Mail: sbabic@nabladev.com <mailto:sbabic@nabladev.com> > > > > > > -- > > > _______________________________________________________________________ > > Nabla Software Engineering GmbH > > Hirschstr. 111A | 86156 Augsburg | Tel: +49 821 45592596 > > Geschäftsführer : Stefano Babic | HRB 40522 Augsburg > > E-Mail: sbabic@nabladev.com <mailto:sbabic@nabladev.com> > > > > > > > > -- > > *Dario Binacchi* > > Senior Embedded Software Engineer > > M. +39 328 0625246 > > dario.binacchi@amarulasolutions.com > > <mailto:dario.binacchi@amarulasolutions.com> > > ――――――――――――――― > > Amarula Solutions SRL > > Via Felice Cavallotti 25D, 41012 Carpi, MO, IT > > info@amarulasolutions.com <mailto:info@amarulasolutions.com> > > www.amarulasolutions.com <http://www.amarulasolutions.com/> > > > -- > _______________________________________________________________________ > Nabla Software Engineering GmbH > Hirschstr. 111A | 86156 Augsburg | Tel: +49 821 45592596 > Geschäftsführer : Stefano Babic | HRB 40522 Augsburg > E-Mail: sbabic@nabladev.com >
Hi Dario, On 4/30/26 16:15, Dario Binacchi wrote: > Hi Stefano, > > On Thu, Apr 30, 2026 at 3:24 PM Stefano Babic > <stefano.babic@swupdate.org <mailto:stefano.babic@swupdate.org>> wrote: > > Hi Dario, > > On 4/30/26 14:52, Dario Binacchi wrote: > > Hi Stefano, > > > > On Wed, Apr 29, 2026 at 5:12 PM Stefano Babic > > <stefano.babic@swupdate.org <mailto:stefano.babic@swupdate.org> > <mailto:stefano.babic@swupdate.org > <mailto:stefano.babic@swupdate.org>>> wrote: > > > > Hi Dario, > > > > On 4/29/26 16:01, Dario Binacchi wrote: > > > Add a handler to manage the boot selection process > according to > > > the Firmware Update (FWU) metadata specification using the > > > libfwumdata library. > > > > This seems that the specification is something generic, but > this is > > really just for STM32MP2, as described in the cover. Then an > according > > documentation should be added. > > > > > > AFAIK the FWU (Firmware Update) metadata is a fully generic > specification > > (part of the Arm FWU specification). While the STM32MP2 is my use > case > > and the > > reason I wrote this patch, the standard and this implementation > are not > > ST-specific. Other platforms already implement and use FWU > metadata in > > U-Boot, > > so the handler is meant to be completely platform-agnostic. > > > > > > Nevertheless, I will raise a basic issue about the concept. I > cannot > > find the patches sent to openembedded-core, too. > > > > > > You can find the patch submitted to oe-core here: > > https://patchwork.yoctoproject.org/project/oe-core/ <https:// > patchwork.yoctoproject.org/project/oe-core/> > > patch/20260429145136.618168-1- > dario.binacchi@amarulasolutions.com/ > <http://20260429145136.618168-1-dario.binacchi@amarulasolutions.com/> > > <https://patchwork.yoctoproject.org/project/oe-core/ <https:// > patchwork.yoctoproject.org/project/oe-core/> > > patch/20260429145136.618168-1- > dario.binacchi@amarulasolutions.com/ > <http://20260429145136.618168-1-dario.binacchi@amarulasolutions.com/>> > > Thanks ! > > > > > > > According to the related patches merged into U-Boot, this is a ST > > replacement for fw_setenv / fw_printenv. The configuration > file, at > > least the one pushed to U-Boot, has the same old format as U- > Boot's > > tools. So I am just asking why we should have a separate tool > (yes, I > > saw in U-Boot, too) instead of integrating into the current > ecosystem. > > > > From a concept view, the tool is used to select which is > the active > > image to be booted, and select also some parms (flags) for it. In > > SWUpdate, this is the "bootloader" interface, and not a "script" > > handler. That can be implemented also as script, as here, is > clear, but > > from the logical point of view, it does not belong to. > > > > > > Implementing it as a "script" handler was simply the easiest and > fastest > > path for me to validate the concept, and I should have probably > tagged > > the patch as an RFC for this reason. I agree that, from a > logical point of > > view, this belongs in the "bootloader" interface. > > > > Ok > > > > > And the second main aspect: if this is just to choose the active > > software set, and the fwumdata.c is poushed as replacement > for FWU > > metadata of fw_setenv, and also taken into account that its > code seems > > to me pretty simple, whhy shouldn't be integrated as storage into > > libubootenv, instead ? > > > > > > I believe it should remain a separate library (libfwumdata) for a > couple > > of reasons: > > > > Conceptual separation: U-Boot itself keeps the standard > environment and > > FWU metadata separated. They serve different purposes and have > > entirely different structures (a flexible key-value store vs. a > rigidly > > defined A/B state structure). Merging FWU metadata handling into > > libubootenv could lead to conceptual misunderstandings. > > But libubootenv maintains the name, but it is already not only thought > for U-Boot. Currently, it is used to store persistently tuple > > > FWU metadata is fundamentally not a collection of arbitrary tuples > (key-value pairs). It is a rigidly > defined binary structure. But this just means that the accepted vars or better state is limited and match into a well defined storage. > I think that forcing the FWU metadata to be > accessed and managed through a > generic tuple-based interface is an architectural stretch. I do not want this, too. But taking into account that API and at the end the goal is the same, this can be done by generalizing the libubootenv structure and use callbacks to write into the storage. At the end, we have the same in U-Boot for the Update, the bank / partition (or better, the chosen software set) is selected. And from the API... U-Boot ==> fw_setenv swset 1 fwumdata ==> yafwumdata -a 1 IMHO we have a duplication of goals and libraries. Reading the comments on the patches on OE-CORE, it looks like I am not the only one with this feeling. Sorry that you do not see the same. > It would > artificially limit the correct management > of the data and any future implementation of the FWU specification > features just to fit into a key-value paradigm. I do not want to constrain this but I think we do not need such kind off constrain. > > that must > survive an update. Namespaces allow to set vars into different domains > than U-Boot (bootloader vars vs application vars is the most typical > use > case). A FWU will be just a different namespace, but interface remains > coherent. > > > > > Dedicated API: I think it's correct to have a dedicated, minimal > C library > > specifically designed to allow any userspace application - not just > > SWUpdate, > > but also other OTA managers or proprietary system services - to > easily > switch > > Well, this was one reason for the libubootenv, and it is used by other > OTA updater, too. It is not bound to SWUpdate, SWUpdate is just an user > of the library. > > So checking inside your libfwumdata, and seeing the analogies with > libubootenv, and you have already stated in the header that there are > parts taken from libubootenv, I am even less convinced that adding > another additional library is the best way to go. > > > The similarities you noticed with |libubootenv| are absolutely > intentional, > but they are strictly limited to the API design pattern (the |init|, | > open|, |store|, |close| flow) > and the configuration file parsing. I adopted this pattern because it is > a familiar and > robust approach for the ecosystem, not because the underlying data > models are compatible. But as I said, the library can be configured so that a different underlying data is possible. > Furthermore, there are specific FWU API functions that simply cannot be > implemented as > standard |get|/|set| functions due to this completely different data > structure. A clear proof of > this structural divergence is the implementation of the |yafwumdata| > tool itself, which mimics > the U-Boot tool but is specifically tailored to handle the unique > logic of the FWU standard. I do not see in the code any blocking point to decide for a different solution. > > Since you know SWUpdate's architecture inside out, I want to leave the > ball in your court. > Is there really no other way to implement this cleanly without > shoehorning a fixed binary > structure into a string dictionary like libubootenv? > > Is it possible to find a design compromise that respects the nature of > the FWU standard > and doesn't leave either of us completely dissatisfied? > It is not to find a compromise, it is to find which should be the best and maintainable solution without introducing duplication and fragmentation. So again, I am not convinced at all this is the way to go. Best regards, Stefano > Thanks and regards, > Dario > > If I can agree about > the separation from U-B0oot environment (and this is already provided > via name3space), why is this not simply done by adding to libubootenv ? > It can be still used by any OTA, it is still separated by U-Boot's env > (ok, not the name..), configuration is already in a more modern and > flexible way as in old U-Boot and in libfwumdata, that takes over from > U-Boot (YAML). > > The most practical way seems to extend the current library instead of > creating a new one. > > > boot banks. It differs from U-Boot's mkfwumdata (which generates the > > metadata > > image from scratch at build time) and fwumdata (the CLI tool for > > targeted updates). > > libfwumdata provides a strictly limited, safe C API to update > just the 3 > > fields needed for a bank switch. > > > > So, can we meet halfway? We could integrate the management of FWU > variables > > inside bootloader/uboot.c. > > Not at all. It is a bad solution for you, too. We agree that is > separated by U-Boot, then this mixes all up. > > > If a variable has the fwu- prefix (e.g., fwu- > > active), > > it will be saved using libfwumdata; otherwise, it will be handled by > > libubootenv as usual. > > This is just a hack - I fully disagree here. > > And be sure, there will be some user early or later who starts to set > U-Boot variables starting with "fwu" ("Fair World Unit", maybe ?) > and he > will complain it does not work. > > > > > Keeping libfwumdata separate avoids forcing FWU metadata > management inside > > the libubootenv library. This approach gives users a seamless > bootenv: > > interface > > while keeping the underlying architectures clean. > > I do not see the advantage here - on the opposite, if it is integrated, > user has the same interface. > > > > > Would this compromise be acceptable to you for v2? > > > > Sorry, not. > > Best regards, > Stefano > > > Thanks and regards, > > Dario > > > > Then SWUpdate hasn't another interface, there is > > still the bootloader interface, and under the hood the FMU is > written > > instead of U-Boot env. > > > > Best regards, > > Stefano > > > > > > > > The handler is a script handler that updates the active_index > > > and marks the selected bank as valid during the post- > install phase. > > > > > > Example in sw-description: > > > > > > scripts: ( > > > { > > > type = "fwumdata"; > > > properties: { > > > active = "1"; > > > } > > > } > > > ); > > > > > > Signed-off-by: Dario Binacchi > > <dario.binacchi@amarulasolutions.com > <mailto:dario.binacchi@amarulasolutions.com> > > <mailto:dario.binacchi@amarulasolutions.com > <mailto:dario.binacchi@amarulasolutions.com>>> > > > --- > > > Kconfig | 4 ++ > > > Makefile.deps | 4 ++ > > > Makefile.flags | 3 + > > > bootloader/Kconfig | 7 ++ > > > configs/all_handlers_defconfig | 1 + > > > doc/source/handlers.rst | 37 ++++++++++ > > > handlers/Kconfig | 17 +++++ > > > handlers/Makefile | 1 + > > > handlers/fwumdata_handler.c | 125 +++++++++++++++++++ > +++++++ > > +++++++ > > > 9 files changed, 199 insertions(+) > > > create mode 100644 handlers/fwumdata_handler.c > > > > > > diff --git a/Kconfig b/Kconfig > > > index 2cf68eb890b0..fcb60f900b3f 100644 > > > --- a/Kconfig > > > +++ b/Kconfig > > > @@ -129,6 +129,10 @@ config HAVE_ZCK > > > bool > > > option env="HAVE_ZCK" > > > > > > +config HAVE_LIBFWUMDATA > > > + bool > > > + option env="HAVE_LIBFWUMDATA" > > > + > > > menu "SWUpdate Settings" > > > > > > menu "General Configuration" > > > diff --git a/Makefile.deps b/Makefile.deps > > > index c759f6876dea..313d5af6230c 100644 > > > --- a/Makefile.deps > > > +++ b/Makefile.deps > > > @@ -121,3 +121,7 @@ endif > > > ifeq ($(HAVE_ZCK),) > > > export HAVE_ZCK = y > > > endif > > > + > > > +ifeq ($(HAVE_LIBFWUMDATA),) > > > +export HAVE_LIBFWUMDATA = y > > > +endif > > > diff --git a/Makefile.flags b/Makefile.flags > > > index 40dd3b66856e..76b87e67fe67 100644 > > > --- a/Makefile.flags > > > +++ b/Makefile.flags > > > @@ -233,6 +233,9 @@ ifeq ($(CONFIG_UCFWHANDLER),y) > > > LDLIBS += gpiod > > > endif > > > > > > +ifeq ($(CONFIG_FWUMDATA_HANDLER),y) > > > +LDLIBS += fwumdata > > > +endif > > > > > > ifeq ($(CONFIG_BOOTLOADER_STATIC_LINKED),y) > > > ifeq ($(CONFIG_BOOTLOADER_EBG),y) > > > diff --git a/bootloader/Kconfig b/bootloader/Kconfig > > > index edc02d99b2d1..36f856507356 100644 > > > --- a/bootloader/Kconfig > > > +++ b/bootloader/Kconfig > > > @@ -158,3 +158,10 @@ config UPDATE_STATE_BOOTLOADER > > > help > > > Store update information in Bootloader's environment. > > > > > > +config FWUMDATA_CONFIG_FILE > > > + string "FWU Metadata Configuration file" > > > + depends on HAVE_LIBFWUMDATA > > > + default "/etc/fwumdata.config" > > > + help > > > + It tells where the FWU metadata are saved. > > > + > > > diff --git a/configs/all_handlers_defconfig b/configs/ > > all_handlers_defconfig > > > index 16cd9b6b98f1..63299bd223ae 100644 > > > --- a/configs/all_handlers_defconfig > > > +++ b/configs/all_handlers_defconfig > > > @@ -20,6 +20,7 @@ CONFIG_DISKPART=y > > > CONFIG_DISKPART_FORMAT=y > > > CONFIG_DISKFORMAT_HANDLER=y > > > CONFIG_FAT_FILESYSTEM=y > > > +CONFIG_FWUMDATA_HANDLER=y > > > CONFIG_EXT_FILESYSTEM=y > > > CONFIG_LUASCRIPTHANDLER=y > > > CONFIG_RAW=y > > > diff --git a/doc/source/handlers.rst b/doc/source/handlers.rst > > > index 6742c10a58c3..cbfb146f099c 100644 > > > --- a/doc/source/handlers.rst > > > +++ b/doc/source/handlers.rst > > > @@ -1710,3 +1710,40 @@ Examples: > > > name = "helloworld"; > > > }; > > > }); > > > + > > > +FWU Metadata Handler > > > +-------------------- > > > + > > > +This is a script handler used to manage the boot selection > > process according to > > > +the Firmware Update (FWU) metadata specification. > > > + > > > +The handler implements a post-install script that updates the > > metadata to switch > > > +the active bank and marks it as valid, ensuring the > system boots > > from the new > > > +bank at the next reset. The ``active`` property defines which > > bank must be > > > +selected. > > > + > > > +Example selecting boot bank 1 (bank A in A/B schema): > > > + > > > +:: > > > + > > > + scripts: ( > > > + { > > > + type = "fwumdata"; > > > + properties: { > > > + active = "1"; > > > + } > > > + } > > > + ); > > > + > > > +Example selecting boot bank 2 (bank B in A/B schema): > > > + > > > +:: > > > + > > > + scripts: ( > > > + { > > > + type = "fwumdata"; > > > + properties: { > > > + active = "2"; > > > + } > > > + } > > > + ); > > > diff --git a/handlers/Kconfig b/handlers/Kconfig > > > index 152bc08074a1..b7d9e51a20c9 100644 > > > --- a/handlers/Kconfig > > > +++ b/handlers/Kconfig > > > @@ -151,6 +151,23 @@ config EMMC_HANDLER > > > with a dual-copy concept. This guarantees that the > upgrade > > > is power-cut safe. > > > > > > +config FWUMDATA_HANDLER > > > + bool "FWU metadata update" > > > + depends on HAVE_LIBFWUMDATA > > > + default n > > > + help > > > + This handler allows to manage the boot selection > process > > using > > > + firmware update (FWU) metadata via libfwumdata. > > > + > > > + Selecting the new boot bank automatically triggers the > > handler to > > > + set the current bank for rollback and mark the > selected > > boot-up > > > + bank as 'valid'. > > > + > > > + This ensures the system is ready to boot from the > updated > > > + partition while maintaining a safe path to revert > to the > > previous > > > + working state if the new firmware fails to reach the > > 'accepted' > > > + state > > > + > > > config RAW > > > bool "raw" > > > default n > > > diff --git a/handlers/Makefile b/handlers/Makefile > > > index 8490172a10a3..45fcb525e461 100644 > > > --- a/handlers/Makefile > > > +++ b/handlers/Makefile > > > @@ -30,3 +30,4 @@ obj-$(CONFIG_SWUFORWARDER_HANDLER) += > > swuforward_handler.o swuforward-ws.o > > > obj-$(CONFIG_UBIVOL) += ubivol_handler.o > > > obj-$(CONFIG_UCFWHANDLER) += ucfw_handler.o > > > obj-$(CONFIG_DOCKER) += docker_handler.o > > > +obj-$(CONFIG_FWUMDATA_HANDLER) += fwumdata_handler.o > > > diff --git a/handlers/fwumdata_handler.c b/handlers/ > > fwumdata_handler.c > > > new file mode 100644 > > > index 000000000000..1331fe64aa74 > > > --- /dev/null > > > +++ b/handlers/fwumdata_handler.c > > > @@ -0,0 +1,125 @@ > > > +#include <stdio.h> > > > +#include <unistd.h> > > > +#include <fcntl.h> > > > +#include <stdlib.h> > > > +#include <stdbool.h> > > > +#include <errno.h> > > > +#include <linux/version.h> > > > +#include <sys/ioctl.h> > > > +#include <stddef.h> > > > + > > > +#include "swupdate_image.h" > > > +#include "handler.h" > > > +#include "util.h" > > > + > > > +#include <libfwumdata.h> > > > + > > > +static int _fwumdata_set(uint32_t active_index, uint32_t > > previous_index, > > > + uint8_t bank_state) > > > +{ > > > + int mdd; > > > + int ret; > > > + > > > + mdd = fwumdata_init(); > > > + if (mdd < 0) { > > > + ERROR("Cannot initialize libfwumdata\n"); > > > + return mdd; > > > + } > > > + > > > + ret = fwumdata_read_config(mdd, > CONFIG_FWUMDATA_CONFIG_FILE); > > > + if (ret) { > > > + ERROR("Cannot read %s\n", > CONFIG_FWUMDATA_CONFIG_FILE); > > > + goto exit; > > > + } > > > + > > > + ret = fwumdata_open(mdd, 0); > > > + if (ret) { > > > + ERROR("Cannot open %s\n", > CONFIG_FWUMDATA_CONFIG_FILE); > > > + goto exit; > > > + } > > > + > > > + ret = fwumdata_set_active_index(mdd, active_index); > > > + if (ret) { > > > + ERROR("Cannot set active index\n"); > > > + goto close; > > > + } > > > + > > > + fwumdata_set_previous_index(mdd, previous_index); > > > + if (ret) { > > > + ERROR("Cannot set previous index\n"); > > > + goto close; > > > + } > > > + > > > + ret = fwumdata_set_bank_state(mdd, active_index, > bank_state); > > > + if (ret) { > > > + ERROR("Cannot set bank state\n"); > > > + goto close; > > > + } > > > + > > > + ret = fwumdata_store(mdd); > > > + if (ret) { > > > + ERROR("Cannot store fwu metadata\n"); > > > + goto close; > > > + } > > > + > > > + DEBUG("fwumdata: active: %d, previous: %d, state: 0x%x", > > > + active_index, previous_index, bank_state); > > > + > > > +close: > > > + fwumdata_close(mdd); > > > +exit: > > > + fwumdata_exit(mdd); > > > + return ret; > > > +} > > > + > > > +static int fwumdata_set(struct img_type *img, void *data) > > > +{ > > > + struct script_handler_data *script_data; > > > + char *value; > > > + int active_index = -1; > > > + int previous_index; > > > + > > > + > > > + if (!data) > > > + return -EINVAL; > > > + > > > + script_data = data; > > > + > > > + /* > > > + * Call only in case of postinstall > > > + */ > > > + if (script_data->scriptfn != POSTINSTALL) > > > + return 0; > > > + > > > + value = dict_get_value(&img->properties, "active"); > > > + if (!value) { > > > + ERROR("active: cannot find in sw-description"); > > > + return -EINVAL; > > > + } > > > + > > > + active_index = ustrtoull(value, NULL, 10); > > > + if (errno) { > > > + ERROR("active %s: ustrotull failed", value); > > > + return -EINVAL; > > > + } > > > + > > > + active_index--; > > > + if (active_index == 0) { > > > + previous_index = 1; > > > + } else if (active_index == 1) { > > > + previous_index = 0; > > > + } else { > > > + ERROR("active %s: invalid value", value); > > > + return -EINVAL; > > > + > > > + } > > > + > > > + return _fwumdata_set(active_index, previous_index, > > FWUMDATA_BANK_VALID); > > > +} > > > + > > > +__attribute__((constructor)) > > > +void fwumdata_handler(void) > > > +{ > > > + register_handler("fwumdata", fwumdata_set, > > > + SCRIPT_HANDLER | NO_DATA_HANDLER, > NULL); > > > +} > > > > -- > > > _______________________________________________________________________ > > Nabla Software Engineering GmbH > > Hirschstr. 111A | 86156 Augsburg | Tel: +49 821 45592596 > > Geschäftsführer : Stefano Babic | HRB 40522 Augsburg > > E-Mail: sbabic@nabladev.com <mailto:sbabic@nabladev.com> > <mailto:sbabic@nabladev.com <mailto:sbabic@nabladev.com>> > > > > > > -- > > > _______________________________________________________________________ > > Nabla Software Engineering GmbH > > Hirschstr. 111A | 86156 Augsburg | Tel: +49 821 45592596 > > Geschäftsführer : Stefano Babic | HRB 40522 Augsburg > > E-Mail: sbabic@nabladev.com <mailto:sbabic@nabladev.com> > <mailto:sbabic@nabladev.com <mailto:sbabic@nabladev.com>> > > > > > > > > -- > > *Dario Binacchi* > > Senior Embedded Software Engineer > > M. +39 328 0625246 > > dario.binacchi@amarulasolutions.com > <mailto:dario.binacchi@amarulasolutions.com> > > <mailto:dario.binacchi@amarulasolutions.com > <mailto:dario.binacchi@amarulasolutions.com>> > > ――――――――――――――― > > Amarula Solutions SRL > > Via Felice Cavallotti 25D, 41012 Carpi, MO, IT > > info@amarulasolutions.com <mailto:info@amarulasolutions.com> > <mailto:info@amarulasolutions.com <mailto:info@amarulasolutions.com>> > > www.amarulasolutions.com <http://www.amarulasolutions.com> > <http://www.amarulasolutions.com/ <http://www.amarulasolutions.com/>> > > > -- > _______________________________________________________________________ > Nabla Software Engineering GmbH > Hirschstr. 111A | 86156 Augsburg | Tel: +49 821 45592596 > Geschäftsführer : Stefano Babic | HRB 40522 Augsburg > E-Mail: sbabic@nabladev.com <mailto:sbabic@nabladev.com> > > > > -- > *Dario Binacchi* > Senior Embedded Software Engineer > M. +39 328 0625246 > dario.binacchi@amarulasolutions.com > <mailto:dario.binacchi@amarulasolutions.com> > ――――――――――――――― > Amarula Solutions SRL > Via Felice Cavallotti 25D, 41012 Carpi, MO, IT > info@amarulasolutions.com <mailto:info@amarulasolutions.com> > www.amarulasolutions.com <http://www.amarulasolutions.com/> > > -- > You received this message because you are subscribed to the Google > Groups "swupdate" group. > To unsubscribe from this group and stop receiving emails from it, send > an email to swupdate+unsubscribe@googlegroups.com > <mailto:swupdate+unsubscribe@googlegroups.com>. > To view this discussion visit https://groups.google.com/d/msgid/ > swupdate/ > CABGWkvrFwZCjJx%3D70tNh%3DZm__eXq22kaaNGxvZ8sESZ6eBPj_w%40mail.gmail.com > <https://groups.google.com/d/msgid/swupdate/ > CABGWkvrFwZCjJx%3D70tNh%3DZm__eXq22kaaNGxvZ8sESZ6eBPj_w%40mail.gmail.com?utm_medium=email&utm_source=footer>. To unsubscribe from this group and stop receiving emails from it, send an email to linux-amarula+unsubscribe@amarulasolutions.com.
diff --git a/Kconfig b/Kconfig index 2cf68eb890b0..fcb60f900b3f 100644 --- a/Kconfig +++ b/Kconfig @@ -129,6 +129,10 @@ config HAVE_ZCK bool option env="HAVE_ZCK" +config HAVE_LIBFWUMDATA + bool + option env="HAVE_LIBFWUMDATA" + menu "SWUpdate Settings" menu "General Configuration" diff --git a/Makefile.deps b/Makefile.deps index c759f6876dea..313d5af6230c 100644 --- a/Makefile.deps +++ b/Makefile.deps @@ -121,3 +121,7 @@ endif ifeq ($(HAVE_ZCK),) export HAVE_ZCK = y endif + +ifeq ($(HAVE_LIBFWUMDATA),) +export HAVE_LIBFWUMDATA = y +endif diff --git a/Makefile.flags b/Makefile.flags index 40dd3b66856e..76b87e67fe67 100644 --- a/Makefile.flags +++ b/Makefile.flags @@ -233,6 +233,9 @@ ifeq ($(CONFIG_UCFWHANDLER),y) LDLIBS += gpiod endif +ifeq ($(CONFIG_FWUMDATA_HANDLER),y) +LDLIBS += fwumdata +endif ifeq ($(CONFIG_BOOTLOADER_STATIC_LINKED),y) ifeq ($(CONFIG_BOOTLOADER_EBG),y) diff --git a/bootloader/Kconfig b/bootloader/Kconfig index edc02d99b2d1..36f856507356 100644 --- a/bootloader/Kconfig +++ b/bootloader/Kconfig @@ -158,3 +158,10 @@ config UPDATE_STATE_BOOTLOADER help Store update information in Bootloader's environment. +config FWUMDATA_CONFIG_FILE + string "FWU Metadata Configuration file" + depends on HAVE_LIBFWUMDATA + default "/etc/fwumdata.config" + help + It tells where the FWU metadata are saved. + diff --git a/configs/all_handlers_defconfig b/configs/all_handlers_defconfig index 16cd9b6b98f1..63299bd223ae 100644 --- a/configs/all_handlers_defconfig +++ b/configs/all_handlers_defconfig @@ -20,6 +20,7 @@ CONFIG_DISKPART=y CONFIG_DISKPART_FORMAT=y CONFIG_DISKFORMAT_HANDLER=y CONFIG_FAT_FILESYSTEM=y +CONFIG_FWUMDATA_HANDLER=y CONFIG_EXT_FILESYSTEM=y CONFIG_LUASCRIPTHANDLER=y CONFIG_RAW=y diff --git a/doc/source/handlers.rst b/doc/source/handlers.rst index 6742c10a58c3..cbfb146f099c 100644 --- a/doc/source/handlers.rst +++ b/doc/source/handlers.rst @@ -1710,3 +1710,40 @@ Examples: name = "helloworld"; }; }); + +FWU Metadata Handler +-------------------- + +This is a script handler used to manage the boot selection process according to +the Firmware Update (FWU) metadata specification. + +The handler implements a post-install script that updates the metadata to switch +the active bank and marks it as valid, ensuring the system boots from the new +bank at the next reset. The ``active`` property defines which bank must be +selected. + +Example selecting boot bank 1 (bank A in A/B schema): + +:: + + scripts: ( + { + type = "fwumdata"; + properties: { + active = "1"; + } + } + ); + +Example selecting boot bank 2 (bank B in A/B schema): + +:: + + scripts: ( + { + type = "fwumdata"; + properties: { + active = "2"; + } + } + ); diff --git a/handlers/Kconfig b/handlers/Kconfig index 152bc08074a1..b7d9e51a20c9 100644 --- a/handlers/Kconfig +++ b/handlers/Kconfig @@ -151,6 +151,23 @@ config EMMC_HANDLER with a dual-copy concept. This guarantees that the upgrade is power-cut safe. +config FWUMDATA_HANDLER + bool "FWU metadata update" + depends on HAVE_LIBFWUMDATA + default n + help + This handler allows to manage the boot selection process using + firmware update (FWU) metadata via libfwumdata. + + Selecting the new boot bank automatically triggers the handler to + set the current bank for rollback and mark the selected boot-up + bank as 'valid'. + + This ensures the system is ready to boot from the updated + partition while maintaining a safe path to revert to the previous + working state if the new firmware fails to reach the 'accepted' + state + config RAW bool "raw" default n diff --git a/handlers/Makefile b/handlers/Makefile index 8490172a10a3..45fcb525e461 100644 --- a/handlers/Makefile +++ b/handlers/Makefile @@ -30,3 +30,4 @@ obj-$(CONFIG_SWUFORWARDER_HANDLER) += swuforward_handler.o swuforward-ws.o obj-$(CONFIG_UBIVOL) += ubivol_handler.o obj-$(CONFIG_UCFWHANDLER) += ucfw_handler.o obj-$(CONFIG_DOCKER) += docker_handler.o +obj-$(CONFIG_FWUMDATA_HANDLER) += fwumdata_handler.o diff --git a/handlers/fwumdata_handler.c b/handlers/fwumdata_handler.c new file mode 100644 index 000000000000..1331fe64aa74 --- /dev/null +++ b/handlers/fwumdata_handler.c @@ -0,0 +1,125 @@ +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdlib.h> +#include <stdbool.h> +#include <errno.h> +#include <linux/version.h> +#include <sys/ioctl.h> +#include <stddef.h> + +#include "swupdate_image.h" +#include "handler.h" +#include "util.h" + +#include <libfwumdata.h> + +static int _fwumdata_set(uint32_t active_index, uint32_t previous_index, + uint8_t bank_state) +{ + int mdd; + int ret; + + mdd = fwumdata_init(); + if (mdd < 0) { + ERROR("Cannot initialize libfwumdata\n"); + return mdd; + } + + ret = fwumdata_read_config(mdd, CONFIG_FWUMDATA_CONFIG_FILE); + if (ret) { + ERROR("Cannot read %s\n", CONFIG_FWUMDATA_CONFIG_FILE); + goto exit; + } + + ret = fwumdata_open(mdd, 0); + if (ret) { + ERROR("Cannot open %s\n", CONFIG_FWUMDATA_CONFIG_FILE); + goto exit; + } + + ret = fwumdata_set_active_index(mdd, active_index); + if (ret) { + ERROR("Cannot set active index\n"); + goto close; + } + + fwumdata_set_previous_index(mdd, previous_index); + if (ret) { + ERROR("Cannot set previous index\n"); + goto close; + } + + ret = fwumdata_set_bank_state(mdd, active_index, bank_state); + if (ret) { + ERROR("Cannot set bank state\n"); + goto close; + } + + ret = fwumdata_store(mdd); + if (ret) { + ERROR("Cannot store fwu metadata\n"); + goto close; + } + + DEBUG("fwumdata: active: %d, previous: %d, state: 0x%x", + active_index, previous_index, bank_state); + +close: + fwumdata_close(mdd); +exit: + fwumdata_exit(mdd); + return ret; +} + +static int fwumdata_set(struct img_type *img, void *data) +{ + struct script_handler_data *script_data; + char *value; + int active_index = -1; + int previous_index; + + + if (!data) + return -EINVAL; + + script_data = data; + + /* + * Call only in case of postinstall + */ + if (script_data->scriptfn != POSTINSTALL) + return 0; + + value = dict_get_value(&img->properties, "active"); + if (!value) { + ERROR("active: cannot find in sw-description"); + return -EINVAL; + } + + active_index = ustrtoull(value, NULL, 10); + if (errno) { + ERROR("active %s: ustrotull failed", value); + return -EINVAL; + } + + active_index--; + if (active_index == 0) { + previous_index = 1; + } else if (active_index == 1) { + previous_index = 0; + } else { + ERROR("active %s: invalid value", value); + return -EINVAL; + + } + + return _fwumdata_set(active_index, previous_index, FWUMDATA_BANK_VALID); +} + +__attribute__((constructor)) +void fwumdata_handler(void) +{ + register_handler("fwumdata", fwumdata_set, + SCRIPT_HANDLER | NO_DATA_HANDLER, NULL); +}
Add a handler to manage the boot selection process according to the Firmware Update (FWU) metadata specification using the libfwumdata library. The handler is a script handler that updates the active_index and marks the selected bank as valid during the post-install phase. Example in sw-description: scripts: ( { type = "fwumdata"; properties: { active = "1"; } } ); Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com> --- Kconfig | 4 ++ Makefile.deps | 4 ++ Makefile.flags | 3 + bootloader/Kconfig | 7 ++ configs/all_handlers_defconfig | 1 + doc/source/handlers.rst | 37 ++++++++++ handlers/Kconfig | 17 +++++ handlers/Makefile | 1 + handlers/fwumdata_handler.c | 125 +++++++++++++++++++++++++++++++++ 9 files changed, 199 insertions(+) create mode 100644 handlers/fwumdata_handler.c