diff mbox series

[07/18] bootstd: Use the bootargs env var for changing the cmdline

Message ID 20230428191819.3070393-7-sjg@chromium.org
State Superseded
Delegated to: Bin Meng
Headers show
Series bootstd: Add a bootmeth for ChromiumOS on x86 | expand

Commit Message

Simon Glass April 28, 2023, 7:18 p.m. UTC
The "bootargs" environment variable is used to set the command-line
arguments to pass to the OS. Use this same mechanism with bootstd as well.
When the variable is updated, it is written to the current bootflow. When
the current bootflow is updated, the environment variable is updated too.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 boot/bootflow.c        | 59 ++++++++++++++++++++++++++++++++++++++++++
 cmd/bootflow.c         |  6 +++++
 include/env_callback.h |  6 +++--
 3 files changed, 69 insertions(+), 2 deletions(-)

Comments

Bin Meng May 15, 2023, 7:48 a.m. UTC | #1
Hi Simon,

On Sat, Apr 29, 2023 at 3:27 AM Simon Glass <sjg@chromium.org> wrote:
>
> The "bootargs" environment variable is used to set the command-line
> arguments to pass to the OS. Use this same mechanism with bootstd as well.
> When the variable is updated, it is written to the current bootflow. When
> the current bootflow is updated, the environment variable is updated too.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  boot/bootflow.c        | 59 ++++++++++++++++++++++++++++++++++++++++++
>  cmd/bootflow.c         |  6 +++++
>  include/env_callback.h |  6 +++--
>  3 files changed, 69 insertions(+), 2 deletions(-)
>
> diff --git a/boot/bootflow.c b/boot/bootflow.c
> index 487552fa28c..62b7f45ab27 100644
> --- a/boot/bootflow.c
> +++ b/boot/bootflow.c
> @@ -12,6 +12,7 @@
>  #include <bootmeth.h>
>  #include <bootstd.h>
>  #include <dm.h>
> +#include <env_internal.h>
>  #include <malloc.h>
>  #include <dm/device-internal.h>
>  #include <dm/uclass-internal.h>
> @@ -552,3 +553,61 @@ int bootflow_iter_check_system(const struct bootflow_iter *iter)
>
>         return -ENOTSUPP;
>  }
> +
> +/**
> + * bootflow_cmdline_set() - Set the command line for a bootflow
> + *
> + * @value: New command-line string
> + * Returns 0 if OK, -ENOENT if no current bootflow, -ENOMEM if out of memory
> + */
> +int bootflow_cmdline_set(struct bootflow *bflow, const char *value)
> +{
> +       char *cmdline = NULL;
> +
> +       if (value) {
> +               cmdline = strdup(value);
> +               if (!cmdline)
> +                       return -ENOMEM;
> +       }
> +
> +       free(bflow->cmdline);

What happens if this API gets called the very first time, with
flow->cmdline points to a random place?

> +       bflow->cmdline = cmdline;
> +
> +       return 0;
> +}
> +
> +#ifdef CONFIG_BOOTSTD_FULL
> +/**
> + * on_bootargs() - Update the cmdline of a bootflow
> + */
> +static int on_bootargs(const char *name, const char *value, enum env_op op,
> +                      int flags)
> +{
> +       struct bootstd_priv *std;
> +       struct bootflow *bflow;
> +       int ret;
> +
> +       ret = bootstd_get_priv(&std);
> +       if (ret)
> +               return 0;
> +       bflow = std->cur_bootflow;
> +       if (!bflow)
> +               return 0;
> +
> +       switch (op) {
> +       case env_op_create:
> +       case env_op_overwrite:
> +               ret = bootflow_cmdline_set(bflow, value);
> +               if (ret && ret != ENOENT)
> +                       return 1;
> +               return 0;
> +       case env_op_delete:
> +               bootflow_cmdline_set(bflow, NULL);
> +               fallthrough;
> +       default:
> +               return 0;
> +       }
> +}
> +U_BOOT_ENV_CALLBACK(bootargs, on_bootargs);
> +#endif
> +
> diff --git a/cmd/bootflow.c b/cmd/bootflow.c
> index 59d1bdc25b7..b20d5893632 100644
> --- a/cmd/bootflow.c
> +++ b/cmd/bootflow.c
> @@ -288,6 +288,12 @@ static int do_bootflow_select(struct cmd_tbl *cmdtp, int flag, int argc,
>                 return CMD_RET_FAILURE;
>         }
>         std->cur_bootflow = found;
> +       if (IS_ENABLED(CONFIG_BOOTSTD_FULL)) {
> +               if (env_set("bootargs", found->cmdline)) {
> +                       printf("Cannot set bootargs\n");
> +                       return CMD_RET_FAILURE;
> +               }
> +       }
>
>         return 0;
>  }
> diff --git a/include/env_callback.h b/include/env_callback.h
> index a9a14f2a84a..23bc650c162 100644
> --- a/include/env_callback.h
> +++ b/include/env_callback.h
> @@ -60,8 +60,10 @@
>  #define NET6_CALLBACKS
>  #endif
>
> -#ifdef CONFIG_BOOTSTD
> -#define BOOTSTD_CALLBACK       "bootmeths:bootmeths,"
> +#ifdef CONFIG_BOOTSTD_FULL
> +#define BOOTSTD_CALLBACK \
> +       "bootmeths:bootmeths," \
> +       "bootargs:bootargs,"
>  #else
>  #define BOOTSTD_CALLBACK
>  #endif
> --

