u-boot-fw-utils: forward port support for dynamic environment

Support for dynamic location of U-Boot environment was added in
commit 2b5017956b. This forward ports
the patch to Yocto 2.4.

Signed-off-by: Hector Palacios <hector.palacios@digi.com>

https://jira.digi.com/browse/DEL-5574
This commit is contained in:
Hector Palacios 2018-01-22 11:26:37 +01:00
parent c741dc365a
commit 5eb436f152
2 changed files with 144 additions and 0 deletions

View File

@ -0,0 +1,143 @@
From: Hector Palacios <hector.palacios@digi.com>
Date: Mon, 22 Jan 2018 10:18:18 +0100
Subject: [PATCH] tools: env: add support to set dynamic location of
environment copies
A mechanism was added in U-Boot to set the location of environment copies
dynamically in an shared area. If the config file sets both copies to the
same offset, a function will be called to set the offset of each copy to
the first two good NAND sectors within the specified area.
The config file should contain the sector size and the number of sectors
of the area, like in this example:
# Device name Offset Size Erase-size No.Blocks
/dev/mtd1 0x0 0x20000 0x20000 8
/dev/mtd1 0x0 0x20000 0x20000 8
Signed-off-by: Hector Palacios <hector.palacios@digi.com>
https://jira.digi.com/browse/DUB-741
---
tools/env/fw_env.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c
index db1182c7216e..820feb3946f5 100644
--- a/tools/env/fw_env.c
+++ b/tools/env/fw_env.c
@@ -127,6 +127,8 @@ static int env_aes_cbc_crypt(char *data, const int enc, uint8_t *key);
static int caam_encryption_flag;
static int HaveRedundEnv = 0;
+static int have_dynamic_env;
+static off_t top_of_range; /* end of the last block we may use */
static unsigned char active_flag = 1;
/* obsolete_flag must be 0 to efficiently set it on NOR flash without erasing */
@@ -847,6 +849,22 @@ static int flash_read_buf (int dev, int fd, void *buf, size_t count,
*/
blocklen = DEVESIZE (dev);
+ if (!have_dynamic_env) {
+ /*
+ * To calculate the top of the range, we have to use the
+ * global DEVOFFSET (dev), which can be different from
+ * offset
+ */
+ top_of_range = ((DEVOFFSET(dev) / blocklen) +
+ ENVSECTORS(dev)) * blocklen;
+ }
+
+ if (offset >= top_of_range) {
+ /* End of range is reached */
+ fprintf(stderr, "Too few good blocks within range\n");
+ return -1;
+ }
+
/* Limit to one block for the first read */
if (readlen > blocklen - block_seek)
readlen = blocklen - block_seek;
@@ -1194,6 +1212,63 @@ static int sysfs_mmcboot_set_protection(const char *device, int value)
return 0;
}
+static int set_dynamic_location(void)
+{
+ int fd, i, nsectors;
+ loff_t offset, blocksize;
+ int dev = 0;
+ int copies = 1;
+ int rc = 0;
+
+ if (HaveRedundEnv)
+ copies++;
+
+ fd = open(DEVNAME(dev), O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "Can't open %s: %s\n", DEVNAME(dev),
+ strerror(errno));
+ rc = -1;
+ goto error;
+ }
+
+ /* Set initial block to start looking for environment */
+ offset = DEVOFFSET(dev);
+ /* Use variables for common values */
+ blocksize = DEVESIZE(dev);
+ /* Look for the number of sectors specified for the primary copy */
+ nsectors = ENVSECTORS(dev);
+
+ for (i = 0; i < nsectors && copies; i++) {
+ rc = flash_bad_block(fd, DEVTYPE(dev), offset);
+ if (rc < 0) {
+ rc = -1;
+ goto error;
+ } else if (!rc) {
+ /*
+ * Set first good block as primary (no matter if it is
+ * the other copy. After all, the 'current' copy is
+ * determined by the active flag.
+ */
+ DEVOFFSET(dev) = offset;
+ copies--;
+ dev++;
+ }
+ offset += blocksize;
+ }
+
+ while (copies) {
+ /* No good sectors available. Set offset out of bounds */
+ DEVOFFSET(dev) = offset;
+ copies--;
+ dev++;
+ }
+ rc = 0;
+
+error:
+ close(fd);
+ return rc;
+}
+
static int flash_io (int mode)
{
int fd_current, fd_target, rc, dev_target;
@@ -1327,6 +1402,18 @@ int fw_env_open(struct env_opts *opts)
environment.data = single->data;
}
+ /*
+ * Trigger dynamic location of environment if redundant copy has the
+ * same offset than primary copy.
+ */
+ if (HaveRedundEnv && (DEVOFFSET(0) == DEVOFFSET(1))) {
+ have_dynamic_env = 1;
+ top_of_range = DEVOFFSET(0) + (ENVSECTORS(0) * DEVESIZE(0));
+
+ if (set_dynamic_location() < 0)
+ return -1;
+ }
+
dev_current = 0;
if (flash_io(O_RDONLY)) {
ret = -EIO;

View File

@ -10,6 +10,7 @@ UBOOT_FW_UTILS_PATCHES = " \
file://0001-tools-env-implement-support-for-environment-encrypti.patch \
file://0002-Implement-U-Boot-environment-access-functions.patch \
file://0003-fw_env-add-support-to-unlock-emmc-boot-partition.patch \
file://0004-tools-env-add-support-to-set-dynamic-location-of-env.patch \
"
# Patches from 'meta-swupdate' touch the same files than ours, so we need to