From: "Marek Behún" <kabel@kernel.org>
To: "Simon Glass" <sjg@chromium.org>, "Stefan Roese" <sr@denx.de>,
"Pali Rohár" <pali@kernel.org>
Cc: u-boot@lists.denx.de, "Marek Behún" <marek.behun@nic.cz>
Subject: [PATCH 4/5] env: Add support for board specific special default environment
Date: Thu, 28 Oct 2021 05:28:09 +0200 [thread overview]
Message-ID: <20211028032810.18146-5-kabel@kernel.org> (raw)
In-Reply-To: <20211028032810.18146-1-kabel@kernel.org>
From: Marek Behún <marek.behun@nic.cz>
The default_environment[] buffer is built at compile time, but sometimes
it makes sense for some default environment variables to be determined
at runtime, for example:
- one board code may support different boards, and needs that
fdtfile, board, board_name
are set appropriately when command
env default -a
is executed
- some boards may want to prohibit the
env default -a
command to remove device MAC addresses stored in
ethaddr, ethNaddr.
This is the case for the ESPRESSObin board code, for example, where
currently the board_late_init() function rewrites the default
environment array to achieve this.
Add a new board specific function,
const char *board_special_default_env(unsigned i, const char **name);
which returns the value of i-th board special default environemnt
variable, while storing it's name to *name.
Add default weak implementation of this functions returning NULL.
Add code to default environemnt handlers in env/common.c, which iterate
these special board default environment variables and get it's values in
precedence to values in the default_environment[] buffer.
Signed-off-by: Marek Behún <marek.behun@nic.cz>
---
env/common.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 96 insertions(+), 3 deletions(-)
diff --git a/env/common.c b/env/common.c
index 208e2adaa0..d157ca562a 100644
--- a/env/common.c
+++ b/env/common.c
@@ -148,6 +148,41 @@ char *from_env(const char *envvar)
return ret;
}
+__weak const char *board_special_default_env(unsigned i, const char **name)
+{
+ return NULL;
+}
+
+static int board_special_default_env_get(const char *var, char *buf,
+ unsigned len)
+{
+ int i;
+
+ /*
+ * Iterate all board special default env variables, and if one
+ * exists with the requested name, return it.
+ */
+ for (i = 0; ; ++i) {
+ const char *name, *value;
+
+ value = board_special_default_env(i, &name);
+ if (!value)
+ break;
+
+ if (!strcmp(var, name)) {
+ unsigned res = strlen(value);
+
+ memcpy(buf, value, min(len, res + 1));
+ if (len <= res)
+ buf[len - 1] = '\0';
+
+ return res;
+ }
+ }
+
+ return -1;
+}
+
static int env_get_from_linear(const char *env, const char *name, char *buf,
unsigned len)
{
@@ -157,6 +192,17 @@ static int env_get_from_linear(const char *env, const char *name, char *buf,
if (name == NULL || *name == '\0')
return -1;
+ if (env == default_environment) {
+ int res = board_special_default_env_get(name, buf, len);
+
+ /*
+ * Board special default envs take precedence over the
+ * default_environment[] array.
+ */
+ if (res >= 0)
+ return res;
+ }
+
name_len = strlen(name);
for (p = env; *p != '\0'; p = end + 1) {
@@ -248,6 +294,41 @@ char *env_get_default(const char *name)
return NULL;
}
+static int import_board_special_default_envs(bool all, int nvars,
+ char * const vars[], int flags)
+{
+ int i;
+
+ for (i = 0; ; ++i) {
+ const char *name, *value;
+ struct env_entry e, *ep;
+
+ value = board_special_default_env(i, &name);
+ if (!value)
+ break;
+
+ if (!all) {
+ int j;
+
+ /* If name is not in vars, skip */
+
+ for (j = 0; j < nvars; ++j)
+ if (!strcmp(name, vars[j]))
+ break;
+ if (j == nvars)
+ continue;
+ }
+
+ e.key = name;
+ e.data = (char *)value;
+
+ if (!hsearch_r(e, ENV_ENTER, &ep, &env_htab, flags))
+ return -1;
+ }
+
+ return 0;
+}
+
void env_set_default(const char *s, int flags)
{
if (s) {
@@ -270,6 +351,12 @@ void env_set_default(const char *s, int flags)
return;
}
+ if (import_board_special_default_envs(true, 0, NULL, flags) < 0) {
+ pr_err("## Error: Board special default environment import failed: errno = %d\n",
+ errno);
+ return;
+ }
+
gd->flags |= GD_FLG_ENV_READY;
gd->flags |= GD_FLG_ENV_DEFAULT;
}
@@ -278,14 +365,20 @@ void env_set_default(const char *s, int flags)
/* [re]set individual variables to their value in the default environment */
int env_set_default_vars(int nvars, char * const vars[], int flags)
{
+ int res;
+
/*
* Special use-case: import from default environment
* (and use \0 as a separator)
*/
flags |= H_NOCLEAR | H_DEFAULT;
- return himport_r(&env_htab, default_environment,
- sizeof(default_environment), '\0',
- flags, 0, nvars, vars);
+ res = himport_r(&env_htab, default_environment,
+ sizeof(default_environment), '\0', flags, 0, nvars,
+ vars);
+ if (!res)
+ return res;
+
+ return import_board_special_default_envs(false, nvars, vars, flags);
}
/*
--
2.32.0
next prev parent reply other threads:[~2021-10-28 3:29 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-28 3:28 [PATCH 0/5] Board specific runtime determined default env Marek Behún
2021-10-28 3:28 ` [PATCH 1/5] env: Don't set ready flag if import failed in env_set_default() Marek Behún
2021-10-29 3:17 ` Simon Glass
2021-10-28 3:28 ` [PATCH 2/5] env: Fix env_get() when returning empty string using env_get_f() Marek Behún
2021-10-29 3:17 ` Simon Glass
2021-10-29 8:51 ` Marek Behún
2021-10-29 9:03 ` Pali Rohár
2021-10-31 13:07 ` Simon Glass
2021-10-31 15:27 ` Marek Behún
2021-10-28 3:28 ` [PATCH 3/5] env: Simplify env_get_default() Marek Behún
2021-10-29 3:17 ` Simon Glass
2021-10-28 3:28 ` Marek Behún [this message]
2021-10-29 3:17 ` [PATCH 4/5] env: Add support for board specific special default environment Simon Glass
2021-10-29 8:57 ` Marek Behún
2021-10-31 13:07 ` Simon Glass
2021-10-28 3:28 ` [PATCH 5/5] arm: mvebu: Espressobin: Use new API for setting default env at runtime Marek Behún
2021-10-29 3:17 ` Simon Glass
2021-10-31 20:15 ` Pali Rohár
2021-11-02 14:57 ` Simon Glass
2021-11-03 10:48 ` Pali Rohár
2021-10-29 3:17 ` [PATCH 0/5] Board specific runtime determined default env Simon Glass
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211028032810.18146-5-kabel@kernel.org \
--to=kabel@kernel.org \
--cc=marek.behun@nic.cz \
--cc=pali@kernel.org \
--cc=sjg@chromium.org \
--cc=sr@denx.de \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox