Hi, On 8/25/26 5:05 AM, [email protected] wrote: > From: Chali Anis <[email protected]> > > Until now, a "barebox,state" node had to be part of a board's own, > statically compiled-in devicetree source. That's a hard requirement > for external build systems (Yocto, buildroot, ...) that want to add a > state layout without carrying a board-specific dts patch.
or externally in the ESP. > Add CONFIG_STATE_OVERLAY, which compiles an externally supplied > devicetree overlay (.dtso, pointed to by CONFIG_STATE_OVERLAY_DTS) Why two options? > into the barebox binary and applies it to barebox's own live > devicetree at postcore_initcall time, mirroring how > CONFIG_EXTERNAL_DTS_FRAGMENTS already lets an external build system > inject plain dts fragments. Once applied, the resulting node is > picked up by the regular state probing like any statically defined > one. This selects CONFIG_OF_OVERLAY_LIVE, required so &label > references in the overlay (e.g. to an existing backend partition) > resolve against the base devicetree's __symbols__ node. The cover letter mentions QEMU and board-dt-2nd as benefiting from this, but OF_OVERLAY_LIVE helps neither of them as the DT comes from outside barebox. > Not every target has a live devicetree by postcore_initcall time, > though, so guard against that explicitly and skip cleanly rather than > calling into the overlay code with a NULL root. Once applied, call > of_alias_scan() so the overlay's /aliases entry becomes visible the > same way a live overlay applied via the interactive of_overlay command > already does. Also select CONFIG_OFDEVICE: registering a live > devicetree root at all, on targets with no firmware-supplied one of > their own, depends on it. OFDEVICE is not really meant to be selected by generic features, rather generic features should depend on it if they need it. Architectures / Platforms are wgi should select OFDEVICE if they want to probe OF devices. > > Assisted-by: Claude Sonnet 5 > Signed-off-by: Chali Anis <[email protected]> > --- > .../bindings/barebox/barebox,state.rst | 9 ++++ > Documentation/user/state.rst | 32 +++++++++++++++ > common/Kconfig | 41 +++++++++++++++++++ > common/state/Makefile | 20 +++++++++ > common/state/state_overlay.c | 29 +++++++++++++ > 5 files changed, 131 insertions(+) > create mode 100644 common/state/state_overlay.c > > diff --git a/Documentation/devicetree/bindings/barebox/barebox,state.rst > b/Documentation/devicetree/bindings/barebox/barebox,state.rst > index 390e148a2879..36b1d9acb038 100644 > --- a/Documentation/devicetree/bindings/barebox/barebox,state.rst > +++ b/Documentation/devicetree/bindings/barebox/barebox,state.rst > @@ -23,6 +23,15 @@ Required Properties > * additionally a *state* node must have an alias in the ``/aliases`` node > pointing > to it. > > +.. note:: A *state* node does not have to be part of the board's static > + devicetree source. It can instead be added at runtime via a devicetree > + overlay, see :ref:`CONFIG_STATE_OVERLAY <state_overlay>`. In that case, > + the node referenced by ``backend`` must still exist in the board's own > + devicetree source under a stable, well-known *label* (not merely an > + ``/aliases`` entry), because overlay phandle resolution works by > + resolving ``&label`` references against the base devicetree's > + ``__symbols__`` node, which requires ``CONFIG_OF_OVERLAY_LIVE``. As mentioned above, this is not enough. If it's an external DT, CONFIG_OF_OVERLAY_LIVE won't help. > + > .. _barebox,state_magic: > > The ``magic`` property is a unique number which identifies the *state* > variable > diff --git a/Documentation/user/state.rst b/Documentation/user/state.rst > index d97ba4e9f157..a03670dfa68e 100644 > --- a/Documentation/user/state.rst > +++ b/Documentation/user/state.rst > @@ -759,6 +759,38 @@ content, its backend-type and *state* variable layout. > }; > }; > > +.. _state_overlay: > + > +Devicetree Overlay based State Node > +------------------------------------ > + > +Normally the *state* node is part of the board's own, statically compiled-in > +devicetree source. ``CONFIG_STATE_OVERLAY`` allows a *state* node to instead > +be added at runtime, via a devicetree overlay that is compiled into the > +barebox binary and applied to barebox's own live devicetree during boot. > +Once applied, the resulting node is picked up by the regular *state* probing > +just like a statically defined one, and is fixed up into whatever devicetree > +barebox eventually boots (internal or external), without requiring any > +board-specific code. > + > +This is primarily meant for use by an external build system (Yocto, > +buildroot, ...) that wants to inject a state layout without patching the > +board's dts: set ``CONFIG_STATE_OVERLAY=y`` and point > +``CONFIG_STATE_OVERLAY_DTS`` at the ``.dtso`` overlay file's path, similar to > +how ``CONFIG_EXTERNAL_DTS_FRAGMENTS`` works for regular dts fragments. As > +with that option, it's not intended to be set in barebox's own defconfig > +files. > + > +Because the overlay is applied to barebox's *live* devicetree, its > +``backend`` phandle can only resolve references to nodes that already exist > +in the board's own devicetree source, and only if that devicetree carries a > +``__symbols__`` node - i.e. ``CONFIG_OF_OVERLAY_LIVE`` must be enabled > +(``CONFIG_STATE_OVERLAY`` selects it automatically). This means the > +referenced backend node needs a stable, well-known *label* defined in the > +board's own devicetree source, not merely an ``/aliases`` entry - the > +overlay itself then only needs to add the *state* node and its alias, > +referencing that existing label. Thanks for including docs. > + > Frontend > -------- > > diff --git a/common/Kconfig b/common/Kconfig > index 85df7f7daec6..abe7d100150c 100644 > --- a/common/Kconfig > +++ b/common/Kconfig > @@ -1351,6 +1351,47 @@ config STATE_BACKWARD_COMPATIBLE > compatibility with the state framework of barebox <= v2016.08.0. Newer > revisions expect an additional 'meta header' and fail otherwise. > > +config STATE_OVERLAY > + bool "apply an external devicetree overlay to add a state node" > + depends on STATE > + select OF_OVERLAY > + select OF_OVERLAY_LIVE > + select OFDEVICE > + help > + Compile an externally supplied devicetree overlay (.dtso) into the > + barebox binary and apply it to barebox's own live devicetree at > + boot, in order to add a "barebox,state" node (and its /aliases > + entry) that isn't part of the board's own compiled-in devicetree. > + > + This selects CONFIG_OF_OVERLAY_LIVE, required so the board's own > + built-in devicetree carries a __symbols__ node, needed to resolve > + &label references from the overlay back into the base devicetree > + (e.g. a reference to a backend partition already defined in the > + board's static dts). > + > + This also selects CONFIG_OFDEVICE: registering a live devicetree > + root at all, on targets with no firmware-supplied one of their > + own, depends on it. > + > + See CONFIG_STATE_OVERLAY_DTS to specify the overlay source file. As mentioned above, unclear to me why we need two options. > + > +config STATE_OVERLAY_DTS > + string "external state overlay .dtso file" > + depends on STATE_OVERLAY > + help > + Path to a devicetree overlay source file (.dtso) that will be > + compiled and linked into the barebox image and applied to the > + live devicetree at boot to add a "barebox,state" node. > + > + As with CONFIG_EXTERNAL_DTS_FRAGMENTS, this is not intended to be > + put into Barebox's defconfig files. It's an external build > + system's job, like Yocto or buildroot, to inject a state overlay > + file from outside the Barebox source tree. > + > + Any backend node referenced from the overlay via &label must > + already exist in the board's own devicetree source, under a > + stable, well-known label (not merely an /aliases entry). > + > config BOOTCHOOSER > bool "bootchooser infrastructure" > select BOOT > diff --git a/common/state/Makefile b/common/state/Makefile > index 93215dd06921..a906c66a0747 100644 > --- a/common/state/Makefile > +++ b/common/state/Makefile > @@ -7,3 +7,23 @@ obj-y += backend_format_raw.o > obj-y += backend_storage.o > obj-y += backend_bucket_direct.o > obj-$(CONFIG_MTD) += backend_bucket_circular.o > + > +# External state devicetree overlay > +# --------------------------------------------------------------------------- > +state-overlay-dts := $(call remove_quotes,$(CONFIG_STATE_OVERLAY_DTS)) > + > +ifdef CONFIG_STATE_OVERLAY > +ifeq ($(state-overlay-dts),) > +$(error CONFIG_STATE_OVERLAY is enabled but CONFIG_STATE_OVERLAY_DTS is > empty) > +endif > +ifeq ($(wildcard $(state-overlay-dts)),) > +$(error CONFIG_STATE_OVERLAY_DTS="$(state-overlay-dts)" does not exist) > +endif > + > +obj-y += state_overlay.o state-overlay.dtbo.o > + > +$(obj)/state-overlay.dtbo: $(state-overlay-dts) $(DTC) FORCE > + $(call if_changed_dep,dtc) > +endif > + > +clean-files += *.dtbo *.dtbo.S .*.dtso > diff --git a/common/state/state_overlay.c b/common/state/state_overlay.c > new file mode 100644 > index 000000000000..b3f68eaea4b2 > --- /dev/null > +++ b/common/state/state_overlay.c > @@ -0,0 +1,29 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +#include <common.h> > +#include <init.h> > +#include <of.h> > +#include <linux/err.h> > + > +extern char __dtbo_state_overlay_start[]; > + > +static int state_overlay_apply(void) > +{ > + struct device_node *root = of_get_root_node(); > + int ret; > + > + if (!root) { > + pr_err("no live devicetree yet, skipping state overlay\n"); > + return 0; > + } > + > + ret = of_overlay_apply_dtbo(root, __dtbo_state_overlay_start); > + if (ret) { > + pr_err("failed to apply state overlay: %pe\n", ERR_PTR(ret)); > + return ret; > + } > + > + of_alias_scan(); > + > + return 0; > +} > +postcore_initcall(state_overlay_apply); This can be used to apply arbitrary overlay content, so the option name should probably not be state specific. Cheers, Ahmad > -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
