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 <[email protected]>
> ---
>  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
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

Reply via email to