* [RFC PATCH v2 0/2] Introduce fastboot oem board command
@ 2024-02-01 9:20 Alexey Romanov
2024-02-01 9:20 ` [RFC PATCH v2 1/2] fastboot: introduce 'oem board' subcommand Alexey Romanov
` (2 more replies)
0 siblings, 3 replies; 14+ messages in thread
From: Alexey Romanov @ 2024-02-01 9:20 UTC (permalink / raw)
To: sjg, hs, sean.anderson, dimorinny, mkorpershoek, patrick.delaunay
Cc: kernel, u-boot, Alexey Romanov
Changes v2 since v1 at [1]:
- Added an example of using the command as requsted
by Sean Anderson [2].
Links:
[1] https://lore.kernel.org/all/20231228152522.83291-1-avromanov@salutedevices.com/
[2] https://lore.kernel.org/all/72ac233d-c18d-4f57-bc66-451fe0bd2997@seco.com/
Alexey Romanov (2):
fastboot: introduce 'oem board' subcommand
board: ad401: example of fastboot oem board realization
board/amlogic/ad401/fastboot.c | 222 +++++++++++++++++++++++++++++++++
drivers/fastboot/Kconfig | 7 ++
drivers/fastboot/fb_command.c | 15 +++
include/fastboot.h | 1 +
4 files changed, 245 insertions(+)
create mode 100644 board/amlogic/ad401/fastboot.c
--
2.30.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC PATCH v2 1/2] fastboot: introduce 'oem board' subcommand
2024-02-01 9:20 [RFC PATCH v2 0/2] Introduce fastboot oem board command Alexey Romanov
@ 2024-02-01 9:20 ` Alexey Romanov
2024-02-15 9:14 ` Mattijs Korpershoek
2024-02-01 9:20 ` [RFC PATCH v2 2/2] board: ad401: example of fastboot oem board realization Alexey Romanov
2024-02-14 8:39 ` [RFC PATCH v2 0/2] Introduce fastboot oem board command Alexey Romanov
2 siblings, 1 reply; 14+ messages in thread
From: Alexey Romanov @ 2024-02-01 9:20 UTC (permalink / raw)
To: sjg, hs, sean.anderson, dimorinny, mkorpershoek, patrick.delaunay
Cc: kernel, u-boot, Alexey Romanov
Currently, fastboot protocol in U-Boot has no opportunity
to execute vendor custom code with verifed boot. This patch
introduce new fastboot subcommand fastboot oem board:<cmd>,
which allow to run custom oem_board function.
Default implementation is __weak. Vendor must redefine it in
board/ folder with his own logic.
For example, some vendors have their custom nand/emmc partition
flashing or erasing. Here some typical command for such use cases:
- flashing:
$ fastboot stage bootloader.img
$ fastboot oem board:write_bootloader
- erasing:
$ fastboot oem board:erase_env
Signed-off-by: Alexey Romanov <avromanov@salutedevices.com>
---
drivers/fastboot/Kconfig | 7 +++++++
drivers/fastboot/fb_command.c | 15 +++++++++++++++
include/fastboot.h | 1 +
3 files changed, 23 insertions(+)
diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig
index a4313d60a9..4d94391a76 100644
--- a/drivers/fastboot/Kconfig
+++ b/drivers/fastboot/Kconfig
@@ -241,6 +241,13 @@ config FASTBOOT_OEM_RUN
this feature if you are using verified boot, as it will allow an
attacker to bypass any restrictions you have in place.
+config FASTBOOT_OEM_BOARD
+ bool "Enable the 'oem board' command"
+ help
+ This extends the fastboot protocol with an "oem board" command. This
+ command allows running vendor custom code defined in board/ files.
+ Otherwise, it will do nothing and send fastboot fail.
+
endif # FASTBOOT
endmenu
diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
index 5fcadcdf50..2298815770 100644
--- a/drivers/fastboot/fb_command.c
+++ b/drivers/fastboot/fb_command.c
@@ -40,6 +40,7 @@ static void reboot_recovery(char *, char *);
static void oem_format(char *, char *);
static void oem_partconf(char *, char *);
static void oem_bootbus(char *, char *);
+static void oem_board(char *, char *);
static void run_ucmd(char *, char *);
static void run_acmd(char *, char *);
@@ -107,6 +108,10 @@ static const struct {
.command = "oem run",
.dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_RUN, (run_ucmd), (NULL))
},
+ [FASTBOOT_COMMAND_OEM_BOARD] = {
+ .command = "oem board",
+ .dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_BOARD, (oem_board), (NULL))
+ },
[FASTBOOT_COMMAND_UCMD] = {
.command = "UCmd",
.dispatch = CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT, (run_ucmd), (NULL))
@@ -490,3 +495,13 @@ static void __maybe_unused oem_bootbus(char *cmd_parameter, char *response)
else
fastboot_okay(NULL, response);
}
+
+void __weak fastboot_oem_board(char *cmd_parameter, void *data, u32 size, char *response)
+{
+ fastboot_fail("oem board function not defined", response);
+}
+
+static void __maybe_unused oem_board(char *cmd_parameter, char *response)
+{
+ fastboot_oem_board(cmd_parameter, fastboot_buf_addr, image_size, response);
+}
diff --git a/include/fastboot.h b/include/fastboot.h
index 296451f89d..06c1f26b6c 100644
--- a/include/fastboot.h
+++ b/include/fastboot.h
@@ -37,6 +37,7 @@ enum {
FASTBOOT_COMMAND_OEM_PARTCONF,
FASTBOOT_COMMAND_OEM_BOOTBUS,
FASTBOOT_COMMAND_OEM_RUN,
+ FASTBOOT_COMMAND_OEM_BOARD,
FASTBOOT_COMMAND_ACMD,
FASTBOOT_COMMAND_UCMD,
FASTBOOT_COMMAND_COUNT
--
2.30.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC PATCH v2 2/2] board: ad401: example of fastboot oem board realization
2024-02-01 9:20 [RFC PATCH v2 0/2] Introduce fastboot oem board command Alexey Romanov
2024-02-01 9:20 ` [RFC PATCH v2 1/2] fastboot: introduce 'oem board' subcommand Alexey Romanov
@ 2024-02-01 9:20 ` Alexey Romanov
2024-02-01 13:56 ` Dan Carpenter
2024-02-15 9:24 ` Mattijs Korpershoek
2024-02-14 8:39 ` [RFC PATCH v2 0/2] Introduce fastboot oem board command Alexey Romanov
2 siblings, 2 replies; 14+ messages in thread
From: Alexey Romanov @ 2024-02-01 9:20 UTC (permalink / raw)
To: sjg, hs, sean.anderson, dimorinny, mkorpershoek, patrick.delaunay
Cc: kernel, u-boot, Alexey Romanov
An example of how we use fastboot oeam board subcommand
for Sean Anderson.
1 - OEM_BOARD_WRITE_BOOTLOADER_CMD:
We use it for custom Amlogic bootloader + tpl
flashing protocol.
2 - OEM_BOARD_ERASE_CMD:
Custom logic for erasing the env-emulated partition,
which isn't in the mtd markup map.
Example of the script which completely flashes the device:
$ fastboot erase bootloader
$ fastboot stage u-boot.bin
$ fastboot oem board:write_bootloader
$ fastboot reboot-bootloader
$ fastboot oem board:erase_env
$ fastboot erase misc
$ fastboot erase super
$ fastboot flash super rootfs
$ fastboot reboot
Signed-off-by: Alexey Romanov <avromanov@salutedevices.com>
---
board/amlogic/ad401/fastboot.c | 222 +++++++++++++++++++++++++++++++++
1 file changed, 222 insertions(+)
create mode 100644 board/amlogic/ad401/fastboot.c
diff --git a/board/amlogic/ad401/fastboot.c b/board/amlogic/ad401/fastboot.c
new file mode 100644
index 0000000000..01da8efa5b
--- /dev/null
+++ b/board/amlogic/ad401/fastboot.c
@@ -0,0 +1,222 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2023 SaluteDevices, Inc.
+ */
+
+#include <common.h>
+#include <env.h>
+#include <fastboot.h>
+#include <nand.h>
+#include <asm/arch/nand.h>
+#include <jffs2/load_kernel.h>
+#include <linux/sizes.h>
+#include <linux/types.h>
+#include <linux/mtd/mtd.h>
+
+enum {
+ OEM_BOARD_ERASE_CMD,
+ OEM_BOARD_WRITE_BOOTLOADER_CMD,
+};
+
+struct defenv {
+ char *name;
+ char value[256];
+};
+
+static void save_defenv(struct defenv *e, size_t cnt)
+{
+ int i;
+
+ for (i = 0; i < cnt; i++) {
+ const char *env_val = env_get(e[i].name);
+
+ if (env_val)
+ strlcpy(e[i].value, env_val, sizeof(e[i].value));
+ else
+ e[i].value[0] = '\0';
+ }
+}
+
+static void set_defenv(struct defenv *e, size_t cnt)
+{
+ int i;
+
+ for (i = 0; i < cnt; i++)
+ env_set(e[i].name, e[i].value);
+}
+
+static int fastboot_erase_env(void)
+{
+ char *const defenv_names[] = { "lock", "mtdparts", "mtdids" };
+ struct defenv env[ARRAY_SIZE(defenv_names)];
+ int err, i;
+
+ for (i = 0; i < ARRAY_SIZE(env); i++)
+ env[i].name = defenv_names[i];
+
+ printf("ENV is being erased...\n");
+
+ /*
+ * Reset environment to the default, excluding 'lock' variable,
+ * because it reflects the fastboot's state after execution of
+ * 'flashing unlock' command, hence it must survive the env-erasing.
+ * Otherwise, further erase commands will fail on check_lock().
+ *
+ * Also, we have to save 'mtdparts' and 'mtdids' variables
+ * because they are necessary to obtain partition map.
+ */
+
+ save_defenv(env, ARRAY_SIZE(env));
+ env_set_default(NULL, 0);
+ set_defenv(env, ARRAY_SIZE(env));
+
+ err = env_save();
+ if (err) {
+ pr_err("Can't overwrite ENV-partition\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int fastboot_nand_write_tpl(struct mtd_info *mtd, void *buffer,
+ u32 offset, size_t size, int flags)
+{
+ int boot_cpy_num = meson_bootloader_copy_num(BOOT_TPL);
+ u64 size_per_copy = meson_bootloader_copy_size(mtd, BOOT_TPL);
+ int i;
+
+ for (i = 0; i < boot_cpy_num; i++) {
+ size_t retlen, len = size;
+ int ret;
+
+ ret = nand_write_skip_bad(mtd, offset + (i * size_per_copy),
+ &len, &retlen, offset + size_per_copy,
+ buffer, flags);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fastboot_nand_write_bl2(struct mtd_info *mtd, void *buffer,
+ u32 offset, size_t size, int flags)
+{
+ int boot_cpy_num = meson_bootloader_copy_num(BOOT_BL2);
+ u64 size_per_copy = meson_bootloader_copy_size(mtd, BOOT_BL2);
+ int i;
+
+ for (i = 0; i < boot_cpy_num; i++) {
+ int ret;
+
+ ret = meson_bootloader_write_bl2(mtd, buffer,
+ offset + (i * size_per_copy),
+ size, flags);
+ if (ret)
+ return ret;
+ }
+
+ return meson_bootloader_write_info_pages();
+}
+
+static int fastboot_nand_write_bootloader(void *buffer, u32 size)
+{
+ struct part_info *part;
+ struct mtd_info *mtd = NULL;
+ struct mtd_device *dev;
+ u8 pnum;
+ int ret;
+
+ if (size < BL2_SIZE)
+ return 0;
+
+ if (!buffer)
+ return -EINVAL;
+
+ ret = mtdparts_init();
+ if (ret) {
+ pr_err("Cannot initialize MTD partitions\n");
+ return ret;
+ }
+
+ ret = find_dev_and_part("bootloader", &dev, &pnum, &part);
+ if (ret) {
+ pr_err("cannot find 'bootloader' partition\n");
+ return ret;
+ }
+
+ mtd = get_nand_dev_by_index(dev->id->num);
+ if (!mtd)
+ return -EINVAL;
+
+ ret = fastboot_nand_write_bl2(mtd, buffer, part->offset,
+ BL2_SIZE, WITH_WR_VERIFY);
+ if (ret) {
+ pr_err("fastboot: failed to write BL2\n");
+ return ret;
+ }
+
+ ret = find_dev_and_part("tpl", &dev, &pnum, &part);
+ if (ret) {
+ pr_err("cannot find 'bootloader' partition\n");
+ return ret;
+ }
+
+ mtd = get_nand_dev_by_index(dev->id->num);
+ if (!mtd)
+ return -EINVAL;
+
+ ret = fastboot_nand_write_tpl(mtd, buffer + BL2_SIZE, part->offset,
+ size - BL2_SIZE, WITH_WR_VERIFY);
+ if (ret) {
+ pr_err("fastboot: failed to write TPL\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+int get_oem_board_command(const char *cmd)
+{
+ const char *oem_commands[] = {
+ [OEM_BOARD_ERASE_CMD] = "erase_env",
+ [OEM_BOARD_WRITE_BOOTLOADER_CMD] = "write_bootloader",
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(oem_commands); i++)
+ if (!strcmp(cmd, oem_commands[i]))
+ return i;
+
+ return -EINVAL;
+}
+
+void fastboot_oem_board(const char *cmd_parameter, void *data, u32 size,
+ char *response)
+{
+ char buf[128] = { 0 };
+ int ret, cmd;
+
+ cmd = get_oem_board_command(cmd_parameter);
+
+ switch (cmd) {
+ case OEM_BOARD_ERASE_CMD:
+ ret = fastboot_erase_env();
+ break;
+ case OEM_BOARD_WRITE_BOOTLOADER_CMD:
+ ret = fastboot_nand_write_bootloader(data, size);
+ break;
+ default:
+ snprintf(buf, sizeof(buf),
+ "Command 'oem board %s' not supported",
+ cmd_parameter);
+ fastboot_fail(buf, response);
+ return;
+ }
+
+ if (ret < 0)
+ fastboot_fail("Failed to erase env partition", response);
+ else
+ fastboot_okay(NULL, response);
+}
--
2.30.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 2/2] board: ad401: example of fastboot oem board realization
2024-02-01 9:20 ` [RFC PATCH v2 2/2] board: ad401: example of fastboot oem board realization Alexey Romanov
@ 2024-02-01 13:56 ` Dan Carpenter
2024-02-01 14:54 ` Alexey Romanov
2024-02-15 9:24 ` Mattijs Korpershoek
1 sibling, 1 reply; 14+ messages in thread
From: Dan Carpenter @ 2024-02-01 13:56 UTC (permalink / raw)
To: Alexey Romanov
Cc: sjg, hs, sean.anderson, dimorinny, mkorpershoek, patrick.delaunay,
kernel, u-boot
On Thu, Feb 01, 2024 at 12:20:27PM +0300, Alexey Romanov wrote:
> +static int fastboot_nand_write_tpl(struct mtd_info *mtd, void *buffer,
> + u32 offset, size_t size, int flags)
> +{
> + int boot_cpy_num = meson_bootloader_copy_num(BOOT_TPL);
> + u64 size_per_copy = meson_bootloader_copy_size(mtd, BOOT_TPL);
> + int i;
> +
> + for (i = 0; i < boot_cpy_num; i++) {
> + size_t retlen, len = size;
> + int ret;
> +
> + ret = nand_write_skip_bad(mtd, offset + (i * size_per_copy),
> + &len, &retlen, offset + size_per_copy,
^^^^^^^^^^^^^^^^^^^^^^
Sorry if I'm missing something obvious, but why is the limit
"offset + size_per_copy"? I would have expected it to be just
"size_per_copy" or maybe some kind of limit minus the offset...
> + buffer, flags);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
regards,
dan carpenter
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 2/2] board: ad401: example of fastboot oem board realization
2024-02-01 13:56 ` Dan Carpenter
@ 2024-02-01 14:54 ` Alexey Romanov
0 siblings, 0 replies; 14+ messages in thread
From: Alexey Romanov @ 2024-02-01 14:54 UTC (permalink / raw)
To: Dan Carpenter
Cc: sjg@chromium.org, hs@denx.de, sean.anderson@seco.com,
dimorinny@google.com, mkorpershoek@baylibre.com,
patrick.delaunay@foss.st.com, kernel, u-boot@lists.denx.de
Hi,
On Thu, Feb 01, 2024 at 04:56:34PM +0300, Dan Carpenter wrote:
> On Thu, Feb 01, 2024 at 12:20:27PM +0300, Alexey Romanov wrote:
> > +static int fastboot_nand_write_tpl(struct mtd_info *mtd, void *buffer,
> > + u32 offset, size_t size, int flags)
> > +{
> > + int boot_cpy_num = meson_bootloader_copy_num(BOOT_TPL);
> > + u64 size_per_copy = meson_bootloader_copy_size(mtd, BOOT_TPL);
> > + int i;
> > +
> > + for (i = 0; i < boot_cpy_num; i++) {
> > + size_t retlen, len = size;
> > + int ret;
> > +
> > + ret = nand_write_skip_bad(mtd, offset + (i * size_per_copy),
> > + &len, &retlen, offset + size_per_copy,
> ^^^^^^^^^^^^^^^^^^^^^^
> Sorry if I'm missing something obvious, but why is the limit
> "offset + size_per_copy"? I would have expected it to be just
> "size_per_copy" or maybe some kind of limit minus the offset...
Yeah, this is incorrect. Should be size_per_copy.
But this patch is just an example of realization.
>
> > + buffer, flags);
> > + if (ret)
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
>
> regards,
> dan carpenter
>
--
Thank you,
Alexey
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 0/2] Introduce fastboot oem board command
2024-02-01 9:20 [RFC PATCH v2 0/2] Introduce fastboot oem board command Alexey Romanov
2024-02-01 9:20 ` [RFC PATCH v2 1/2] fastboot: introduce 'oem board' subcommand Alexey Romanov
2024-02-01 9:20 ` [RFC PATCH v2 2/2] board: ad401: example of fastboot oem board realization Alexey Romanov
@ 2024-02-14 8:39 ` Alexey Romanov
2 siblings, 0 replies; 14+ messages in thread
From: Alexey Romanov @ 2024-02-14 8:39 UTC (permalink / raw)
To: sjg@chromium.org, hs@denx.de, sean.anderson@seco.com,
dimorinny@google.com, mkorpershoek@baylibre.com,
patrick.delaunay@foss.st.com
Cc: kernel, u-boot@lists.denx.de
Hello! Ping.
On Thu, Feb 01, 2024 at 12:20:25PM +0300, Alexey Romanov wrote:
> Changes v2 since v1 at [1]:
> - Added an example of using the command as requsted
> by Sean Anderson [2].
>
> Links:
> [1] https://lore.kernel.org/all/20231228152522.83291-1-avromanov@salutedevices.com/
> [2] https://lore.kernel.org/all/72ac233d-c18d-4f57-bc66-451fe0bd2997@seco.com/
>
> Alexey Romanov (2):
> fastboot: introduce 'oem board' subcommand
> board: ad401: example of fastboot oem board realization
>
> board/amlogic/ad401/fastboot.c | 222 +++++++++++++++++++++++++++++++++
> drivers/fastboot/Kconfig | 7 ++
> drivers/fastboot/fb_command.c | 15 +++
> include/fastboot.h | 1 +
> 4 files changed, 245 insertions(+)
> create mode 100644 board/amlogic/ad401/fastboot.c
>
> --
> 2.30.1
>
--
Thank you,
Alexey
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 1/2] fastboot: introduce 'oem board' subcommand
2024-02-01 9:20 ` [RFC PATCH v2 1/2] fastboot: introduce 'oem board' subcommand Alexey Romanov
@ 2024-02-15 9:14 ` Mattijs Korpershoek
2024-03-04 14:11 ` Alexey Romanov
2024-04-03 8:49 ` Alexey Romanov
0 siblings, 2 replies; 14+ messages in thread
From: Mattijs Korpershoek @ 2024-02-15 9:14 UTC (permalink / raw)
To: Alexey Romanov, sjg, hs, sean.anderson, dimorinny,
patrick.delaunay
Cc: kernel, u-boot, Alexey Romanov, Neil Armstrong
Hi Alexey,
Thank you for the patch.
On jeu., févr. 01, 2024 at 12:20, Alexey Romanov <avromanov@salutedevices.com> wrote:
> Currently, fastboot protocol in U-Boot has no opportunity
> to execute vendor custom code with verifed boot. This patch
> introduce new fastboot subcommand fastboot oem board:<cmd>,
> which allow to run custom oem_board function.
>
> Default implementation is __weak. Vendor must redefine it in
> board/ folder with his own logic.
>
> For example, some vendors have their custom nand/emmc partition
> flashing or erasing. Here some typical command for such use cases:
>
> - flashing:
>
> $ fastboot stage bootloader.img
> $ fastboot oem board:write_bootloader
>
> - erasing:
>
> $ fastboot oem board:erase_env
>
> Signed-off-by: Alexey Romanov <avromanov@salutedevices.com>
Sorry for the delay. I needed time to give this some thoughts and I
waited for Sean to chime as well on this.
I've heard from Neil that this might be related to:
https://github.com/superna9999/pyamlboot/pull/20
I think this can be useful. Not necessarily for writing custom
partitions, but I see this could be used for other things:
1. Provision SoC-specific fuses (serialno/mac addr) at the factory line
(for production devices)
Examples:
$ fastboot oem board:write_serialno ABCDEF
$ fastboot oem board:write_macaddr AA:BB:CC:DD:EE
2. Access secure storage (via an Trusted Application)
But both examples could also be in a fastboot flash format:
$ fastboot flash serialno ABCDEF
One concern I have is that U-Boot forks might use this command as
an excuse to not makes things generic.
I hope that others will chime in on this as well.
I'd like to discuss this more because once this command is in we cannot
remove it later.
> ---
> drivers/fastboot/Kconfig | 7 +++++++
> drivers/fastboot/fb_command.c | 15 +++++++++++++++
> include/fastboot.h | 1 +
> 3 files changed, 23 insertions(+)
>
> diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig
> index a4313d60a9..4d94391a76 100644
> --- a/drivers/fastboot/Kconfig
> +++ b/drivers/fastboot/Kconfig
> @@ -241,6 +241,13 @@ config FASTBOOT_OEM_RUN
> this feature if you are using verified boot, as it will allow an
> attacker to bypass any restrictions you have in place.
>
> +config FASTBOOT_OEM_BOARD
> + bool "Enable the 'oem board' command"
> + help
> + This extends the fastboot protocol with an "oem board" command. This
> + command allows running vendor custom code defined in board/ files.
> + Otherwise, it will do nothing and send fastboot fail.
If we move forward with this, please also document the new command in:
doc/android/fastboot.rst
> +
> endif # FASTBOOT
>
> endmenu
> diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
> index 5fcadcdf50..2298815770 100644
> --- a/drivers/fastboot/fb_command.c
> +++ b/drivers/fastboot/fb_command.c
> @@ -40,6 +40,7 @@ static void reboot_recovery(char *, char *);
> static void oem_format(char *, char *);
> static void oem_partconf(char *, char *);
> static void oem_bootbus(char *, char *);
> +static void oem_board(char *, char *);
> static void run_ucmd(char *, char *);
> static void run_acmd(char *, char *);
>
> @@ -107,6 +108,10 @@ static const struct {
> .command = "oem run",
> .dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_RUN, (run_ucmd), (NULL))
> },
> + [FASTBOOT_COMMAND_OEM_BOARD] = {
> + .command = "oem board",
> + .dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_BOARD, (oem_board), (NULL))
> + },
> [FASTBOOT_COMMAND_UCMD] = {
> .command = "UCmd",
> .dispatch = CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT, (run_ucmd), (NULL))
> @@ -490,3 +495,13 @@ static void __maybe_unused oem_bootbus(char *cmd_parameter, char *response)
> else
> fastboot_okay(NULL, response);
> }
> +
> +void __weak fastboot_oem_board(char *cmd_parameter, void *data, u32 size, char *response)
> +{
> + fastboot_fail("oem board function not defined", response);
> +}
> +
> +static void __maybe_unused oem_board(char *cmd_parameter, char *response)
> +{
> + fastboot_oem_board(cmd_parameter, fastboot_buf_addr, image_size, response);
> +}
> diff --git a/include/fastboot.h b/include/fastboot.h
> index 296451f89d..06c1f26b6c 100644
> --- a/include/fastboot.h
> +++ b/include/fastboot.h
> @@ -37,6 +37,7 @@ enum {
> FASTBOOT_COMMAND_OEM_PARTCONF,
> FASTBOOT_COMMAND_OEM_BOOTBUS,
> FASTBOOT_COMMAND_OEM_RUN,
> + FASTBOOT_COMMAND_OEM_BOARD,
> FASTBOOT_COMMAND_ACMD,
> FASTBOOT_COMMAND_UCMD,
> FASTBOOT_COMMAND_COUNT
> --
> 2.30.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 2/2] board: ad401: example of fastboot oem board realization
2024-02-01 9:20 ` [RFC PATCH v2 2/2] board: ad401: example of fastboot oem board realization Alexey Romanov
2024-02-01 13:56 ` Dan Carpenter
@ 2024-02-15 9:24 ` Mattijs Korpershoek
2024-03-04 14:03 ` Alexey Romanov
1 sibling, 1 reply; 14+ messages in thread
From: Mattijs Korpershoek @ 2024-02-15 9:24 UTC (permalink / raw)
To: Alexey Romanov, sjg, hs, sean.anderson, dimorinny,
patrick.delaunay
Cc: kernel, u-boot, Alexey Romanov
On jeu., févr. 01, 2024 at 12:20, Alexey Romanov <avromanov@salutedevices.com> wrote:
> An example of how we use fastboot oeam board subcommand
> for Sean Anderson.
>
> 1 - OEM_BOARD_WRITE_BOOTLOADER_CMD:
>
> We use it for custom Amlogic bootloader + tpl
> flashing protocol.
>
> 2 - OEM_BOARD_ERASE_CMD:
>
> Custom logic for erasing the env-emulated partition,
> which isn't in the mtd markup map.
>
> Example of the script which completely flashes the device:
>
> $ fastboot erase bootloader
> $ fastboot stage u-boot.bin
> $ fastboot oem board:write_bootloader
> $ fastboot reboot-bootloader
> $ fastboot oem board:erase_env
> $ fastboot erase misc
> $ fastboot erase super
> $ fastboot flash super rootfs
> $ fastboot reboot
>
> Signed-off-by: Alexey Romanov <avromanov@salutedevices.com>
> ---
> board/amlogic/ad401/fastboot.c | 222 +++++++++++++++++++++++++++++++++
> 1 file changed, 222 insertions(+)
> create mode 100644 board/amlogic/ad401/fastboot.c
>
> diff --git a/board/amlogic/ad401/fastboot.c b/board/amlogic/ad401/fastboot.c
> new file mode 100644
> index 0000000000..01da8efa5b
> --- /dev/null
> +++ b/board/amlogic/ad401/fastboot.c
> @@ -0,0 +1,222 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2023 SaluteDevices, Inc.
> + */
> +
> +#include <common.h>
> +#include <env.h>
> +#include <fastboot.h>
> +#include <nand.h>
> +#include <asm/arch/nand.h>
> +#include <jffs2/load_kernel.h>
> +#include <linux/sizes.h>
> +#include <linux/types.h>
> +#include <linux/mtd/mtd.h>
> +
> +enum {
> + OEM_BOARD_ERASE_CMD,
> + OEM_BOARD_WRITE_BOOTLOADER_CMD,
> +};
> +
> +struct defenv {
> + char *name;
> + char value[256];
> +};
> +
> +static void save_defenv(struct defenv *e, size_t cnt)
> +{
> + int i;
> +
> + for (i = 0; i < cnt; i++) {
> + const char *env_val = env_get(e[i].name);
> +
> + if (env_val)
> + strlcpy(e[i].value, env_val, sizeof(e[i].value));
> + else
> + e[i].value[0] = '\0';
> + }
> +}
> +
> +static void set_defenv(struct defenv *e, size_t cnt)
> +{
> + int i;
> +
> + for (i = 0; i < cnt; i++)
> + env_set(e[i].name, e[i].value);
> +}
> +
> +static int fastboot_erase_env(void)
> +{
> + char *const defenv_names[] = { "lock", "mtdparts", "mtdids" };
> + struct defenv env[ARRAY_SIZE(defenv_names)];
> + int err, i;
> +
> + for (i = 0; i < ARRAY_SIZE(env); i++)
> + env[i].name = defenv_names[i];
> +
> + printf("ENV is being erased...\n");
> +
> + /*
> + * Reset environment to the default, excluding 'lock' variable,
> + * because it reflects the fastboot's state after execution of
> + * 'flashing unlock' command, hence it must survive the env-erasing.
> + * Otherwise, further erase commands will fail on check_lock().
> + *
> + * Also, we have to save 'mtdparts' and 'mtdids' variables
> + * because they are necessary to obtain partition map.
> + */
> +
> + save_defenv(env, ARRAY_SIZE(env));
> + env_set_default(NULL, 0);
> + set_defenv(env, ARRAY_SIZE(env));
> +
> + err = env_save();
> + if (err) {
> + pr_err("Can't overwrite ENV-partition\n");
> + return err;
> + }
Hmm so the fastboot locked state is saved in the U-Boot environment.
There is probably a good reason for this (no secure storage for
example). But this does not feel board specific.
Wouldn't it be better if we could just run "fastboot erase bootenv" and
that the generic fastboot code does the right thing?
(which is env default, and ignoring some magic/specific variables)
> +
> + return 0;
> +}
> +
> +static int fastboot_nand_write_tpl(struct mtd_info *mtd, void *buffer,
> + u32 offset, size_t size, int flags)
> +{
> + int boot_cpy_num = meson_bootloader_copy_num(BOOT_TPL);
> + u64 size_per_copy = meson_bootloader_copy_size(mtd, BOOT_TPL);
> + int i;
> +
> + for (i = 0; i < boot_cpy_num; i++) {
> + size_t retlen, len = size;
> + int ret;
> +
> + ret = nand_write_skip_bad(mtd, offset + (i * size_per_copy),
> + &len, &retlen, offset + size_per_copy,
> + buffer, flags);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int fastboot_nand_write_bl2(struct mtd_info *mtd, void *buffer,
> + u32 offset, size_t size, int flags)
> +{
> + int boot_cpy_num = meson_bootloader_copy_num(BOOT_BL2);
> + u64 size_per_copy = meson_bootloader_copy_size(mtd, BOOT_BL2);
> + int i;
> +
> + for (i = 0; i < boot_cpy_num; i++) {
> + int ret;
> +
> + ret = meson_bootloader_write_bl2(mtd, buffer,
> + offset + (i * size_per_copy),
> + size, flags);
> + if (ret)
> + return ret;
> + }
> +
> + return meson_bootloader_write_info_pages();
> +}
> +
> +static int fastboot_nand_write_bootloader(void *buffer, u32 size)
> +{
> + struct part_info *part;
> + struct mtd_info *mtd = NULL;
> + struct mtd_device *dev;
> + u8 pnum;
> + int ret;
> +
> + if (size < BL2_SIZE)
> + return 0;
> +
> + if (!buffer)
> + return -EINVAL;
> +
> + ret = mtdparts_init();
> + if (ret) {
> + pr_err("Cannot initialize MTD partitions\n");
> + return ret;
> + }
> +
> + ret = find_dev_and_part("bootloader", &dev, &pnum, &part);
> + if (ret) {
> + pr_err("cannot find 'bootloader' partition\n");
> + return ret;
> + }
> +
> + mtd = get_nand_dev_by_index(dev->id->num);
> + if (!mtd)
> + return -EINVAL;
> +
> + ret = fastboot_nand_write_bl2(mtd, buffer, part->offset,
> + BL2_SIZE, WITH_WR_VERIFY);
> + if (ret) {
> + pr_err("fastboot: failed to write BL2\n");
> + return ret;
> + }
> +
> + ret = find_dev_and_part("tpl", &dev, &pnum, &part);
> + if (ret) {
> + pr_err("cannot find 'bootloader' partition\n");
> + return ret;
> + }
> +
> + mtd = get_nand_dev_by_index(dev->id->num);
> + if (!mtd)
> + return -EINVAL;
> +
> + ret = fastboot_nand_write_tpl(mtd, buffer + BL2_SIZE, part->offset,
> + size - BL2_SIZE, WITH_WR_VERIFY);
> + if (ret) {
> + pr_err("fastboot: failed to write TPL\n");
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +int get_oem_board_command(const char *cmd)
> +{
> + const char *oem_commands[] = {
> + [OEM_BOARD_ERASE_CMD] = "erase_env",
> + [OEM_BOARD_WRITE_BOOTLOADER_CMD] = "write_bootloader",
> + };
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(oem_commands); i++)
> + if (!strcmp(cmd, oem_commands[i]))
> + return i;
> +
> + return -EINVAL;
> +}
> +
> +void fastboot_oem_board(const char *cmd_parameter, void *data, u32 size,
> + char *response)
> +{
> + char buf[128] = { 0 };
> + int ret, cmd;
> +
> + cmd = get_oem_board_command(cmd_parameter);
> +
> + switch (cmd) {
> + case OEM_BOARD_ERASE_CMD:
> + ret = fastboot_erase_env();
> + break;
> + case OEM_BOARD_WRITE_BOOTLOADER_CMD:
> + ret = fastboot_nand_write_bootloader(data, size);
> + break;
> + default:
> + snprintf(buf, sizeof(buf),
> + "Command 'oem board %s' not supported",
> + cmd_parameter);
> + fastboot_fail(buf, response);
> + return;
> + }
> +
> + if (ret < 0)
> + fastboot_fail("Failed to erase env partition", response);
> + else
> + fastboot_okay(NULL, response);
> +}
> --
> 2.30.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 2/2] board: ad401: example of fastboot oem board realization
2024-02-15 9:24 ` Mattijs Korpershoek
@ 2024-03-04 14:03 ` Alexey Romanov
2024-04-05 9:02 ` Mattijs Korpershoek
0 siblings, 1 reply; 14+ messages in thread
From: Alexey Romanov @ 2024-03-04 14:03 UTC (permalink / raw)
To: Mattijs Korpershoek
Cc: sjg@chromium.org, hs@denx.de, sean.anderson@seco.com,
dimorinny@google.com, patrick.delaunay@foss.st.com, kernel,
u-boot@lists.denx.de
Hello Mattijs,
On Thu, Feb 15, 2024 at 10:24:11AM +0100, Mattijs Korpershoek wrote:
> On jeu., f'evr. 01, 2024 at 12:20, Alexey Romanov <avromanov@salutedevices.com> wrote:
>
> > An example of how we use fastboot oeam board subcommand
> > for Sean Anderson.
> >
> > 1 - OEM_BOARD_WRITE_BOOTLOADER_CMD:
> >
> > We use it for custom Amlogic bootloader + tpl
> > flashing protocol.
> >
> > 2 - OEM_BOARD_ERASE_CMD:
> >
> > Custom logic for erasing the env-emulated partition,
> > which isn't in the mtd markup map.
> >
> > Example of the script which completely flashes the device:
> >
> > $ fastboot erase bootloader
> > $ fastboot stage u-boot.bin
> > $ fastboot oem board:write_bootloader
> > $ fastboot reboot-bootloader
> > $ fastboot oem board:erase_env
> > $ fastboot erase misc
> > $ fastboot erase super
> > $ fastboot flash super rootfs
> > $ fastboot reboot
> >
> > Signed-off-by: Alexey Romanov <avromanov@salutedevices.com>
> > ---
> > board/amlogic/ad401/fastboot.c | 222 +++++++++++++++++++++++++++++++++
> > 1 file changed, 222 insertions(+)
> > create mode 100644 board/amlogic/ad401/fastboot.c
> >
> > diff --git a/board/amlogic/ad401/fastboot.c b/board/amlogic/ad401/fastboot.c
> > new file mode 100644
> > index 0000000000..01da8efa5b
> > --- /dev/null
> > +++ b/board/amlogic/ad401/fastboot.c
> > @@ -0,0 +1,222 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * (C) Copyright 2023 SaluteDevices, Inc.
> > + */
> > +
> > +#include <common.h>
> > +#include <env.h>
> > +#include <fastboot.h>
> > +#include <nand.h>
> > +#include <asm/arch/nand.h>
> > +#include <jffs2/load_kernel.h>
> > +#include <linux/sizes.h>
> > +#include <linux/types.h>
> > +#include <linux/mtd/mtd.h>
> > +
> > +enum {
> > + OEM_BOARD_ERASE_CMD,
> > + OEM_BOARD_WRITE_BOOTLOADER_CMD,
> > +};
> > +
> > +struct defenv {
> > + char *name;
> > + char value[256];
> > +};
> > +
> > +static void save_defenv(struct defenv *e, size_t cnt)
> > +{
> > + int i;
> > +
> > + for (i = 0; i < cnt; i++) {
> > + const char *env_val = env_get(e[i].name);
> > +
> > + if (env_val)
> > + strlcpy(e[i].value, env_val, sizeof(e[i].value));
> > + else
> > + e[i].value[0] = '\0';
> > + }
> > +}
> > +
> > +static void set_defenv(struct defenv *e, size_t cnt)
> > +{
> > + int i;
> > +
> > + for (i = 0; i < cnt; i++)
> > + env_set(e[i].name, e[i].value);
> > +}
> > +
> > +static int fastboot_erase_env(void)
> > +{
> > + char *const defenv_names[] = { "lock", "mtdparts", "mtdids" };
> > + struct defenv env[ARRAY_SIZE(defenv_names)];
> > + int err, i;
> > +
> > + for (i = 0; i < ARRAY_SIZE(env); i++)
> > + env[i].name = defenv_names[i];
> > +
> > + printf("ENV is being erased...\n");
> > +
> > + /*
> > + * Reset environment to the default, excluding 'lock' variable,
> > + * because it reflects the fastboot's state after execution of
> > + * 'flashing unlock' command, hence it must survive the env-erasing.
> > + * Otherwise, further erase commands will fail on check_lock().
> > + *
> > + * Also, we have to save 'mtdparts' and 'mtdids' variables
> > + * because they are necessary to obtain partition map.
> > + */
> > +
> > + save_defenv(env, ARRAY_SIZE(env));
> > + env_set_default(NULL, 0);
> > + set_defenv(env, ARRAY_SIZE(env));
> > +
> > + err = env_save();
> > + if (err) {
> > + pr_err("Can't overwrite ENV-partition\n");
> > + return err;
> > + }
>
> Hmm so the fastboot locked state is saved in the U-Boot environment.
> There is probably a good reason for this (no secure storage for
> example). But this does not feel board specific.
>
> Wouldn't it be better if we could just run "fastboot erase bootenv" and
> that the generic fastboot code does the right thing?
Are you proposing to modify the code of fastboot in such a way
that if user send 'erase bootenv' string, then we call generic
function to cleanup environment, instead of try to search (and erase)
in partition schema 'bootenv' partition?
> (which is env default, and ignoring some magic/specific variables)
>
> > +
> > + return 0;
> > +}
> > +
> > +static int fastboot_nand_write_tpl(struct mtd_info *mtd, void *buffer,
> > + u32 offset, size_t size, int flags)
> > +{
> > + int boot_cpy_num = meson_bootloader_copy_num(BOOT_TPL);
> > + u64 size_per_copy = meson_bootloader_copy_size(mtd, BOOT_TPL);
> > + int i;
> > +
> > + for (i = 0; i < boot_cpy_num; i++) {
> > + size_t retlen, len = size;
> > + int ret;
> > +
> > + ret = nand_write_skip_bad(mtd, offset + (i * size_per_copy),
> > + &len, &retlen, offset + size_per_copy,
> > + buffer, flags);
> > + if (ret)
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int fastboot_nand_write_bl2(struct mtd_info *mtd, void *buffer,
> > + u32 offset, size_t size, int flags)
> > +{
> > + int boot_cpy_num = meson_bootloader_copy_num(BOOT_BL2);
> > + u64 size_per_copy = meson_bootloader_copy_size(mtd, BOOT_BL2);
> > + int i;
> > +
> > + for (i = 0; i < boot_cpy_num; i++) {
> > + int ret;
> > +
> > + ret = meson_bootloader_write_bl2(mtd, buffer,
> > + offset + (i * size_per_copy),
> > + size, flags);
> > + if (ret)
> > + return ret;
> > + }
> > +
> > + return meson_bootloader_write_info_pages();
> > +}
> > +
> > +static int fastboot_nand_write_bootloader(void *buffer, u32 size)
> > +{
> > + struct part_info *part;
> > + struct mtd_info *mtd = NULL;
> > + struct mtd_device *dev;
> > + u8 pnum;
> > + int ret;
> > +
> > + if (size < BL2_SIZE)
> > + return 0;
> > +
> > + if (!buffer)
> > + return -EINVAL;
> > +
> > + ret = mtdparts_init();
> > + if (ret) {
> > + pr_err("Cannot initialize MTD partitions\n");
> > + return ret;
> > + }
> > +
> > + ret = find_dev_and_part("bootloader", &dev, &pnum, &part);
> > + if (ret) {
> > + pr_err("cannot find 'bootloader' partition\n");
> > + return ret;
> > + }
> > +
> > + mtd = get_nand_dev_by_index(dev->id->num);
> > + if (!mtd)
> > + return -EINVAL;
> > +
> > + ret = fastboot_nand_write_bl2(mtd, buffer, part->offset,
> > + BL2_SIZE, WITH_WR_VERIFY);
> > + if (ret) {
> > + pr_err("fastboot: failed to write BL2\n");
> > + return ret;
> > + }
> > +
> > + ret = find_dev_and_part("tpl", &dev, &pnum, &part);
> > + if (ret) {
> > + pr_err("cannot find 'bootloader' partition\n");
> > + return ret;
> > + }
> > +
> > + mtd = get_nand_dev_by_index(dev->id->num);
> > + if (!mtd)
> > + return -EINVAL;
> > +
> > + ret = fastboot_nand_write_tpl(mtd, buffer + BL2_SIZE, part->offset,
> > + size - BL2_SIZE, WITH_WR_VERIFY);
> > + if (ret) {
> > + pr_err("fastboot: failed to write TPL\n");
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +int get_oem_board_command(const char *cmd)
> > +{
> > + const char *oem_commands[] = {
> > + [OEM_BOARD_ERASE_CMD] = "erase_env",
> > + [OEM_BOARD_WRITE_BOOTLOADER_CMD] = "write_bootloader",
> > + };
> > + int i;
> > +
> > + for (i = 0; i < ARRAY_SIZE(oem_commands); i++)
> > + if (!strcmp(cmd, oem_commands[i]))
> > + return i;
> > +
> > + return -EINVAL;
> > +}
> > +
> > +void fastboot_oem_board(const char *cmd_parameter, void *data, u32 size,
> > + char *response)
> > +{
> > + char buf[128] = { 0 };
> > + int ret, cmd;
> > +
> > + cmd = get_oem_board_command(cmd_parameter);
> > +
> > + switch (cmd) {
> > + case OEM_BOARD_ERASE_CMD:
> > + ret = fastboot_erase_env();
> > + break;
> > + case OEM_BOARD_WRITE_BOOTLOADER_CMD:
> > + ret = fastboot_nand_write_bootloader(data, size);
> > + break;
> > + default:
> > + snprintf(buf, sizeof(buf),
> > + "Command 'oem board %s' not supported",
> > + cmd_parameter);
> > + fastboot_fail(buf, response);
> > + return;
> > + }
> > +
> > + if (ret < 0)
> > + fastboot_fail("Failed to erase env partition", response);
> > + else
> > + fastboot_okay(NULL, response);
> > +}
> > --
> > 2.30.1
--
Thank you,
Alexey
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 1/2] fastboot: introduce 'oem board' subcommand
2024-02-15 9:14 ` Mattijs Korpershoek
@ 2024-03-04 14:11 ` Alexey Romanov
2024-04-05 9:01 ` Mattijs Korpershoek
2024-04-03 8:49 ` Alexey Romanov
1 sibling, 1 reply; 14+ messages in thread
From: Alexey Romanov @ 2024-03-04 14:11 UTC (permalink / raw)
To: Mattijs Korpershoek
Cc: sjg@chromium.org, hs@denx.de, sean.anderson@seco.com,
dimorinny@google.com, patrick.delaunay@foss.st.com, kernel,
u-boot@lists.denx.de, Neil Armstrong
Hello,
On Thu, Feb 15, 2024 at 10:14:13AM +0100, Mattijs Korpershoek wrote:
> Hi Alexey,
>
> Thank you for the patch.
>
> On jeu., f'evr. 01, 2024 at 12:20, Alexey Romanov <avromanov@salutedevices.com> wrote:
>
> > Currently, fastboot protocol in U-Boot has no opportunity
> > to execute vendor custom code with verifed boot. This patch
> > introduce new fastboot subcommand fastboot oem board:<cmd>,
> > which allow to run custom oem_board function.
> >
> > Default implementation is __weak. Vendor must redefine it in
> > board/ folder with his own logic.
> >
> > For example, some vendors have their custom nand/emmc partition
> > flashing or erasing. Here some typical command for such use cases:
> >
> > - flashing:
> >
> > $ fastboot stage bootloader.img
> > $ fastboot oem board:write_bootloader
> >
> > - erasing:
> >
> > $ fastboot oem board:erase_env
> >
> > Signed-off-by: Alexey Romanov <avromanov@salutedevices.com>
>
> Sorry for the delay. I needed time to give this some thoughts and I
> waited for Sean to chime as well on this.
>
> I've heard from Neil that this might be related to:
> https://github.com/superna9999/pyamlboot/pull/20
Yeah, pyamlboot also uses the same 'bootloader' partition flashing
scheme as I present in the patch 2. This is custom Amlogic protocol.
>
> I think this can be useful. Not necessarily for writing custom
> partitions, but I see this could be used for other things:
>
> 1. Provision SoC-specific fuses (serialno/mac addr) at the factory line
> (for production devices)
> Examples:
> $ fastboot oem board:write_serialno ABCDEF
> $ fastboot oem board:write_macaddr AA:BB:CC:DD:EE
>
> 2. Access secure storage (via an Trusted Application)
Agree, you are completely right.
>
> But both examples could also be in a fastboot flash format:
> $ fastboot flash serialno ABCDEF
But this case requires to 'serialno' partition definition in schema?
I didn't fully understand you.
>
> One concern I have is that U-Boot forks might use this command as
> an excuse to not makes things generic.
>
> I hope that others will chime in on this as well.
> I'd like to discuss this more because once this command is in we cannot
> remove it later.
>
> > ---
> > drivers/fastboot/Kconfig | 7 +++++++
> > drivers/fastboot/fb_command.c | 15 +++++++++++++++
> > include/fastboot.h | 1 +
> > 3 files changed, 23 insertions(+)
> >
> > diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig
> > index a4313d60a9..4d94391a76 100644
> > --- a/drivers/fastboot/Kconfig
> > +++ b/drivers/fastboot/Kconfig
> > @@ -241,6 +241,13 @@ config FASTBOOT_OEM_RUN
> > this feature if you are using verified boot, as it will allow an
> > attacker to bypass any restrictions you have in place.
> >
> > +config FASTBOOT_OEM_BOARD
> > + bool "Enable the 'oem board' command"
> > + help
> > + This extends the fastboot protocol with an "oem board" command. This
> > + command allows running vendor custom code defined in board/ files.
> > + Otherwise, it will do nothing and send fastboot fail.
>
> If we move forward with this, please also document the new command in:
> doc/android/fastboot.rst
>
> > +
> > endif # FASTBOOT
> >
> > endmenu
> > diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
> > index 5fcadcdf50..2298815770 100644
> > --- a/drivers/fastboot/fb_command.c
> > +++ b/drivers/fastboot/fb_command.c
> > @@ -40,6 +40,7 @@ static void reboot_recovery(char *, char *);
> > static void oem_format(char *, char *);
> > static void oem_partconf(char *, char *);
> > static void oem_bootbus(char *, char *);
> > +static void oem_board(char *, char *);
> > static void run_ucmd(char *, char *);
> > static void run_acmd(char *, char *);
> >
> > @@ -107,6 +108,10 @@ static const struct {
> > .command = "oem run",
> > .dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_RUN, (run_ucmd), (NULL))
> > },
> > + [FASTBOOT_COMMAND_OEM_BOARD] = {
> > + .command = "oem board",
> > + .dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_BOARD, (oem_board), (NULL))
> > + },
> > [FASTBOOT_COMMAND_UCMD] = {
> > .command = "UCmd",
> > .dispatch = CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT, (run_ucmd), (NULL))
> > @@ -490,3 +495,13 @@ static void __maybe_unused oem_bootbus(char *cmd_parameter, char *response)
> > else
> > fastboot_okay(NULL, response);
> > }
> > +
> > +void __weak fastboot_oem_board(char *cmd_parameter, void *data, u32 size, char *response)
> > +{
> > + fastboot_fail("oem board function not defined", response);
> > +}
> > +
> > +static void __maybe_unused oem_board(char *cmd_parameter, char *response)
> > +{
> > + fastboot_oem_board(cmd_parameter, fastboot_buf_addr, image_size, response);
> > +}
> > diff --git a/include/fastboot.h b/include/fastboot.h
> > index 296451f89d..06c1f26b6c 100644
> > --- a/include/fastboot.h
> > +++ b/include/fastboot.h
> > @@ -37,6 +37,7 @@ enum {
> > FASTBOOT_COMMAND_OEM_PARTCONF,
> > FASTBOOT_COMMAND_OEM_BOOTBUS,
> > FASTBOOT_COMMAND_OEM_RUN,
> > + FASTBOOT_COMMAND_OEM_BOARD,
> > FASTBOOT_COMMAND_ACMD,
> > FASTBOOT_COMMAND_UCMD,
> > FASTBOOT_COMMAND_COUNT
> > --
> > 2.30.1
--
Thank you,
Alexey
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 1/2] fastboot: introduce 'oem board' subcommand
2024-02-15 9:14 ` Mattijs Korpershoek
2024-03-04 14:11 ` Alexey Romanov
@ 2024-04-03 8:49 ` Alexey Romanov
2024-04-05 8:58 ` Mattijs Korpershoek
1 sibling, 1 reply; 14+ messages in thread
From: Alexey Romanov @ 2024-04-03 8:49 UTC (permalink / raw)
To: Mattijs Korpershoek
Cc: sjg@chromium.org, hs@denx.de, sean.anderson@seco.com,
dimorinny@google.com, patrick.delaunay@foss.st.com, kernel,
u-boot@lists.denx.de, Neil Armstrong
Hello Mattijs,
is there any feedback?
On Thu, Feb 15, 2024 at 10:14:13AM +0100, Mattijs Korpershoek wrote:
> Hi Alexey,
>
> Thank you for the patch.
>
> On jeu., f'evr. 01, 2024 at 12:20, Alexey Romanov <avromanov@salutedevices.com> wrote:
>
> > Currently, fastboot protocol in U-Boot has no opportunity
> > to execute vendor custom code with verifed boot. This patch
> > introduce new fastboot subcommand fastboot oem board:<cmd>,
> > which allow to run custom oem_board function.
> >
> > Default implementation is __weak. Vendor must redefine it in
> > board/ folder with his own logic.
> >
> > For example, some vendors have their custom nand/emmc partition
> > flashing or erasing. Here some typical command for such use cases:
> >
> > - flashing:
> >
> > $ fastboot stage bootloader.img
> > $ fastboot oem board:write_bootloader
> >
> > - erasing:
> >
> > $ fastboot oem board:erase_env
> >
> > Signed-off-by: Alexey Romanov <avromanov@salutedevices.com>
>
> Sorry for the delay. I needed time to give this some thoughts and I
> waited for Sean to chime as well on this.
>
> I've heard from Neil that this might be related to:
> https://github.com/superna9999/pyamlboot/pull/20
>
> I think this can be useful. Not necessarily for writing custom
> partitions, but I see this could be used for other things:
>
> 1. Provision SoC-specific fuses (serialno/mac addr) at the factory line
> (for production devices)
> Examples:
> $ fastboot oem board:write_serialno ABCDEF
> $ fastboot oem board:write_macaddr AA:BB:CC:DD:EE
>
> 2. Access secure storage (via an Trusted Application)
>
> But both examples could also be in a fastboot flash format:
> $ fastboot flash serialno ABCDEF
>
> One concern I have is that U-Boot forks might use this command as
> an excuse to not makes things generic.
>
> I hope that others will chime in on this as well.
> I'd like to discuss this more because once this command is in we cannot
> remove it later.
>
> > ---
> > drivers/fastboot/Kconfig | 7 +++++++
> > drivers/fastboot/fb_command.c | 15 +++++++++++++++
> > include/fastboot.h | 1 +
> > 3 files changed, 23 insertions(+)
> >
> > diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig
> > index a4313d60a9..4d94391a76 100644
> > --- a/drivers/fastboot/Kconfig
> > +++ b/drivers/fastboot/Kconfig
> > @@ -241,6 +241,13 @@ config FASTBOOT_OEM_RUN
> > this feature if you are using verified boot, as it will allow an
> > attacker to bypass any restrictions you have in place.
> >
> > +config FASTBOOT_OEM_BOARD
> > + bool "Enable the 'oem board' command"
> > + help
> > + This extends the fastboot protocol with an "oem board" command. This
> > + command allows running vendor custom code defined in board/ files.
> > + Otherwise, it will do nothing and send fastboot fail.
>
> If we move forward with this, please also document the new command in:
> doc/android/fastboot.rst
>
> > +
> > endif # FASTBOOT
> >
> > endmenu
> > diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
> > index 5fcadcdf50..2298815770 100644
> > --- a/drivers/fastboot/fb_command.c
> > +++ b/drivers/fastboot/fb_command.c
> > @@ -40,6 +40,7 @@ static void reboot_recovery(char *, char *);
> > static void oem_format(char *, char *);
> > static void oem_partconf(char *, char *);
> > static void oem_bootbus(char *, char *);
> > +static void oem_board(char *, char *);
> > static void run_ucmd(char *, char *);
> > static void run_acmd(char *, char *);
> >
> > @@ -107,6 +108,10 @@ static const struct {
> > .command = "oem run",
> > .dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_RUN, (run_ucmd), (NULL))
> > },
> > + [FASTBOOT_COMMAND_OEM_BOARD] = {
> > + .command = "oem board",
> > + .dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_BOARD, (oem_board), (NULL))
> > + },
> > [FASTBOOT_COMMAND_UCMD] = {
> > .command = "UCmd",
> > .dispatch = CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT, (run_ucmd), (NULL))
> > @@ -490,3 +495,13 @@ static void __maybe_unused oem_bootbus(char *cmd_parameter, char *response)
> > else
> > fastboot_okay(NULL, response);
> > }
> > +
> > +void __weak fastboot_oem_board(char *cmd_parameter, void *data, u32 size, char *response)
> > +{
> > + fastboot_fail("oem board function not defined", response);
> > +}
> > +
> > +static void __maybe_unused oem_board(char *cmd_parameter, char *response)
> > +{
> > + fastboot_oem_board(cmd_parameter, fastboot_buf_addr, image_size, response);
> > +}
> > diff --git a/include/fastboot.h b/include/fastboot.h
> > index 296451f89d..06c1f26b6c 100644
> > --- a/include/fastboot.h
> > +++ b/include/fastboot.h
> > @@ -37,6 +37,7 @@ enum {
> > FASTBOOT_COMMAND_OEM_PARTCONF,
> > FASTBOOT_COMMAND_OEM_BOOTBUS,
> > FASTBOOT_COMMAND_OEM_RUN,
> > + FASTBOOT_COMMAND_OEM_BOARD,
> > FASTBOOT_COMMAND_ACMD,
> > FASTBOOT_COMMAND_UCMD,
> > FASTBOOT_COMMAND_COUNT
> > --
> > 2.30.1
--
Thank you,
Alexey
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 1/2] fastboot: introduce 'oem board' subcommand
2024-04-03 8:49 ` Alexey Romanov
@ 2024-04-05 8:58 ` Mattijs Korpershoek
0 siblings, 0 replies; 14+ messages in thread
From: Mattijs Korpershoek @ 2024-04-05 8:58 UTC (permalink / raw)
To: Alexey Romanov
Cc: sjg@chromium.org, hs@denx.de, sean.anderson@seco.com,
dimorinny@google.com, patrick.delaunay@foss.st.com, kernel,
u-boot@lists.denx.de, Neil Armstrong
Hi Alexey,
On mer., avril 03, 2024 at 08:49, Alexey Romanov <avromanov@salutedevices.com> wrote:
> Hello Mattijs,
> is there any feedback?
Sorry for the late reply. I was both swamped with other work and awaiting.
feedback from others.
I don't have strong enough arguments to state that this is not useful to
others, I have re-considered this and I'm willing to pick it up.
Please rebase, as this no longer applies.
Also see some review comments below
>
> On Thu, Feb 15, 2024 at 10:14:13AM +0100, Mattijs Korpershoek wrote:
>> Hi Alexey,
>>
>> Thank you for the patch.
>>
>> On jeu., f'evr. 01, 2024 at 12:20, Alexey Romanov <avromanov@salutedevices.com> wrote:
>>
>> > Currently, fastboot protocol in U-Boot has no opportunity
>> > to execute vendor custom code with verifed boot. This patch
>> > introduce new fastboot subcommand fastboot oem board:<cmd>,
>> > which allow to run custom oem_board function.
>> >
>> > Default implementation is __weak. Vendor must redefine it in
>> > board/ folder with his own logic.
>> >
>> > For example, some vendors have their custom nand/emmc partition
>> > flashing or erasing. Here some typical command for such use cases:
>> >
>> > - flashing:
>> >
>> > $ fastboot stage bootloader.img
>> > $ fastboot oem board:write_bootloader
>> >
>> > - erasing:
>> >
>> > $ fastboot oem board:erase_env
>> >
>> > Signed-off-by: Alexey Romanov <avromanov@salutedevices.com>
>>
>> Sorry for the delay. I needed time to give this some thoughts and I
>> waited for Sean to chime as well on this.
>>
>> I've heard from Neil that this might be related to:
>> https://github.com/superna9999/pyamlboot/pull/20
>>
>> I think this can be useful. Not necessarily for writing custom
>> partitions, but I see this could be used for other things:
>>
>> 1. Provision SoC-specific fuses (serialno/mac addr) at the factory line
>> (for production devices)
>> Examples:
>> $ fastboot oem board:write_serialno ABCDEF
>> $ fastboot oem board:write_macaddr AA:BB:CC:DD:EE
>>
>> 2. Access secure storage (via an Trusted Application)
>>
>> But both examples could also be in a fastboot flash format:
>> $ fastboot flash serialno ABCDEF
>>
>> One concern I have is that U-Boot forks might use this command as
>> an excuse to not makes things generic.
>>
>> I hope that others will chime in on this as well.
>> I'd like to discuss this more because once this command is in we cannot
>> remove it later.
>>
>> > ---
>> > drivers/fastboot/Kconfig | 7 +++++++
>> > drivers/fastboot/fb_command.c | 15 +++++++++++++++
>> > include/fastboot.h | 1 +
>> > 3 files changed, 23 insertions(+)
>> >
>> > diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig
>> > index a4313d60a9..4d94391a76 100644
>> > --- a/drivers/fastboot/Kconfig
>> > +++ b/drivers/fastboot/Kconfig
>> > @@ -241,6 +241,13 @@ config FASTBOOT_OEM_RUN
>> > this feature if you are using verified boot, as it will allow an
>> > attacker to bypass any restrictions you have in place.
>> >
>> > +config FASTBOOT_OEM_BOARD
>> > + bool "Enable the 'oem board' command"
>> > + help
>> > + This extends the fastboot protocol with an "oem board" command. This
>> > + command allows running vendor custom code defined in board/ files.
>> > + Otherwise, it will do nothing and send fastboot fail.
>>
>> If we move forward with this, please also document the new command in:
>> doc/android/fastboot.rst
This still applies, document the command please.
>>
>> > +
>> > endif # FASTBOOT
>> >
>> > endmenu
>> > diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
>> > index 5fcadcdf50..2298815770 100644
>> > --- a/drivers/fastboot/fb_command.c
>> > +++ b/drivers/fastboot/fb_command.c
>> > @@ -40,6 +40,7 @@ static void reboot_recovery(char *, char *);
>> > static void oem_format(char *, char *);
>> > static void oem_partconf(char *, char *);
>> > static void oem_bootbus(char *, char *);
>> > +static void oem_board(char *, char *);
>> > static void run_ucmd(char *, char *);
>> > static void run_acmd(char *, char *);
>> >
>> > @@ -107,6 +108,10 @@ static const struct {
>> > .command = "oem run",
>> > .dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_RUN, (run_ucmd), (NULL))
>> > },
>> > + [FASTBOOT_COMMAND_OEM_BOARD] = {
>> > + .command = "oem board",
>> > + .dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_BOARD, (oem_board), (NULL))
>> > + },
>> > [FASTBOOT_COMMAND_UCMD] = {
>> > .command = "UCmd",
>> > .dispatch = CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT, (run_ucmd), (NULL))
>> > @@ -490,3 +495,13 @@ static void __maybe_unused oem_bootbus(char *cmd_parameter, char *response)
>> > else
>> > fastboot_okay(NULL, response);
>> > }
>> > +
>> > +void __weak fastboot_oem_board(char *cmd_parameter, void *data, u32 size, char *response)
>> > +{
>> > + fastboot_fail("oem board function not defined", response);
>> > +}
>> > +
>> > +static void __maybe_unused oem_board(char *cmd_parameter, char *response)
>> > +{
>> > + fastboot_oem_board(cmd_parameter, fastboot_buf_addr, image_size, response);
>> > +}
Please also document the functions with comment headers, as done for the
other oem_ functions.
>> > diff --git a/include/fastboot.h b/include/fastboot.h
>> > index 296451f89d..06c1f26b6c 100644
>> > --- a/include/fastboot.h
>> > +++ b/include/fastboot.h
>> > @@ -37,6 +37,7 @@ enum {
>> > FASTBOOT_COMMAND_OEM_PARTCONF,
>> > FASTBOOT_COMMAND_OEM_BOOTBUS,
>> > FASTBOOT_COMMAND_OEM_RUN,
>> > + FASTBOOT_COMMAND_OEM_BOARD,
>> > FASTBOOT_COMMAND_ACMD,
>> > FASTBOOT_COMMAND_UCMD,
>> > FASTBOOT_COMMAND_COUNT
>> > --
>> > 2.30.1
>
> --
> Thank you,
> Alexey
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 1/2] fastboot: introduce 'oem board' subcommand
2024-03-04 14:11 ` Alexey Romanov
@ 2024-04-05 9:01 ` Mattijs Korpershoek
0 siblings, 0 replies; 14+ messages in thread
From: Mattijs Korpershoek @ 2024-04-05 9:01 UTC (permalink / raw)
To: Alexey Romanov
Cc: sjg@chromium.org, hs@denx.de, sean.anderson@seco.com,
dimorinny@google.com, patrick.delaunay@foss.st.com, kernel,
u-boot@lists.denx.de, Neil Armstrong
Hi Alexey,
On lun., mars 04, 2024 at 14:11, Alexey Romanov <avromanov@salutedevices.com> wrote:
> Hello,
>
> On Thu, Feb 15, 2024 at 10:14:13AM +0100, Mattijs Korpershoek wrote:
>> Hi Alexey,
>>
>> Thank you for the patch.
>>
>> On jeu., f'evr. 01, 2024 at 12:20, Alexey Romanov <avromanov@salutedevices.com> wrote:
>>
>> > Currently, fastboot protocol in U-Boot has no opportunity
>> > to execute vendor custom code with verifed boot. This patch
>> > introduce new fastboot subcommand fastboot oem board:<cmd>,
>> > which allow to run custom oem_board function.
>> >
>> > Default implementation is __weak. Vendor must redefine it in
>> > board/ folder with his own logic.
>> >
>> > For example, some vendors have their custom nand/emmc partition
>> > flashing or erasing. Here some typical command for such use cases:
>> >
>> > - flashing:
>> >
>> > $ fastboot stage bootloader.img
>> > $ fastboot oem board:write_bootloader
>> >
>> > - erasing:
>> >
>> > $ fastboot oem board:erase_env
>> >
>> > Signed-off-by: Alexey Romanov <avromanov@salutedevices.com>
>>
>> Sorry for the delay. I needed time to give this some thoughts and I
>> waited for Sean to chime as well on this.
>>
>> I've heard from Neil that this might be related to:
>> https://github.com/superna9999/pyamlboot/pull/20
>
> Yeah, pyamlboot also uses the same 'bootloader' partition flashing
> scheme as I present in the patch 2. This is custom Amlogic protocol.
>
>>
>> I think this can be useful. Not necessarily for writing custom
>> partitions, but I see this could be used for other things:
>>
>> 1. Provision SoC-specific fuses (serialno/mac addr) at the factory line
>> (for production devices)
>> Examples:
>> $ fastboot oem board:write_serialno ABCDEF
>> $ fastboot oem board:write_macaddr AA:BB:CC:DD:EE
>>
>> 2. Access secure storage (via an Trusted Application)
>
> Agree, you are completely right.
>
>>
>> But both examples could also be in a fastboot flash format:
>> $ fastboot flash serialno ABCDEF
>
> But this case requires to 'serialno' partition definition in schema?
> I didn't fully understand you.
I meant more in a "conceptual way". (from a end user perspective)
"fastboot flash" is generic command that's just supposed to write data
somewhere.
The back-end (partitioning etc) depends on the storage the device uses
so that's a "implementation detail".
In any case, I don't have a proper alternative to what you are proposing
so as send in [1], I'm okay picking this up after some minor review
comments are addressed.
[1] https://lore.kernel.org/all/87jzlcfang.fsf@baylibre.com/
>
>>
>> One concern I have is that U-Boot forks might use this command as
>> an excuse to not makes things generic.
>>
>> I hope that others will chime in on this as well.
>> I'd like to discuss this more because once this command is in we cannot
>> remove it later.
>>
>> > ---
>> > drivers/fastboot/Kconfig | 7 +++++++
>> > drivers/fastboot/fb_command.c | 15 +++++++++++++++
>> > include/fastboot.h | 1 +
>> > 3 files changed, 23 insertions(+)
>> >
>> > diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig
>> > index a4313d60a9..4d94391a76 100644
>> > --- a/drivers/fastboot/Kconfig
>> > +++ b/drivers/fastboot/Kconfig
>> > @@ -241,6 +241,13 @@ config FASTBOOT_OEM_RUN
>> > this feature if you are using verified boot, as it will allow an
>> > attacker to bypass any restrictions you have in place.
>> >
>> > +config FASTBOOT_OEM_BOARD
>> > + bool "Enable the 'oem board' command"
>> > + help
>> > + This extends the fastboot protocol with an "oem board" command. This
>> > + command allows running vendor custom code defined in board/ files.
>> > + Otherwise, it will do nothing and send fastboot fail.
>>
>> If we move forward with this, please also document the new command in:
>> doc/android/fastboot.rst
>>
>> > +
>> > endif # FASTBOOT
>> >
>> > endmenu
>> > diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
>> > index 5fcadcdf50..2298815770 100644
>> > --- a/drivers/fastboot/fb_command.c
>> > +++ b/drivers/fastboot/fb_command.c
>> > @@ -40,6 +40,7 @@ static void reboot_recovery(char *, char *);
>> > static void oem_format(char *, char *);
>> > static void oem_partconf(char *, char *);
>> > static void oem_bootbus(char *, char *);
>> > +static void oem_board(char *, char *);
>> > static void run_ucmd(char *, char *);
>> > static void run_acmd(char *, char *);
>> >
>> > @@ -107,6 +108,10 @@ static const struct {
>> > .command = "oem run",
>> > .dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_RUN, (run_ucmd), (NULL))
>> > },
>> > + [FASTBOOT_COMMAND_OEM_BOARD] = {
>> > + .command = "oem board",
>> > + .dispatch = CONFIG_IS_ENABLED(FASTBOOT_OEM_BOARD, (oem_board), (NULL))
>> > + },
>> > [FASTBOOT_COMMAND_UCMD] = {
>> > .command = "UCmd",
>> > .dispatch = CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT, (run_ucmd), (NULL))
>> > @@ -490,3 +495,13 @@ static void __maybe_unused oem_bootbus(char *cmd_parameter, char *response)
>> > else
>> > fastboot_okay(NULL, response);
>> > }
>> > +
>> > +void __weak fastboot_oem_board(char *cmd_parameter, void *data, u32 size, char *response)
>> > +{
>> > + fastboot_fail("oem board function not defined", response);
>> > +}
>> > +
>> > +static void __maybe_unused oem_board(char *cmd_parameter, char *response)
>> > +{
>> > + fastboot_oem_board(cmd_parameter, fastboot_buf_addr, image_size, response);
>> > +}
>> > diff --git a/include/fastboot.h b/include/fastboot.h
>> > index 296451f89d..06c1f26b6c 100644
>> > --- a/include/fastboot.h
>> > +++ b/include/fastboot.h
>> > @@ -37,6 +37,7 @@ enum {
>> > FASTBOOT_COMMAND_OEM_PARTCONF,
>> > FASTBOOT_COMMAND_OEM_BOOTBUS,
>> > FASTBOOT_COMMAND_OEM_RUN,
>> > + FASTBOOT_COMMAND_OEM_BOARD,
>> > FASTBOOT_COMMAND_ACMD,
>> > FASTBOOT_COMMAND_UCMD,
>> > FASTBOOT_COMMAND_COUNT
>> > --
>> > 2.30.1
>
> --
> Thank you,
> Alexey
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 2/2] board: ad401: example of fastboot oem board realization
2024-03-04 14:03 ` Alexey Romanov
@ 2024-04-05 9:02 ` Mattijs Korpershoek
0 siblings, 0 replies; 14+ messages in thread
From: Mattijs Korpershoek @ 2024-04-05 9:02 UTC (permalink / raw)
To: Alexey Romanov
Cc: sjg@chromium.org, hs@denx.de, sean.anderson@seco.com,
dimorinny@google.com, patrick.delaunay@foss.st.com, kernel,
u-boot@lists.denx.de
Hi Alexey,
On lun., mars 04, 2024 at 14:03, Alexey Romanov <avromanov@salutedevices.com> wrote:
> Hello Mattijs,
>
> On Thu, Feb 15, 2024 at 10:24:11AM +0100, Mattijs Korpershoek wrote:
>> On jeu., f'evr. 01, 2024 at 12:20, Alexey Romanov <avromanov@salutedevices.com> wrote:
>>
>> > An example of how we use fastboot oeam board subcommand
>> > for Sean Anderson.
>> >
>> > 1 - OEM_BOARD_WRITE_BOOTLOADER_CMD:
>> >
>> > We use it for custom Amlogic bootloader + tpl
>> > flashing protocol.
>> >
>> > 2 - OEM_BOARD_ERASE_CMD:
>> >
>> > Custom logic for erasing the env-emulated partition,
>> > which isn't in the mtd markup map.
>> >
>> > Example of the script which completely flashes the device:
>> >
>> > $ fastboot erase bootloader
>> > $ fastboot stage u-boot.bin
>> > $ fastboot oem board:write_bootloader
>> > $ fastboot reboot-bootloader
>> > $ fastboot oem board:erase_env
>> > $ fastboot erase misc
>> > $ fastboot erase super
>> > $ fastboot flash super rootfs
>> > $ fastboot reboot
>> >
>> > Signed-off-by: Alexey Romanov <avromanov@salutedevices.com>
>> > ---
>> > board/amlogic/ad401/fastboot.c | 222 +++++++++++++++++++++++++++++++++
>> > 1 file changed, 222 insertions(+)
>> > create mode 100644 board/amlogic/ad401/fastboot.c
>> >
>> > diff --git a/board/amlogic/ad401/fastboot.c b/board/amlogic/ad401/fastboot.c
>> > new file mode 100644
>> > index 0000000000..01da8efa5b
>> > --- /dev/null
>> > +++ b/board/amlogic/ad401/fastboot.c
>> > @@ -0,0 +1,222 @@
>> > +// SPDX-License-Identifier: GPL-2.0+
>> > +/*
>> > + * (C) Copyright 2023 SaluteDevices, Inc.
>> > + */
>> > +
>> > +#include <common.h>
>> > +#include <env.h>
>> > +#include <fastboot.h>
>> > +#include <nand.h>
>> > +#include <asm/arch/nand.h>
>> > +#include <jffs2/load_kernel.h>
>> > +#include <linux/sizes.h>
>> > +#include <linux/types.h>
>> > +#include <linux/mtd/mtd.h>
>> > +
>> > +enum {
>> > + OEM_BOARD_ERASE_CMD,
>> > + OEM_BOARD_WRITE_BOOTLOADER_CMD,
>> > +};
>> > +
>> > +struct defenv {
>> > + char *name;
>> > + char value[256];
>> > +};
>> > +
>> > +static void save_defenv(struct defenv *e, size_t cnt)
>> > +{
>> > + int i;
>> > +
>> > + for (i = 0; i < cnt; i++) {
>> > + const char *env_val = env_get(e[i].name);
>> > +
>> > + if (env_val)
>> > + strlcpy(e[i].value, env_val, sizeof(e[i].value));
>> > + else
>> > + e[i].value[0] = '\0';
>> > + }
>> > +}
>> > +
>> > +static void set_defenv(struct defenv *e, size_t cnt)
>> > +{
>> > + int i;
>> > +
>> > + for (i = 0; i < cnt; i++)
>> > + env_set(e[i].name, e[i].value);
>> > +}
>> > +
>> > +static int fastboot_erase_env(void)
>> > +{
>> > + char *const defenv_names[] = { "lock", "mtdparts", "mtdids" };
>> > + struct defenv env[ARRAY_SIZE(defenv_names)];
>> > + int err, i;
>> > +
>> > + for (i = 0; i < ARRAY_SIZE(env); i++)
>> > + env[i].name = defenv_names[i];
>> > +
>> > + printf("ENV is being erased...\n");
>> > +
>> > + /*
>> > + * Reset environment to the default, excluding 'lock' variable,
>> > + * because it reflects the fastboot's state after execution of
>> > + * 'flashing unlock' command, hence it must survive the env-erasing.
>> > + * Otherwise, further erase commands will fail on check_lock().
>> > + *
>> > + * Also, we have to save 'mtdparts' and 'mtdids' variables
>> > + * because they are necessary to obtain partition map.
>> > + */
>> > +
>> > + save_defenv(env, ARRAY_SIZE(env));
>> > + env_set_default(NULL, 0);
>> > + set_defenv(env, ARRAY_SIZE(env));
>> > +
>> > + err = env_save();
>> > + if (err) {
>> > + pr_err("Can't overwrite ENV-partition\n");
>> > + return err;
>> > + }
>>
>> Hmm so the fastboot locked state is saved in the U-Boot environment.
>> There is probably a good reason for this (no secure storage for
>> example). But this does not feel board specific.
>>
>> Wouldn't it be better if we could just run "fastboot erase bootenv" and
>> that the generic fastboot code does the right thing?
>
> Are you proposing to modify the code of fastboot in such a way
> that if user send 'erase bootenv' string, then we call generic
> function to cleanup environment, instead of try to search (and erase)
> in partition schema 'bootenv' partition?
I would have liked to have a generic "erase bootenv" command yes, but
your solution seems fine so no need to do something different.
Thank you for your patience with this !
>
>> (which is env default, and ignoring some magic/specific variables)
>>
>> > +
>> > + return 0;
>> > +}
>> > +
>> > +static int fastboot_nand_write_tpl(struct mtd_info *mtd, void *buffer,
>> > + u32 offset, size_t size, int flags)
>> > +{
>> > + int boot_cpy_num = meson_bootloader_copy_num(BOOT_TPL);
>> > + u64 size_per_copy = meson_bootloader_copy_size(mtd, BOOT_TPL);
>> > + int i;
>> > +
>> > + for (i = 0; i < boot_cpy_num; i++) {
>> > + size_t retlen, len = size;
>> > + int ret;
>> > +
>> > + ret = nand_write_skip_bad(mtd, offset + (i * size_per_copy),
>> > + &len, &retlen, offset + size_per_copy,
>> > + buffer, flags);
>> > + if (ret)
>> > + return ret;
>> > + }
>> > +
>> > + return 0;
>> > +}
>> > +
>> > +static int fastboot_nand_write_bl2(struct mtd_info *mtd, void *buffer,
>> > + u32 offset, size_t size, int flags)
>> > +{
>> > + int boot_cpy_num = meson_bootloader_copy_num(BOOT_BL2);
>> > + u64 size_per_copy = meson_bootloader_copy_size(mtd, BOOT_BL2);
>> > + int i;
>> > +
>> > + for (i = 0; i < boot_cpy_num; i++) {
>> > + int ret;
>> > +
>> > + ret = meson_bootloader_write_bl2(mtd, buffer,
>> > + offset + (i * size_per_copy),
>> > + size, flags);
>> > + if (ret)
>> > + return ret;
>> > + }
>> > +
>> > + return meson_bootloader_write_info_pages();
>> > +}
>> > +
>> > +static int fastboot_nand_write_bootloader(void *buffer, u32 size)
>> > +{
>> > + struct part_info *part;
>> > + struct mtd_info *mtd = NULL;
>> > + struct mtd_device *dev;
>> > + u8 pnum;
>> > + int ret;
>> > +
>> > + if (size < BL2_SIZE)
>> > + return 0;
>> > +
>> > + if (!buffer)
>> > + return -EINVAL;
>> > +
>> > + ret = mtdparts_init();
>> > + if (ret) {
>> > + pr_err("Cannot initialize MTD partitions\n");
>> > + return ret;
>> > + }
>> > +
>> > + ret = find_dev_and_part("bootloader", &dev, &pnum, &part);
>> > + if (ret) {
>> > + pr_err("cannot find 'bootloader' partition\n");
>> > + return ret;
>> > + }
>> > +
>> > + mtd = get_nand_dev_by_index(dev->id->num);
>> > + if (!mtd)
>> > + return -EINVAL;
>> > +
>> > + ret = fastboot_nand_write_bl2(mtd, buffer, part->offset,
>> > + BL2_SIZE, WITH_WR_VERIFY);
>> > + if (ret) {
>> > + pr_err("fastboot: failed to write BL2\n");
>> > + return ret;
>> > + }
>> > +
>> > + ret = find_dev_and_part("tpl", &dev, &pnum, &part);
>> > + if (ret) {
>> > + pr_err("cannot find 'bootloader' partition\n");
>> > + return ret;
>> > + }
>> > +
>> > + mtd = get_nand_dev_by_index(dev->id->num);
>> > + if (!mtd)
>> > + return -EINVAL;
>> > +
>> > + ret = fastboot_nand_write_tpl(mtd, buffer + BL2_SIZE, part->offset,
>> > + size - BL2_SIZE, WITH_WR_VERIFY);
>> > + if (ret) {
>> > + pr_err("fastboot: failed to write TPL\n");
>> > + return ret;
>> > + }
>> > +
>> > + return 0;
>> > +}
>> > +
>> > +int get_oem_board_command(const char *cmd)
>> > +{
>> > + const char *oem_commands[] = {
>> > + [OEM_BOARD_ERASE_CMD] = "erase_env",
>> > + [OEM_BOARD_WRITE_BOOTLOADER_CMD] = "write_bootloader",
>> > + };
>> > + int i;
>> > +
>> > + for (i = 0; i < ARRAY_SIZE(oem_commands); i++)
>> > + if (!strcmp(cmd, oem_commands[i]))
>> > + return i;
>> > +
>> > + return -EINVAL;
>> > +}
>> > +
>> > +void fastboot_oem_board(const char *cmd_parameter, void *data, u32 size,
>> > + char *response)
>> > +{
>> > + char buf[128] = { 0 };
>> > + int ret, cmd;
>> > +
>> > + cmd = get_oem_board_command(cmd_parameter);
>> > +
>> > + switch (cmd) {
>> > + case OEM_BOARD_ERASE_CMD:
>> > + ret = fastboot_erase_env();
>> > + break;
>> > + case OEM_BOARD_WRITE_BOOTLOADER_CMD:
>> > + ret = fastboot_nand_write_bootloader(data, size);
>> > + break;
>> > + default:
>> > + snprintf(buf, sizeof(buf),
>> > + "Command 'oem board %s' not supported",
>> > + cmd_parameter);
>> > + fastboot_fail(buf, response);
>> > + return;
>> > + }
>> > +
>> > + if (ret < 0)
>> > + fastboot_fail("Failed to erase env partition", response);
>> > + else
>> > + fastboot_okay(NULL, response);
>> > +}
>> > --
>> > 2.30.1
>
> --
> Thank you,
> Alexey
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2024-04-05 9:03 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-01 9:20 [RFC PATCH v2 0/2] Introduce fastboot oem board command Alexey Romanov
2024-02-01 9:20 ` [RFC PATCH v2 1/2] fastboot: introduce 'oem board' subcommand Alexey Romanov
2024-02-15 9:14 ` Mattijs Korpershoek
2024-03-04 14:11 ` Alexey Romanov
2024-04-05 9:01 ` Mattijs Korpershoek
2024-04-03 8:49 ` Alexey Romanov
2024-04-05 8:58 ` Mattijs Korpershoek
2024-02-01 9:20 ` [RFC PATCH v2 2/2] board: ad401: example of fastboot oem board realization Alexey Romanov
2024-02-01 13:56 ` Dan Carpenter
2024-02-01 14:54 ` Alexey Romanov
2024-02-15 9:24 ` Mattijs Korpershoek
2024-03-04 14:03 ` Alexey Romanov
2024-04-05 9:02 ` Mattijs Korpershoek
2024-02-14 8:39 ` [RFC PATCH v2 0/2] Introduce fastboot oem board command Alexey Romanov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox