[U-Boot] [PATCH 3/3] env: Add support for FS environment

Fiach Antaw fiach.antaw at uqconnect.edu.au
Wed Jan 25 09:53:13 CET 2017


This patch adds support for fat/ext4-style environments on top of
the FS api, allowing any filesystem to be used to store the u-boot
environment. This implementation also support redundancy in the
form of a secondary environment file on the same filesystem.

Signed-off-by: Fiach Antaw <fiach.antaw at uqconnect.edu.au>

---

 README                       |  22 ++++++++
 cmd/nvedit.c                 |   1 +
 common/Makefile              |   1 +
 common/env_fs.c              | 126 +++++++++++++++++++++++++++++++++++++++++++
 include/environment.h        |  16 ++++++
 scripts/config_whitelist.txt |   5 ++
 6 files changed, 171 insertions(+)
 create mode 100644 common/env_fs.c

diff --git a/README b/README
index a95348a..ac0dfc2 100644
--- a/README
+++ b/README
@@ -4094,6 +4094,28 @@ but it can not erase, write this NOR flash by SRIO or PCIE interface.
 	  You will probably want to define these to avoid a really noisy system
 	  when storing the env in UBI.
 
+- CONFIG_ENV_IS_IN_FS:
+
+	Define this if you want to store the environment inside a filesystem.
+
+	- CONFIG_ENV_FS_INTERFACE:
+
+	  Define this to the interface to the target environment filesystem.
+
+	- CONFIG_ENV_FS_DEVICE_AND_PART:
+
+	  Define this to the device and partition of the target environment,
+	  using standard syntax (see FAT_ENV_DEVICE_AND_PART).
+
+	- CONFIG_ENV_FS_FILE:
+
+	  Define this to the filename of the environment file.
+
+	- CONFIG_ENV_FS_FILE_REDUND:
+
+	  Define this to the filename of the alternate environment file,
+	  if redundancy is desired.
+
 - CONFIG_ENV_IS_IN_FAT:
        Define this if you want to use the FAT file system for the environment.
 
diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 9ca5cb5..cd407b9 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -53,6 +53,7 @@ DECLARE_GLOBAL_DATA_PTR;
 	!defined(CONFIG_ENV_IS_IN_SPI_FLASH)	&& \
 	!defined(CONFIG_ENV_IS_IN_REMOTE)	&& \
 	!defined(CONFIG_ENV_IS_IN_UBI)		&& \
+	!defined(CONFIG_ENV_IS_IN_FS)		&& \
 	!defined(CONFIG_ENV_IS_NOWHERE)
 # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\
 SATA|SPI_FLASH|NVRAM|MMC|FAT|EXT4|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE
diff --git a/common/Makefile b/common/Makefile
index ecc23e6..1705774 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_ENV_IS_IN_NVRAM) += env_embedded.o
 obj-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
 obj-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o
 obj-$(CONFIG_ENV_IS_IN_FAT) += env_fat.o
+obj-$(CONFIG_ENV_IS_IN_FS) += env_fs.o
 obj-$(CONFIG_ENV_IS_IN_EXT4) += env_ext4.o
 obj-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
 obj-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o
