On Mon, Oct 11, 2021 at 06:53:59PM -0700, Trent Piepho wrote: > Add new "fcb" command. It can save a decoded copy of the FCB to a file, > do a hexdump of the decoded FCB, or display the FCB fields. Or simply > read and validate the FCB. > > The FCB uses a different ECC system that the rest of flash and there is > no easy way to decode it in Barebox or Linux. The code already here > does it. > > This will also set the nand0.barebox device parameters with the location > of the bootloader images as read from the FCB. > > Signed-off-by: Trent Piepho <trent.piepho@xxxxxxxxxxxxxxxxx> > --- > commands/Kconfig | 19 ++++++ > common/imx-bbu-nand-fcb.c | 126 ++++++++++++++++++++++++++++++++++++-- > 2 files changed, 139 insertions(+), 6 deletions(-) > > diff --git a/commands/Kconfig b/commands/Kconfig > index 5ae3cb3dd..d3b5cd7fa 100644 > --- a/commands/Kconfig > +++ b/commands/Kconfig > @@ -277,6 +277,25 @@ config CMD_SLICE > command can be used to print informations about slices and also to manipulate > them on the command line for debugging purposes. > > +config CMD_IMX_NAND_FCB > + tristate > + prompt "iMX FCB decoding and display" > + depends on BAREBOX_UPDATE_IMX_NAND_FCB > + help > + Decode and display or save the contents of the iMX FCB. > + > + This will add a command named "fcb" that will decode the FCB and can > + save the decode data to a file or display the contents. > + > + The FCB is a block of data at the start of NAND flash that instructs > + the iMX ROM bootloader on how to find Barebox. It uses a different > + ECC config than the rest of NAND flash and can't be read correctly > + with normal "md" commands. > + > + The command also saves the locations of the Barebox image in NAND > + from the FCB into parameters on the NAND deivce, which are available > + in scripts as environment variables. > + > # end Information commands > endmenu > > diff --git a/common/imx-bbu-nand-fcb.c b/common/imx-bbu-nand-fcb.c > index 76ac1d4f2..e61494930 100644 > --- a/common/imx-bbu-nand-fcb.c > +++ b/common/imx-bbu-nand-fcb.c > @@ -7,6 +7,8 @@ > > #include <filetype.h> > #include <common.h> > +#include <command.h> > +#include <getopt.h> > #include <malloc.h> > #include <errno.h> > #include <fcntl.h> > @@ -14,6 +16,7 @@ > #include <linux/sizes.h> > #include <bbu.h> > #include <fs.h> > +#include <libfile.h> > #include <linux/mtd/mtd-abi.h> > #include <linux/mtd/nand_mxs.h> > #include <linux/mtd/mtd.h> > @@ -27,6 +30,9 @@ > #include <mtd/mtd-peb.h> > #include <soc/imx/imx-nand-bcb.h> > > +/* Name of NAND device that contains FCB */ > +#define FCB_NAND_PART "nand0.barebox" > + > #ifdef CONFIG_ARCH_IMX6 > #include <mach/imx6.h> > static inline int fcb_is_bch_encoded(void) > @@ -387,6 +393,7 @@ static ssize_t raw_write_page(struct mtd_info *mtd, void *buf, loff_t offset) > return ret; > } > > +/* Returns size of FCB on success, negative on error */ > static int read_fcb(struct mtd_info *mtd, int num, struct fcb_block **retfcb) > { > int ret; > @@ -403,10 +410,13 @@ static int read_fcb(struct mtd_info *mtd, int num, struct fcb_block **retfcb) > goto err; > } > > - if (fcb_is_bch_encoded()) > + if (fcb_is_bch_encoded()) { > fcb = read_fcb_bch(rawpage, 40); > - else > + ret = 128 * 8; > + } else { > fcb = read_fcb_hamming_13_8(rawpage); > + ret = 512; > + } > > if (IS_ERR(fcb)) { > pr_err("Cannot read fcb on block %d\n", num); > @@ -415,7 +425,6 @@ static int read_fcb(struct mtd_info *mtd, int num, struct fcb_block **retfcb) > } > > *retfcb = fcb; > - ret = 0; > err: > free(rawpage); > > @@ -870,7 +879,7 @@ static int fcb_dbbt_check(struct mtd_info *mtd, int num, struct fcb_block *fcb) > int pages_per_block = mtd->erasesize / mtd->writesize; > > ret = read_fcb(mtd, num, &f); > - if (ret) > + if (ret < 0) > return ret; > > if (memcmp(fcb, f, sizeof(*fcb))) { > @@ -1403,7 +1412,7 @@ int imx6_bbu_nand_register_handler(const char *name, unsigned long flags) > imx_handler->filetype = filetype_arm_barebox; > > handler = &imx_handler->handler; > - handler->devicefile = "nand0.barebox"; > + handler->devicefile = FCB_NAND_PART; > handler->name = name; > handler->flags = flags | BBU_HANDLER_CAN_REFRESH; > handler->handler = imx_bbu_nand_update; > @@ -1480,7 +1489,7 @@ int imx28_bbu_nand_register_handler(const char *name, unsigned long flags) > imx_handler->filetype = filetype_mxs_bootstream; > > handler = &imx_handler->handler; > - handler->devicefile = "nand0.barebox"; > + handler->devicefile = FCB_NAND_PART; > handler->name = name; > handler->flags = flags | BBU_HANDLER_CAN_REFRESH; > handler->handler = imx_bbu_nand_update; > @@ -1492,3 +1501,108 @@ int imx28_bbu_nand_register_handler(const char *name, unsigned long flags) > return ret; > } > #endif > + > +#if IS_ENABLED(CONFIG_CMD_IMX_NAND_FCB) > + > +static int do_fcb(int argc, char *argv[]) > +{ > + int opt; > + int fd; > + int ret; > + int fcbsize; > + struct cdev *cdev; > + struct fcb_block *fcb; > + bool hex = false, info = false; > + const char *outfile = NULL; > + unsigned int block = 0; > + > + while ((opt = getopt(argc, argv, "xin:o:")) > 0) { > + switch (opt) { > + case 'x': > + hex = true; > + break; > + case 'i': > + info = true; > + break; > + case 'o': > + outfile = optarg; > + break; > + case 'n': > + block = strtoull_suffix(optarg, NULL, 0); > + break; > + default: > + return COMMAND_ERROR_USAGE; > + } > + } Not sure if we need to control this command in such a fine grained way. For me just extracting all possible FCBs including the firmware images, maybe printing consistency information would be enough. That's just a personal opinion though, feel free to override it. Sascha -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox