[PATCH 1/2] environment: support DT-compatible-specific overlays

Ahmad Fatoum a.fatoum at barebox.org
Mon Apr 13 03:20:20 PDT 2026


Board-specific environments are registered from board code via
defaultenv_append_directory(), but this isn't possible when using
CONFIG_DEFAULT_ENVIRONMENT_PATH with an external environment.

Add support for a match.of_compatible/ directory convention within
the default environment. Subdirectories named after DT root compatible
strings are overlaid onto /env from most generic to most specific
after the default environment is loaded. The match.of_compatible/
directory is removed afterwards to keep /env clean.

Example layout in CONFIG_DEFAULT_ENVIRONMENT_PATH:

  barebox-defaultenv/
    nv/boot.default
    match.of_compatible/
      fsl,imx8mm/
        nv/boot.default
      fsl,imx8mq-evk/
        nv/boot.default

For compatible = "fsl,imx8mm-evk", "fsl,imx8mm":
  1. fsl,imx8mm/     overlay applied first  (most generic)
  2. fsl,imx8mm-evk/ overlay applied second (most specific)

Signed-off-by: Ahmad Fatoum <a.fatoum at barebox.org>
---
 common/startup.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/common/startup.c b/common/startup.c
index 2e2b5f820fe9..e630033e3505 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -46,6 +46,7 @@
 #include <pbl/handoff-data.h>
 #include <libfile.h>
 #include <fuzz.h>
+#include <of.h>
 
 extern initcall_t __barebox_initcalls_start[], __barebox_early_initcalls_end[],
 		  __barebox_initcalls_end[];
@@ -95,6 +96,50 @@ void autoload_external_env(bool endis)
 }
 #endif
 
+static void env_merge_of_compat_overlays(const char *dir)
+{
+	struct device_node *root;
+	const char *compat;
+	struct stat s;
+	char *ofdir, *src;
+	int count;
+
+	root = of_get_root_node();
+	if (!root)
+		return;
+
+	ofdir = xasprintf("%s/match.of_compatible", dir);
+
+	if (stat(ofdir, &s) || !S_ISDIR(s.st_mode))
+		goto out;
+
+	count = of_property_count_strings(root, "compatible");
+
+	/*
+	 * Apply overlays from most generic to most specific, so that
+	 * more specific entries take precedence.
+	 */
+	for (int i = count - 1; i >= 0; i--) {
+		if (of_property_read_string_index(root, "compatible",
+						  i, &compat))
+			continue;
+
+		src = xasprintf("%s/%s", ofdir, compat);
+
+		if (stat(src, &s) == 0 && S_ISDIR(s.st_mode)) {
+			pr_debug("Applying '%s'-compatible environment overlay\n",
+				 compat);
+			copy_recursive(src, dir, 0);
+		}
+
+		free(src);
+	}
+
+	unlink_recursive(ofdir, NULL);
+out:
+	free(ofdir);
+}
+
 static int load_environment(void)
 {
 	const char *default_environment_path;
@@ -115,6 +160,8 @@ static int load_environment(void)
 		pr_info("external environment support %s. Using default environment\n",
 			IS_ENABLED(CONFIG_ENV_HANDLING) ? "disallowed" : "disabled");
 
+	env_merge_of_compat_overlays("/env");
+
 	nvvar_load();
 
 	return 0;
-- 
2.47.3




More information about the barebox mailing list