Hi Alexey, On lun., mars 04, 2024 at 14:03, Alexey Romanov <[email protected]> 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 >> <[email protected]> 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 <[email protected]> >> > --- >> > 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

