gatesgarth migration: Remove u-boot-fw-utils files
This package has been entirely replaced with libubootenv https://jira.digi.com/browse/DEL-7410 Signed-off-by: Gabriel Valcazar <gabriel.valcazar@digi.com>
This commit is contained in:
parent
77039b87df
commit
2388e1b3f6
|
|
@ -1,290 +0,0 @@
|
|||
From: Hector Palacios <hector.palacios@digi.com>
|
||||
Date: Fri, 17 Jul 2020 07:08:50 +0200
|
||||
Subject: [PATCH] tools: env: implement support for environment encryption by
|
||||
CAAM
|
||||
|
||||
Use the md5sum of HWID words (on the device tree) as key modifier.
|
||||
|
||||
Signed-off-by: Diaz de Grenu, Jose <Jose.DiazdeGrenu@digi.com>
|
||||
Signed-off-by: Gonzalo Ruiz <Gonzalo.Ruiz@digi.com>
|
||||
Signed-off-by: Hector Palacios <hector.palacios@digi.com>
|
||||
|
||||
https://jira.digi.com/browse/DEL-7185
|
||||
https://jira.digi.com/browse/DEL-2836
|
||||
---
|
||||
tools/env/Makefile | 2 +-
|
||||
tools/env/caam_keyblob.h | 45 +++++++++++++
|
||||
tools/env/fw_env.c | 141 +++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 187 insertions(+), 1 deletion(-)
|
||||
create mode 100644 tools/env/caam_keyblob.h
|
||||
|
||||
diff --git a/tools/env/Makefile b/tools/env/Makefile
|
||||
index b627796e949e..fc7c44baa2b7 100644
|
||||
--- a/tools/env/Makefile
|
||||
+++ b/tools/env/Makefile
|
||||
@@ -24,7 +24,7 @@ hostprogs-y := fw_printenv
|
||||
|
||||
lib-y += fw_env.o \
|
||||
crc32.o ctype.o linux_string.o \
|
||||
- env_attr.o env_flags.o
|
||||
+ env_attr.o env_flags.o ../../lib/md5.o
|
||||
|
||||
fw_printenv-objs := fw_env_main.o $(lib-y)
|
||||
|
||||
diff --git a/tools/env/caam_keyblob.h b/tools/env/caam_keyblob.h
|
||||
new file mode 100644
|
||||
index 000000000000..1cdf3946c1ba
|
||||
--- /dev/null
|
||||
+++ b/tools/env/caam_keyblob.h
|
||||
@@ -0,0 +1,45 @@
|
||||
+/*
|
||||
+ * CAAM public-level include definitions for the key blob
|
||||
+ *
|
||||
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
|
||||
+ */
|
||||
+
|
||||
+#ifndef CAAM_KEYBLOB_H
|
||||
+#define CAAM_KEYBLOB_H
|
||||
+
|
||||
+
|
||||
+#include <linux/ioctl.h>
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
+struct caam_kb_data {
|
||||
+ char *rawkey;
|
||||
+ size_t rawkey_len;
|
||||
+ char *keyblob;
|
||||
+ size_t keyblob_len;
|
||||
+ char *keymod;
|
||||
+ size_t keymod_len;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+#define CAAM_KB_MAGIC 'I'
|
||||
+
|
||||
+/**
|
||||
+ * DOC: CAAM_KB_ENCRYPT - generate a key blob from raw key
|
||||
+ *
|
||||
+ * Takes an caam_kb_data struct and returns it with the key blob
|
||||
+ */
|
||||
+#define CAAM_KB_ENCRYPT _IOWR(CAAM_KB_MAGIC, 0, \
|
||||
+ struct caam_kb_data)
|
||||
+
|
||||
+/**
|
||||
+ * DOC: CAAM_KB_DECRYPT - get keys from a key blob
|
||||
+ *
|
||||
+ * Takes an caam_kb_data struct and returns it with the raw key.
|
||||
+ */
|
||||
+#define CAAM_KB_DECRYPT _IOWR(CAAM_KB_MAGIC, 1, struct caam_kb_data)
|
||||
+
|
||||
+#ifndef GENMEM_KEYMOD_LEN
|
||||
+#define GENMEM_KEYMOD_LEN 16
|
||||
+#endif
|
||||
+
|
||||
+#endif /* CAAM_KEYBLOB_H */
|
||||
diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c
|
||||
index a5d75958e1b6..228d11c070e6 100644
|
||||
--- a/tools/env/fw_env.c
|
||||
+++ b/tools/env/fw_env.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
+#include <u-boot/md5.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
|
||||
@@ -37,9 +38,17 @@
|
||||
|
||||
#include <mtd/ubi-user.h>
|
||||
|
||||
+#include "caam_keyblob.h"
|
||||
#include "fw_env_private.h"
|
||||
#include "fw_env.h"
|
||||
|
||||
+/*
|
||||
+ * The BLOB includes a random AES-256 key (32 bytes) and a
|
||||
+ * Message Authentication Code (MAC) (16 bytes)
|
||||
+ */
|
||||
+#define BLOB_OVERHEAD 48
|
||||
+#define CAAM_KEY_DEV "/dev/caam_kb"
|
||||
+
|
||||
struct env_opts default_opts = {
|
||||
#ifdef CONFIG_FILE
|
||||
.config_file = CONFIG_FILE
|
||||
@@ -117,6 +126,7 @@ static struct environment environment = {
|
||||
};
|
||||
|
||||
static int have_redund_env;
|
||||
+static int caam_encryption_flag;
|
||||
|
||||
static unsigned char active_flag = 1;
|
||||
/* obsolete_flag must be 0 to efficiently set it on NOR flash without erasing */
|
||||
@@ -442,6 +452,106 @@ char *fw_getdefenv(char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static void check_caam_encryption(void)
|
||||
+{
|
||||
+ const char *dt_prop = "/proc/device-tree/digi,uboot-env,encrypted";
|
||||
+
|
||||
+ if (access(dt_prop, F_OK) != -1)
|
||||
+ caam_encryption_flag = 1;
|
||||
+}
|
||||
+
|
||||
+#define MAX_HWID_WORDS 4
|
||||
+static int env_caam_get_keymod(unsigned char output[16])
|
||||
+{
|
||||
+ int i;
|
||||
+ int len;
|
||||
+ int fd;
|
||||
+ uint32_t ocotp_hwid[MAX_HWID_WORDS];
|
||||
+ const char dt_prop[32];
|
||||
+
|
||||
+ for (i = 0; i < MAX_HWID_WORDS; i++) {
|
||||
+ sprintf(dt_prop, "/proc/device-tree/digi,hwid_%d", i);
|
||||
+ if (access(dt_prop, F_OK) != -1) {
|
||||
+ char buf[sizeof(uint32_t)];
|
||||
+
|
||||
+ fd = open(dt_prop, O_RDONLY);
|
||||
+ if (fd < 0)
|
||||
+ return fd;
|
||||
+ len = read(fd, buf, sizeof(uint32_t));
|
||||
+ if (len < 0) {
|
||||
+ close(fd);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ ocotp_hwid[i] = ntohl(*(uint32_t *)buf);
|
||||
+ close(fd);
|
||||
+ } else {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Calculate md5sum on the raw HWID array */
|
||||
+ md5((unsigned char *)(&ocotp_hwid), sizeof(uint32_t) * i, output);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int env_caam_crypt(char *data, const int enc)
|
||||
+{
|
||||
+ struct caam_kb_data enc_data;
|
||||
+ int fd;
|
||||
+ int ret = 0;
|
||||
+ const int len = usable_envsize;
|
||||
+ int ioctl_mode;
|
||||
+ char *buffer;
|
||||
+ unsigned char key_modifier[16];
|
||||
+
|
||||
+ ret = env_caam_get_keymod(key_modifier);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ enc_data.keymod = (char *)key_modifier;
|
||||
+ enc_data.keymod_len = sizeof(key_modifier);
|
||||
+
|
||||
+ enc_data.keyblob_len = len;
|
||||
+ enc_data.rawkey_len = len - BLOB_OVERHEAD;
|
||||
+
|
||||
+ buffer = malloc(len);
|
||||
+ if (!buffer) {
|
||||
+ printf("Could not allocate memory\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (enc) {
|
||||
+ enc_data.rawkey = data;
|
||||
+ ioctl_mode = CAAM_KB_ENCRYPT;
|
||||
+ enc_data.keyblob = buffer;
|
||||
+ } else {
|
||||
+ enc_data.keyblob = data;
|
||||
+ ioctl_mode = CAAM_KB_DECRYPT;
|
||||
+ enc_data.rawkey = buffer;
|
||||
+ }
|
||||
+
|
||||
+ if ((fd = open(CAAM_KEY_DEV, O_RDWR)) < 0) {
|
||||
+ ret = fd;
|
||||
+ goto free;
|
||||
+ }
|
||||
+
|
||||
+ ret = ioctl(fd, ioctl_mode, &enc_data);
|
||||
+ if (ret) {
|
||||
+ printf("CAAM_KEY_DEV ioctl failed: %d\n", ret);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(data, buffer, len);
|
||||
+
|
||||
+out:
|
||||
+ close(fd);
|
||||
+free:
|
||||
+ free(buffer);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Print the current definition of one, or more, or all
|
||||
* environment variables
|
||||
@@ -505,9 +615,20 @@ int fw_printenv(int argc, char *argv[], int value_only, struct env_opts *opts)
|
||||
|
||||
int fw_env_flush(struct env_opts *opts)
|
||||
{
|
||||
+ int ret;
|
||||
+
|
||||
if (!opts)
|
||||
opts = &default_opts;
|
||||
|
||||
+ if (caam_encryption_flag) {
|
||||
+ ret = env_caam_crypt(environment.data, 1);
|
||||
+ if (ret) {
|
||||
+ fprintf(stderr,
|
||||
+ "Error: can't encrypt env for flash\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Update CRC
|
||||
*/
|
||||
@@ -1396,6 +1517,8 @@ int fw_env_open(struct env_opts *opts)
|
||||
struct env_image_single *single;
|
||||
struct env_image_redundant *redundant;
|
||||
|
||||
+ check_caam_encryption();
|
||||
+
|
||||
if (!opts)
|
||||
opts = &default_opts;
|
||||
|
||||
@@ -1434,6 +1557,15 @@ int fw_env_open(struct env_opts *opts)
|
||||
|
||||
crc0 = crc32(0, (uint8_t *)environment.data, ENV_SIZE);
|
||||
|
||||
+ if (caam_encryption_flag) {
|
||||
+ ret = env_caam_crypt(environment.data, 0);
|
||||
+ if (ret) {
|
||||
+ fprintf(stderr,
|
||||
+ "Error: can't decrypt environment\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
crc0_ok = (crc0 == *environment.crc);
|
||||
if (!have_redund_env) {
|
||||
if (!crc0_ok) {
|
||||
@@ -1491,6 +1623,15 @@ int fw_env_open(struct env_opts *opts)
|
||||
|
||||
crc1 = crc32(0, (uint8_t *)redundant->data, ENV_SIZE);
|
||||
|
||||
+ if (caam_encryption_flag) {
|
||||
+ ret = env_caam_crypt(redundant->data, 0);
|
||||
+ if (ret) {
|
||||
+ fprintf(stderr,
|
||||
+ "Error: can't decrypt environment\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
crc1_ok = (crc1 == redundant->crc);
|
||||
flag1 = redundant->flags;
|
||||
|
|
@ -1,152 +0,0 @@
|
|||
From: Javier Viguera <javier.viguera@digi.com>
|
||||
Date: Tue, 10 Jan 2017 19:34:26 +0100
|
||||
Subject: [PATCH 2/4] Implement U-Boot environment access functions
|
||||
|
||||
Signed-off-by: Javier Viguera <javier.viguera@digi.com>
|
||||
Signed-off-by: Jose Diaz de Grenu <Jose.DiazdeGrenu@digi.com>
|
||||
Signed-off-by: Gonzalo Ruiz <Gonzalo.Ruiz@digi.com>
|
||||
---
|
||||
tools/env/Makefile | 2 +-
|
||||
tools/env/ubootenv.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
tools/env/ubootenv.h | 46 ++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 113 insertions(+), 1 deletion(-)
|
||||
create mode 100644 tools/env/ubootenv.c
|
||||
create mode 100644 tools/env/ubootenv.h
|
||||
|
||||
diff --git a/tools/env/Makefile b/tools/env/Makefile
|
||||
index 33e41f5..486e76c 100644
|
||||
--- a/tools/env/Makefile
|
||||
+++ b/tools/env/Makefile
|
||||
@@ -23,7 +23,7 @@ hostprogs-y := fw_printenv
|
||||
|
||||
lib-y += fw_env.o \
|
||||
crc32.o ctype.o linux_string.o \
|
||||
- env_attr.o env_flags.o ../../lib/md5.o
|
||||
+ env_attr.o env_flags.o ../../lib/md5.o ubootenv.o
|
||||
|
||||
fw_printenv-objs := fw_env_main.o $(lib-y)
|
||||
|
||||
diff --git a/tools/env/ubootenv.c b/tools/env/ubootenv.c
|
||||
new file mode 100644
|
||||
index 0000000..eb9ad5f
|
||||
--- /dev/null
|
||||
+++ b/tools/env/ubootenv.c
|
||||
@@ -0,0 +1,66 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2017, Digi International Inc.
|
||||
+ *
|
||||
+ * This Source Code Form is subject to the terms of the Mozilla Public
|
||||
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
+ * file, you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ *
|
||||
+ * Description: U-Boot environment get/set wrappers
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#include "fw_env.h"
|
||||
+
|
||||
+/*
|
||||
+ * Function: uboot_getenv
|
||||
+ * Description: get U-Boot's environment variable
|
||||
+ */
|
||||
+int uboot_getenv(char *name, const char **value)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ ret = fw_env_open(NULL);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ *value = fw_getenv(name);
|
||||
+
|
||||
+err:
|
||||
+ return ret ? -1 : 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Function: uboot_setenv
|
||||
+ * Description: set U-Boot's environment variable
|
||||
+ */
|
||||
+int uboot_setenv(char *name, char *value)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ ret = fw_env_open(NULL);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ ret = fw_env_write(name, value);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ ret = fw_env_flush(NULL);
|
||||
+ if (ret)
|
||||
+ goto err;
|
||||
+
|
||||
+ ret = fw_env_close(NULL);
|
||||
+
|
||||
+err:
|
||||
+ return ret ? -1 : 0;
|
||||
+}
|
||||
diff --git a/tools/env/ubootenv.h b/tools/env/ubootenv.h
|
||||
new file mode 100644
|
||||
index 0000000..d4043db
|
||||
--- /dev/null
|
||||
+++ b/tools/env/ubootenv.h
|
||||
@@ -0,0 +1,46 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2017, Digi International Inc.
|
||||
+ *
|
||||
+ * This Source Code Form is subject to the terms of the Mozilla Public
|
||||
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
+ * file, you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ *
|
||||
+ * Description: U-Boot environment get/set wrappers
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef UBOOTENV_H
|
||||
+#define UBOOTENV_H
|
||||
+
|
||||
+/*
|
||||
+ * Get U-Boot's environment variable.
|
||||
+ *
|
||||
+ * Params:
|
||||
+ * 'name' (input) Name of the environment variable
|
||||
+ * 'value' (output) Pointer to the variable's value
|
||||
+ * (NULL if not found)
|
||||
+ *
|
||||
+ * Return: 0 on sucess, -1 on failure
|
||||
+ */
|
||||
+int uboot_getenv(char *name, const char **value);
|
||||
+
|
||||
+/*
|
||||
+ * Set U-Boot's environment variable.
|
||||
+ *
|
||||
+ * Params:
|
||||
+ * 'name' (input) Name of the environment variable
|
||||
+ * 'value' (input) Value of the environment variable
|
||||
+ *
|
||||
+ * Return: 0 on sucess, -1 on failure
|
||||
+ */
|
||||
+int uboot_setenv(char *name, char *value);
|
||||
+
|
||||
+#endif /* UBOOTENV_H */
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
From: Javier Viguera <javier.viguera@digi.com>
|
||||
Date: Fri, 15 Feb 2019 09:23:50 +0100
|
||||
Subject: [PATCH 3/4] fw_env: add support to unlock emmc boot partition
|
||||
|
||||
Signed-off-by: Javier Viguera <javier.viguera@digi.com>
|
||||
Signed-off-by: Arturo Buzarra <arturo.buzarra@digi.com>
|
||||
Signed-off-by: Gonzalo Ruiz <Gonzalo.Ruiz@digi.com>
|
||||
---
|
||||
tools/env/fw_env.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 38 insertions(+)
|
||||
|
||||
diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c
|
||||
index b124b1e..b87cd83 100644
|
||||
--- a/tools/env/fw_env.c
|
||||
+++ b/tools/env/fw_env.c
|
||||
@@ -1383,10 +1383,39 @@ err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Set mmcboot partition read-write protection
|
||||
+ */
|
||||
+static int sysfs_mmcboot_set_protection(const char *device, int value)
|
||||
+{
|
||||
+ int fd;
|
||||
+ ssize_t nbytes;
|
||||
+ char buf[64];
|
||||
+ snprintf(buf, sizeof(buf), "/sys/block/%s/force_ro", device);
|
||||
+ fd = open(buf, O_WRONLY);
|
||||
+ if (fd < 0) {
|
||||
+ perror("sysfs_mmcboot_set_protection: error opening mmcblk");
|
||||
+ return fd;
|
||||
+ }
|
||||
+ snprintf(buf, sizeof(buf), "%s", value ? "1" : "0");
|
||||
+ nbytes = write(fd, buf, 2);
|
||||
+ close(fd);
|
||||
+
|
||||
+ /* Verify bytes written */
|
||||
+ if (nbytes < 2)
|
||||
+ {
|
||||
+ perror("sysfs_mmcboot_set_protection: error writing mmcblk protection");
|
||||
+ return nbytes >=0 ? -EIO : nbytes;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int flash_io_write(int fd_current)
|
||||
{
|
||||
int fd_target = -1, rc, dev_target;
|
||||
const char *dname, *target_temp = NULL;
|
||||
+ char *mmcblk = NULL;
|
||||
|
||||
if (have_redund_env) {
|
||||
/* switch to next partition for writing */
|
||||
@@ -1414,6 +1443,11 @@ static int flash_io_write(int fd_current)
|
||||
fd_target = fd_current;
|
||||
}
|
||||
|
||||
+ /* Disable mmcboot protection if using EMMC (set read-write) */
|
||||
+ mmcblk = strstr(DEVNAME(dev_target), "mmcblk");
|
||||
+ if (mmcblk)
|
||||
+ sysfs_mmcboot_set_protection(mmcblk, 0);
|
||||
+
|
||||
rc = flash_write(fd_current, fd_target, dev_target);
|
||||
|
||||
if (fsync(fd_current) && !(errno == EINVAL || errno == EROFS)) {
|
||||
@@ -1465,6 +1499,10 @@ static int flash_io_write(int fd_current)
|
||||
dname, strerror(errno));
|
||||
}
|
||||
}
|
||||
+
|
||||
+ /* Re-enable mmcboot protection (set read-only) */
|
||||
+ if (mmcblk)
|
||||
+ sysfs_mmcboot_set_protection(mmcblk, 1);
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
From: Hector Palacios <hector.palacios@digi.com>
|
||||
Date: Mon, 22 Jan 2018 10:18:18 +0100
|
||||
Subject: [PATCH 4/4] 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
|
||||
Signed-off-by: Gonzalo Ruiz <Gonzalo.Ruiz@digi.com>
|
||||
---
|
||||
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 b87cd83..041dc1b 100644
|
||||
--- a/tools/env/fw_env.c
|
||||
+++ b/tools/env/fw_env.c
|
||||
@@ -129,6 +129,8 @@ static struct environment environment = {
|
||||
|
||||
static int have_redund_env;
|
||||
static int caam_encryption_flag;
|
||||
+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 */
|
||||
@@ -1031,6 +1033,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;
|
||||
@@ -1411,6 +1429,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 (have_redund_env)
|
||||
+ 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_write(int fd_current)
|
||||
{
|
||||
int fd_target = -1, rc, dev_target;
|
||||
@@ -1586,6 +1661,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 (have_redund_env && (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;
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
# Configuration file for fw_(printenv/setenv) utility.
|
||||
# Up to two entries are valid, in this case the redundant
|
||||
# environment sector is assumed present.
|
||||
|
||||
# Device name Offset Size
|
||||
/dev/mmcblk0boot1 0x1C0000 0x4000
|
||||
/dev/mmcblk0boot1 0x1E0000 0x4000
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
# Configuration file for fw_(printenv/setenv) utility.
|
||||
# Up to two entries are valid, in this case the redundant
|
||||
# environment sector is assumed present.
|
||||
# If both copies are set to the same offset, an automatic mechanism will
|
||||
# determine the first good sectors where each copy lives, skipping bad blocks.
|
||||
|
||||
# Device name Offset Size Erase-size No.Blocks
|
||||
/dev/##MTDINDEX## ##ENV_OFFSET## ##ENV_SIZE## ##ERASEBLOCK## ##NBLOCKS##
|
||||
/dev/##MTDINDEX## ##ENV_REDUND_OFFSET## ##ENV_SIZE## ##ERASEBLOCK## ##NBLOCKS##
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
# Copyright (C) 2015-2020 Digi International
|
||||
|
||||
FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:"
|
||||
|
||||
SRC_URI += " \
|
||||
file://${STORAGE_MEDIA}/fw_env.config \
|
||||
"
|
||||
|
||||
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
|
||||
# force that our patches are applied later. As our layer has more priority than
|
||||
# 'meta-swupdate' we need to do the changes to SRC_URI in an anonymous python
|
||||
# function instead of a normal '_append' to the SRC_URI variable.
|
||||
python() {
|
||||
ufw_patches = d.getVar('UBOOT_FW_UTILS_PATCHES', True)
|
||||
if ufw_patches:
|
||||
src_uri = d.getVar('SRC_URI', True)
|
||||
d.setVar('SRC_URI', src_uri + ufw_patches)
|
||||
}
|
||||
|
||||
# We do not have a platform defconfig in this version of u-boot, so just use the generic
|
||||
# sandbox defconfig, which is enough to build the Linux user-space tool (fw_printenv)
|
||||
UBOOT_CONFIG = "sandbox"
|
||||
UBOOT_CONFIG[sandbox] = "sandbox_defconfig"
|
||||
|
||||
do_install_append() {
|
||||
install -d ${D}${includedir}/libubootenv
|
||||
install -m 0644 ${S}/tools/env/ubootenv.h ${D}${includedir}/libubootenv/
|
||||
install -m 0644 ${WORKDIR}/${STORAGE_MEDIA}/fw_env.config ${D}${sysconfdir}/
|
||||
}
|
||||
|
||||
pkg_postinst_ontarget_${PN}() {
|
||||
CONFIG_FILE="/etc/fw_env.config"
|
||||
MMCDEV="$(sed -ne 's,.*root=/dev/mmcblk\([0-9]\)p.*,\1,g;T;p' /proc/cmdline)"
|
||||
if [ -n "${MMCDEV}" ]; then
|
||||
sed -i -e "s,^/dev/mmcblk[^[:blank:]]\+,/dev/mmcblk${MMCDEV},g" ${CONFIG_FILE}
|
||||
fi
|
||||
|
||||
PARTTABLE="/proc/mtd"
|
||||
MTDINDEX="$(sed -ne "s/\(^mtd[0-9]\+\):.*\<environment\>.*/\1/g;T;p" ${PARTTABLE} 2>/dev/null)"
|
||||
if [ -n "${MTDINDEX}" ]; then
|
||||
# Initialize variables for fixed offset values
|
||||
# (backwards compatible with old U-Boot)
|
||||
ENV_OFFSET="${UBOOT_ENV_OFFSET}"
|
||||
ENV_REDUND_OFFSET="${UBOOT_ENV_SIZE}"
|
||||
ENV_SIZE="${UBOOT_ENV_SIZE}"
|
||||
ERASEBLOCK=""
|
||||
NBLOCKS=""
|
||||
|
||||
if [ -f "/proc/device-tree/digi,uboot,dynamic-env" ]; then
|
||||
# Update variables for dynamic environment
|
||||
# - Both copies starting at the same offset
|
||||
ENV_REDUND_OFFSET="${UBOOT_ENV_OFFSET}"
|
||||
# - Calculated erase block size
|
||||
ERASEBLOCK="$(grep "^${MTDINDEX}:" ${PARTTABLE} | awk '{printf("0x%d",$3)}')"
|
||||
# - Calculated number of blocks
|
||||
MTDSIZE="$(grep "^${MTDINDEX}:" ${PARTTABLE} | awk '{printf("0x%d",$2)}')"
|
||||
NBLOCKS="$(((MTDSIZE - UBOOT_ENV_OFFSET) / ERASEBLOCK))"
|
||||
# If a range was provided, calculate the number of
|
||||
# blocks in the range and use that number, unless they
|
||||
# exceed the total number of blocks available in the
|
||||
# whole partition.
|
||||
if [ -n "${UBOOT_ENV_RANGE}" ]; then
|
||||
RANGE_BLOCKS="$((UBOOT_ENV_RANGE / ERASEBLOCK))"
|
||||
[ "${RANGE_BLOCKS}" -lt "${NBLOCKS}" ] && NBLOCKS="${RANGE_BLOCKS}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Substitute stub with configuration and calculated values
|
||||
sed -i -e "s/##MTDINDEX##/${MTDINDEX}/g" \
|
||||
-e "s/##ENV_OFFSET##/${ENV_OFFSET}/g" \
|
||||
-e "s/##ENV_REDUND_OFFSET##/${ENV_REDUND_OFFSET}/g" \
|
||||
-e "s/##ENV_SIZE##/${ENV_SIZE}/g" \
|
||||
-e "s/##ERASEBLOCK##/${ERASEBLOCK}/g" \
|
||||
-e "s/##NBLOCKS##/${NBLOCKS}/g" \
|
||||
${CONFIG_FILE}
|
||||
fi
|
||||
}
|
||||
Loading…
Reference in New Issue