[PATCH v4 10/10] env: ubi: add support to create environment volume if it does not exist
Weijie Gao
weijie.gao at mediatek.com
Wed May 13 10:03:02 CEST 2026
When U-Boot is booting from a fresh device, the environment volume may not
exist in the factory UBI image. This is a common case where factory UBI
image contains only volumes with valid data.
With the current design, even if the volume is created manually, the
environment will still be unusable (e.g., saveenv) before a reboot.
This patch adds support to automatically create missing volumes before
loading environment. This will make environment available at first boot.
There are two options:
CONFIG_ENV_UBI_VOLUME_CREATE: whether to enable volume creation
CONFIG_ENV_UBI_VOLUME_STATIC: create static volume (default is dynamic)
Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
---
v4: Add option to control whether to create static volume
Read environment volume only when it exists or has been created.
v3: fix error handling and default env setting
v2: updated kconfig help text
added error output when failed to create volume
---
env/Kconfig | 20 +++++++++++++++++
env/ubi.c | 65 ++++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 74 insertions(+), 11 deletions(-)
diff --git a/env/Kconfig b/env/Kconfig
index 7abd82ab6f3..9ec3e090481 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -716,6 +716,26 @@ config ENV_UBI_VOLUME_REDUND
help
Name of the redundant volume that you want to store the environment in.
+config ENV_UBI_VOLUME_CREATE
+ bool "Create UBI volume if it does not exist"
+ depends on ENV_IS_IN_UBI
+ help
+ This option is useful if U-Boot will be booted from a fresh device
+ where the environment volume has not been created.
+ This is a common case where factory UBI image contains only volumes
+ with valid data.
+ By enabling this option, any missing environment volumes will be
+ created before loading.
+ If CONFIG_ENV_UBI_VOLUME_REDUND is also enabled, both volumes will be
+ created,
+
+config ENV_UBI_VOLUME_STATIC
+ bool "Create static UBI volume"
+ depends on ENV_UBI_VOLUME_CREATE
+ help
+ By default environment volume will be dynamic.
+ Enable this option to create static volume.
+
config ENV_UBI_VID_OFFSET
int "ubi environment VID offset"
depends on ENV_IS_IN_UBI
diff --git a/env/ubi.c b/env/ubi.c
index 46970ba754f..810faaf7744 100644
--- a/env/ubi.c
+++ b/env/ubi.c
@@ -103,12 +103,30 @@ static int env_ubi_save(void)
}
#endif /* CONFIG_ENV_REDUNDANT */
+static int env_ubi_volume_create(const char *volume)
+{
+ bool dynamic = !IS_ENABLED(CONFIG_ENV_UBI_VOLUME_STATIC);
+ struct ubi_volume *vol;
+ int ret;
+
+ vol = ubi_find_volume(volume);
+ if (vol)
+ return 0;
+
+ ret = ubi_create_vol(volume, CONFIG_ENV_SIZE, dynamic, UBI_VOL_NUM_AUTO,
+ false);
+ if (ret)
+ printf("Failed to create environment volume '%s'\n", volume);
+
+ return ret;
+}
+
#ifdef CONFIG_ENV_REDUNDANT
static int env_ubi_load(void)
{
ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
- int read1_fail, read2_fail;
+ int read1_fail, read2_fail, create1_fail = 0, create2_fail = 0;
env_t *tmp_env1, *tmp_env2;
/*
@@ -132,17 +150,35 @@ static int env_ubi_load(void)
return -EIO;
}
- read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, tmp_env1, 0,
- CONFIG_ENV_SIZE);
- if (read1_fail)
- printf("\n** Unable to read env from %s:%s **\n",
- CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
+ if (IS_ENABLED(CONFIG_ENV_UBI_VOLUME_CREATE)) {
+ create1_fail = env_ubi_volume_create(CONFIG_ENV_UBI_VOLUME);
+ create2_fail = env_ubi_volume_create(CONFIG_ENV_UBI_VOLUME_REDUND);
+ if (create1_fail && create2_fail) {
+ env_set_default(NULL, 0);
+ return -ENODEV;
+ }
+ }
- read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND,
- tmp_env2, 0, CONFIG_ENV_SIZE);
- if (read2_fail)
- printf("\n** Unable to read redundant env from %s:%s **\n",
- CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
+ if (!create1_fail) {
+ read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, tmp_env1, 0,
+ CONFIG_ENV_SIZE);
+ if (read1_fail)
+ printf("\n** Unable to read env from %s:%s **\n",
+ CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
+ } else {
+ read1_fail = create1_fail;
+ }
+
+ if (!create2_fail) {
+ read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND,
+ tmp_env2, 0, CONFIG_ENV_SIZE);
+ if (read2_fail)
+ printf("\n** Unable to read redundant env from %s:%s **\n",
+ CONFIG_ENV_UBI_PART,
+ CONFIG_ENV_UBI_VOLUME_REDUND);
+ } else {
+ read2_fail = create2_fail;
+ }
return env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
read2_fail, H_EXTERNAL);
@@ -169,6 +205,13 @@ static int env_ubi_load(void)
return -EIO;
}
+ if (IS_ENABLED(CONFIG_ENV_UBI_VOLUME_CREATE)) {
+ if (env_ubi_volume_create(CONFIG_ENV_UBI_VOLUME)) {
+ env_set_default(NULL, 0);
+ return -ENODEV;
+ }
+ }
+
if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, 0, CONFIG_ENV_SIZE)) {
printf("\n** Unable to read env from %s:%s **\n",
CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
--
2.45.2
More information about the U-Boot
mailing list