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; + } + } + + if (optind != argc) + return COMMAND_ERROR_USAGE; + + cdev = cdev_by_name(FCB_NAND_PART); + if (!cdev) { + pr_err("Couldn't find FCB flash device '%s'\n", FCB_NAND_PART); + return -ENODEV; + } + + ret = read_fcb(cdev->mtd, block, &fcb); + if (ret < 0) { + perror("read_fcb"); + return ret; + } + fcbsize = ret; + ret = 0; + if (!info && !hex && !outfile) + printf("FCB OK (%d bytes)\n", fcbsize); + + set_dev_params(cdev, fcb); + + if (info) { + const int oldlevel = barebox_loglevel; + + barebox_loglevel = MSG_DEBUG; + pr_debug("Decoded FCB size: %d bytes\n", fcbsize); + dump_fcb(fcb); + barebox_loglevel = oldlevel; + } + + if (hex) + memory_display(fcb, 0, fcbsize, 1, 0); + + if (outfile) { + fd = open(outfile, O_WRONLY | O_CREAT, 0644); + if (fd < 0) { + perror("open"); + ret = fd; + goto out; + } + ret = write_full(fd, fcb, fcbsize); + close(fd); + if (ret < 0) { + perror("write"); + goto out; + } + } + +out: + free(fcb); + return ret; +} + + +BAREBOX_CMD_HELP_START(fcb) +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT("-i", "Print information from FCB") +BAREBOX_CMD_HELP_OPT("-x", "Display FCB data bytes") +BAREBOX_CMD_HELP_OPT("-n BLK", "Eraseblock number to read FCB from") +BAREBOX_CMD_HELP_OPT("-o FILE", "Write decoded FCB to file") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(fcb) + .cmd = do_fcb, + BAREBOX_CMD_DESC("i.MX FCB decoder") + BAREBOX_CMD_OPTS("[-ixno]") + BAREBOX_CMD_GROUP(CMD_GRP_INFO) + BAREBOX_CMD_HELP(cmd_fcb_help) +BAREBOX_CMD_END + +#endif /*CONFIG_CMD_IMX_NAND_FCB*/ -- 2.31.1 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox