From: Gabriel Valcazar Date: Wed, 7 Apr 2021 11:35:15 +0200 Subject: [PATCH] Implement U-Boot environment access functions Keep the same function signatures as u-boot-fw-utils, so that all code making use of this functionality remains compatible. Use the libubootenv implementation of the fw_printenv and fw_setenv apps as reference. Upstream-Status: Inappropriate [DEY specific] https://jira.digi.com/browse/DEL-7410 Signed-off-by: Javier Viguera Signed-off-by: Jose Diaz de Grenu Signed-off-by: Gonzalo Ruiz Signed-off-by: Gabriel Valcazar --- src/libuboot.h | 23 ++++++++++++ src/uboot_env.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) diff --git a/src/libuboot.h b/src/libuboot.h index 3ed3244..e83b3a5 100644 --- a/src/libuboot.h +++ b/src/libuboot.h @@ -201,6 +201,29 @@ const char *libuboot_getname(void *entry); */ const char *libuboot_getvalue(void *entry); +/* + * 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); + #ifdef __cplusplus } #endif diff --git a/src/uboot_env.c b/src/uboot_env.c index ae85c7e..358dfbb 100644 --- a/src/uboot_env.c +++ b/src/uboot_env.c @@ -2103,3 +2103,99 @@ void libuboot_exit(struct uboot_ctx *ctx) free(ctx); } + +static int uboot_common_init(struct uboot_ctx *ctx) +{ + const char *cfgfname = "/etc/fw_env.config"; + const char *defenvfile = "/etc/u-boot-initial-env"; + + if (libuboot_read_config(ctx, cfgfname) < 0) { + fprintf(stderr, "Configuration file wrong or corrupted\n"); + return -1; + } + + if (libuboot_open(ctx) < 0) { + fprintf(stderr, "Cannot read environment, using default\n"); + if (libuboot_load_file(ctx, defenvfile) < 0) { + fprintf(stderr, "Cannot read default environment from file\n"); + return -1; + } + } + + return 0; +} + +/* + * Function: uboot_getenv + * Description: get U-Boot's environment variable + */ +int uboot_getenv(char *name, const char **value) +{ + struct uboot_ctx *ctx; + int ret = 0; + + ret = libuboot_initialize(&ctx, NULL); + if (ret < 0) { + fprintf(stderr, "Cannot initialize environment\n"); + goto err; + } + + ret = uboot_common_init(ctx); + if (ret < 0) + goto err; + + *value = libuboot_get_env(ctx, name); + +err: + libuboot_close(ctx); + libuboot_exit(ctx); + + return ret ? -1 : 0; +} + +/* + * Function: uboot_setenv + * Description: set U-Boot's environment variable + */ +int uboot_setenv(char *name, char *value) +{ + struct uboot_ctx *ctx; + bool need_store = false; + const char *curr; + int ret = 0; + + ret = libuboot_initialize(&ctx, NULL); + if (ret < 0) { + fprintf(stderr, "Cannot initialize environment\n"); + goto err; + } + + ret = uboot_common_init(ctx); + if (ret < 0) + goto err; + + curr = libuboot_get_env(ctx, name); + if (value == NULL) { + if (curr != NULL) { + libuboot_set_env(ctx, name, NULL); + need_store = true; + } + } else { + if (curr == NULL || strcmp(curr, value) != 0) { + libuboot_set_env(ctx, name, value); + need_store = true; + } + } + + if (need_store) { + ret = libuboot_env_store(ctx); + if (ret) + fprintf(stderr, "Error storing the env\n"); + } + +err: + libuboot_close(ctx); + libuboot_exit(ctx); + + return ret ? -1 : 0; +}