diff --git a/common/env_fs.c b/common/env_fs.c
new file mode 100644
index 0000000..bdedaa4
--- /dev/null
+++ b/common/env_fs.c
@@ -0,0 +1,126 @@
+/*
+ * (c) Copyright 2017 by Fiach Antaw <fiach.antaw at uqconnect.edu.au>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <environment.h>
+#include <memalign.h>
+#include <fs.h>
+
+char *env_name_spec = "FS";
+
+env_t *env_ptr;
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int env_init(void)
+{
+	gd->env_addr = (ulong)&default_environment[0];
+	gd->env_valid = 3;
+
+	return 0;
+}
+
+#ifdef CONFIG_CMD_SAVEENV
+int saveenv(void)
+{
+	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
+	int err;
+	loff_t size;
+
+	err = env_export(env_new);
+	if (err)
+		return err;
+
+	err = fs_set_blk_dev(CONFIG_ENV_FS_INTERFACE,
+		CONFIG_ENV_FS_DEVICE_AND_PART, FS_TYPE_ANY);
+	if (err)
+		return err;
+
+#ifdef CONFIG_ENV_FS_FILE_REDUND
+	const char *env_fn;
+
+	if (gd->env_valid == 1)
+		env_fn = CONFIG_ENV_FS_FILE_REDUND;
+	else
+		env_fn = CONFIG_ENV_FS_FILE;
+
+#else /* CONFIG_ENV_FS_FILE_REDUND */
+	const char *env_fn = CONFIG_ENV_FS_FILE;
+#endif /* CONFIG_ENV_FS_FILE_REDUND */
+
+	err = fs_write(env_fn, (ulong)env_new, 0, sizeof(env_t),
+		&size);
+
+#ifdef CONFIG_ENV_FS_FILE_REDUND
+	if (!err)
+		gd->env_valid = gd->env_valid == 1 ? 2 : 1;
+#endif /* CONFIG_ENV_FS_FILE_REDUND */
+
+	return err;
+}
+#endif /* CONFIG_CMD_SAVEENV */
+
+void env_relocate_spec(void)
+{
+#ifdef CONFIG_ENV_FS_FILE_REDUND
+	ALLOC_CACHE_ALIGN_BUFFER(env_t, tmp_env1, 1);
+	ALLOC_CACHE_ALIGN_BUFFER(env_t, tmp_env2, 1);
+	int env1_ok, env2_ok;
+#else /* CONFIG_ENV_FS_FILE_REDUND */
+	ALLOC_CACHE_ALIGN_BUFFER(env_t, tmp_env, 1);
+#endif /* CONFIG_ENV_FS_FILE_REDUND */
+	int err;
+	loff_t size;
+
+	err = fs_set_blk_dev(CONFIG_ENV_FS_INTERFACE,
+		CONFIG_ENV_FS_DEVICE_AND_PART, FS_TYPE_ANY);
+	if (err) {
+		set_default_env("!bad env filesystem");
+		return;
+	}
+
+#ifdef CONFIG_ENV_FS_FILE_REDUND
+	err = fs_read(CONFIG_ENV_FS_FILE, (ulong)tmp_env1, 0,
+		CONFIG_ENV_SIZE, &size);
+	env1_ok = !err;
+
+	err = fs_set_blk_dev(CONFIG_ENV_FS_INTERFACE,
+		CONFIG_ENV_FS_DEVICE_AND_PART, FS_TYPE_ANY);
+	if (err) {
+		set_default_env("!bad env filesystem");
+		return;
+	}
+
+	err = fs_read(CONFIG_ENV_FS_FILE_REDUND, (ulong)tmp_env2, 0,
+		CONFIG_ENV_SIZE, &size);
+	env2_ok = !err;
+
+	if (!env1_ok && !env2_ok) {
+		set_default_env("!bad env files");
+		return;
+	} else if (env1_ok && !env2_ok) {
+		gd->env_valid = 1;
+		env_import((char *)tmp_env1, 1);
+	} else if (!env1_ok && env2_ok) {
+		gd->env_valid = 2;
+		env_import((char *)tmp_env2, 1);
+	} else {
+		env_import_redund((char *)tmp_env1, (char *)tmp_env2);
+	}
+
+#else /* CONFIG_ENV_FS_FILE_REDUND */
+	err = fs_read(CONFIG_ENV_FS_FILE, (ulong)tmp_env, 0,
+		CONFIG_ENV_SIZE, &size);
+	if (err) {
+		set_default_env("!bad env file");
+		return;
+	}
+
+	env_import((char *)tmp_env, 1);
+#endif /* CONFIG_ENV_FS_FILE_REDUND */
+
+	return;
+}
diff --git a/include/environment.h b/include/environment.h
index 0c718eb..d4765d9 100644
--- a/include/environment.h
+++ b/include/environment.h
@@ -103,6 +103,22 @@ extern unsigned long nand_env_oob_offset;
 # endif
 #endif /* CONFIG_ENV_IS_IN_UBI */
 
+#if defined(CONFIG_ENV_IS_IN_FS)
+# ifndef CONFIG_ENV_FS_INTERFACE
+#  error "Need to define CONFIG_ENV_FS_INTERFACE when using CONFIG_ENV_IS_IN_FS"
+# endif
+# ifndef CONFIG_ENV_FS_DEVICE_AND_PART
+#  error "Need to define CONFIG_ENV_FS_DEVICE_AND_PART when using "
+#  error "CONFIG_ENV_IS_IN_FS"
+# endif
+# ifndef CONFIG_ENV_FS_FILE
+#  error "Need to define CONFIG_ENV_FS_FILE when using CONFIG_ENV_IS_IN_FS"
+# endif
+# ifdef CONFIG_ENV_FS_FILE_REDUND
+#  define CONFIG_SYS_REDUNDAND_ENVIRONMENT
+# endif
+#endif /* CONFIG_ENV_IS_IN_FS */
+
 /* Embedded env is only supported for some flash types */
 #ifdef CONFIG_ENV_IS_EMBEDDED
 # if	!defined(CONFIG_ENV_IS_IN_FLASH)	&& \
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index fb9fb34..4c52ee0 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -976,6 +976,10 @@ CONFIG_ENV_FIT_UCBOOT
 CONFIG_ENV_FLAGS_LIST_DEFAULT
 CONFIG_ENV_FLAGS_LIST_STATIC
 CONFIG_ENV_FLASHBOOT
+CONFIG_ENV_FS_DEVICE_AND_PART
+CONFIG_ENV_FS_FILE
+CONFIG_ENV_FS_FILE_REDUND
+CONFIG_ENV_FS_INTERFACE
 CONFIG_ENV_IS_EMBEDDED
 CONFIG_ENV_IS_EMBEDDED_IN_LDR
 CONFIG_ENV_IS_IN_
@@ -983,6 +987,7 @@ CONFIG_ENV_IS_IN_DATAFLASH
 CONFIG_ENV_IS_IN_EEPROM
 CONFIG_ENV_IS_IN_FAT
 CONFIG_ENV_IS_IN_FLASH
+CONFIG_ENV_IS_IN_FS
 CONFIG_ENV_IS_IN_MMC
 CONFIG_ENV_IS_IN_MRAM
 CONFIG_ENV_IS_IN_NAND
-- 
2.7.4



More information about the U-Boot mailing list