From 5eb436f152f92e064e21eee32eac66320a54488e Mon Sep 17 00:00:00 2001 From: Hector Palacios Date: Mon, 22 Jan 2018 11:26:37 +0100 Subject: [PATCH] u-boot-fw-utils: forward port support for dynamic environment Support for dynamic location of U-Boot environment was added in commit 2b5017956be5d81251f2932e2fe0cf2d3ac3f970. This forward ports the patch to Yocto 2.4. Signed-off-by: Hector Palacios https://jira.digi.com/browse/DEL-5574 --- ...pport-to-set-dynamic-location-of-env.patch | 143 ++++++++++++++++++ .../u-boot/u-boot-fw-utils_%.bbappend | 1 + 2 files changed, 144 insertions(+) create mode 100644 meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils/0004-tools-env-add-support-to-set-dynamic-location-of-env.patch diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils/0004-tools-env-add-support-to-set-dynamic-location-of-env.patch b/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils/0004-tools-env-add-support-to-set-dynamic-location-of-env.patch new file mode 100644 index 000000000..34ee46d80 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils/0004-tools-env-add-support-to-set-dynamic-location-of-env.patch @@ -0,0 +1,143 @@ +From: Hector Palacios +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 + +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; diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils_%.bbappend b/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils_%.bbappend index 8a58bd8f4..ae81b52bc 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils_%.bbappend +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils_%.bbappend @@ -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