Regards,
Bin
diff mbox series

Patch

diff --git a/boot/bootflow.c b/boot/bootflow.c
index 487552fa28c..62b7f45ab27 100644
--- a/boot/bootflow.c
+++ b/boot/bootflow.c
@@ -12,6 +12,7 @@ 
 #include <bootmeth.h>
 #include <bootstd.h>
 #include <dm.h>
+#include <env_internal.h>
 #include <malloc.h>
 #include <dm/device-internal.h>
 #include <dm/uclass-internal.h>
@@ -552,3 +553,61 @@  int bootflow_iter_check_system(const struct bootflow_iter *iter)
 
 	return -ENOTSUPP;
 }
+
+/**
+ * bootflow_cmdline_set() - Set the command line for a bootflow
+ *
+ * @value: New command-line string
+ * Returns 0 if OK, -ENOENT if no current bootflow, -ENOMEM if out of memory
+ */
+int bootflow_cmdline_set(struct bootflow *bflow, const char *value)
+{
+	char *cmdline = NULL;
+
+	if (value) {
+		cmdline = strdup(value);
+		if (!cmdline)
+			return -ENOMEM;
+	}
+
+	free(bflow->cmdline);
+	bflow->cmdline = cmdline;
+
+	return 0;
+}
+
+#ifdef CONFIG_BOOTSTD_FULL
+/**
+ * on_bootargs() - Update the cmdline of a bootflow
+ */
+static int on_bootargs(const char *name, const char *value, enum env_op op,
+		       int flags)
+{
+	struct bootstd_priv *std;
+	struct bootflow *bflow;
+	int ret;
+
+	ret = bootstd_get_priv(&std);
+	if (ret)
+		return 0;
+	bflow = std->cur_bootflow;
+	if (!bflow)
+		return 0;
+
+	switch (op) {
+	case env_op_create:
+	case env_op_overwrite:
+		ret = bootflow_cmdline_set(bflow, value);
+		if (ret && ret != ENOENT)
+			return 1;
+		return 0;
+	case env_op_delete:
+		bootflow_cmdline_set(bflow, NULL);
+		fallthrough;
+	default:
+		return 0;
+	}
+}
+U_BOOT_ENV_CALLBACK(bootargs, on_bootargs);
+#endif
+
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index 59d1bdc25b7..b20d5893632 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -288,6 +288,12 @@  static int do_bootflow_select(struct cmd_tbl *cmdtp, int flag, int argc,
 		return CMD_RET_FAILURE;
 	}
 	std->cur_bootflow = found;
+	if (IS_ENABLED(CONFIG_BOOTSTD_FULL)) {
+		if (env_set("bootargs", found->cmdline)) {
+			printf("Cannot set bootargs\n");
+			return CMD_RET_FAILURE;
+		}
+	}
 
 	return 0;
 }
diff --git a/include/env_callback.h b/include/env_callback.h
index a9a14f2a84a..23bc650c162 100644
--- a/include/env_callback.h
+++ b/include/env_callback.h
@@ -60,8 +60,10 @@ 
 #define NET6_CALLBACKS
 #endif
 
-#ifdef CONFIG_BOOTSTD
-#define BOOTSTD_CALLBACK	"bootmeths:bootmeths,"
+#ifdef CONFIG_BOOTSTD_FULL
+#define BOOTSTD_CALLBACK \
+	"bootmeths:bootmeths," \
+	"bootargs:bootargs,"
 #else
 #define BOOTSTD_CALLBACK
 #endif