imls: Add support to list images in NAND device
authorVipin Kumar <vipin.kumar@st.com>
Sun, 16 Dec 2012 22:32:48 +0000 (22:32 +0000)
committerScott Wood <scottwood@freescale.com>
Fri, 22 Feb 2013 22:53:04 +0000 (16:53 -0600)
This patch adds support to list images in NAND flash through imls

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
README
common/cmd_bootm.c

diff --git a/README b/README
index d8cb3940d4f04810dcc6fe88a5f03f0b0cd5d8a8..0070694438c956cad17af9ce27149cc7f98041c0 100644 (file)
--- a/README
+++ b/README
@@ -842,7 +842,8 @@ The following options need to be configured:
                CONFIG_CMD_I2C          * I2C serial bus support
                CONFIG_CMD_IDE          * IDE harddisk support
                CONFIG_CMD_IMI            iminfo
-               CONFIG_CMD_IMLS           List all found images
+               CONFIG_CMD_IMLS           List all images found in NOR flash
+               CONFIG_CMD_IMLS_NAND      List all images found in NAND flash
                CONFIG_CMD_IMMAP        * IMMR dump support
                CONFIG_CMD_IMPORTENV    * import an environment
                CONFIG_CMD_INI          * import data from an ini file into the env
index f0338babeba8f580a1f0fff7c77d3e590f137a6a..1312a0db8a6782d9507244e321c9976de215e596 100644 (file)
@@ -79,9 +79,15 @@ static int image_info(unsigned long addr);
 #include <flash.h>
 #include <mtd/cfi_flash.h>
 extern flash_info_t flash_info[]; /* info for FLASH chips */
+#endif
+
+#if defined(CONFIG_CMD_IMLS) || defined(CONFIG_CMD_IMLS_NAND)
 static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 #endif
 
+#include <linux/err.h>
+#include <nand.h>
+
 #ifdef CONFIG_SILENT_CONSOLE
 static void fixup_silent_linux(void);
 #endif
@@ -1192,7 +1198,7 @@ U_BOOT_CMD(
 /* imls - list all images found in flash */
 /*******************************************************************/
 #if defined(CONFIG_CMD_IMLS)
-static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int do_imls_nor(void)
 {
        flash_info_t *info;
        int i, j;
@@ -1241,6 +1247,161 @@ next_sector:            ;
                }
 next_bank:     ;
        }
+       return 0;
+}
+#endif
+
+#if defined(CONFIG_CMD_IMLS_NAND)
+static int nand_imls_legacyimage(nand_info_t *nand, int nand_dev, loff_t off,
+               size_t len)
+{
+       void *imgdata;
+       int ret;
+
+       imgdata = malloc(len);
+       if (!imgdata) {
+               printf("May be a Legacy Image at NAND device %d offset %08llX:\n",
+                               nand_dev, off);
+               printf("   Low memory(cannot allocate memory for image)\n");
+               return -ENOMEM;
+       }
+
+       ret = nand_read_skip_bad(nand, off, &len,
+                       imgdata);
+       if (ret < 0 && ret != -EUCLEAN) {
+               free(imgdata);
+               return ret;
+       }
+
+       if (!image_check_hcrc(imgdata)) {
+               free(imgdata);
+               return 0;
+       }
+
+       printf("Legacy Image at NAND device %d offset %08llX:\n",
+                       nand_dev, off);
+       image_print_contents(imgdata);
+
+       puts("   Verifying Checksum ... ");
+       if (!image_check_dcrc(imgdata))
+               puts("Bad Data CRC\n");
+       else
+               puts("OK\n");
+
+       free(imgdata);
+
+       return 0;
+}
+
+static int nand_imls_fitimage(nand_info_t *nand, int nand_dev, loff_t off,
+               size_t len)
+{
+       void *imgdata;
+       int ret;
+
+       imgdata = malloc(len);
+       if (!imgdata) {
+               printf("May be a FIT Image at NAND device %d offset %08llX:\n",
+                               nand_dev, off);
+               printf("   Low memory(cannot allocate memory for image)\n");
+               return -ENOMEM;
+       }
+
+       ret = nand_read_skip_bad(nand, off, &len,
+                       imgdata);
+       if (ret < 0 && ret != -EUCLEAN) {
+               free(imgdata);
+               return ret;
+       }
+
+       if (!fit_check_format(imgdata)) {
+               free(imgdata);
+               return 0;
+       }
+
+       printf("FIT Image at NAND device %d offset %08llX:\n", nand_dev, off);
+
+       fit_print_contents(imgdata);
+       free(imgdata);
+
+       return 0;
+}
+
+static int do_imls_nand(void)
+{
+       nand_info_t *nand;
+       int nand_dev = nand_curr_device;
+       size_t len;
+       loff_t off;
+       u32 buffer[16];
+
+       if (nand_dev < 0 || nand_dev >= CONFIG_SYS_MAX_NAND_DEVICE) {
+               puts("\nNo NAND devices available\n");
+               return -ENODEV;
+       }
+
+       printf("\n");
+
+       for (nand_dev = 0; nand_dev < CONFIG_SYS_MAX_NAND_DEVICE; nand_dev++) {
+               nand = &nand_info[nand_dev];
+               if (!nand->name || !nand->size)
+                       continue;
+
+               for (off = 0; off < nand->size; off += nand->erasesize) {
+                       const image_header_t *header;
+                       int ret;
+
+                       if (nand_block_isbad(nand, off))
+                               continue;
+
+                       len = sizeof(buffer);
+
+                       ret = nand_read(nand, off, &len, (u8 *)buffer);
+                       if (ret < 0 && ret != -EUCLEAN) {
+                               printf("NAND read error %d at offset %08llX\n",
+                                               ret, off);
+                               continue;
+                       }
+
+                       switch (genimg_get_format(buffer)) {
+                       case IMAGE_FORMAT_LEGACY:
+                               header = (const image_header_t *)buffer;
+
+                               len = image_get_image_size(header);
+                               nand_imls_legacyimage(nand, nand_dev, off, len);
+                               break;
+#if defined(CONFIG_FIT)
+                       case IMAGE_FORMAT_FIT:
+                               len = fit_get_size(buffer);
+                               nand_imls_fitimage(nand, nand_dev, off, len);
+                               break;
+#endif
+                       }
+               }
+       }
+
+       return 0;
+}
+#endif
+
+#if defined(CONFIG_CMD_IMLS) || defined(CONFIG_CMD_IMLS_NAND)
+static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       int ret_nor = 0, ret_nand = 0;
+
+#if defined(CONFIG_CMD_IMLS)
+       ret_nor = do_imls_nor();
+#endif
+
+#if defined(CONFIG_CMD_IMLS_NAND)
+       ret_nand = do_imls_nand();
+#endif
+
+       if (ret_nor)
+               return ret_nor;
+
+       if (ret_nand)
+               return ret_nand;
 
        return (0);
 }
@@ -1249,8 +1410,8 @@ U_BOOT_CMD(
        imls,   1,              1,      do_imls,
        "list all images found in flash",
        "\n"
-       "    - Prints information about all images found at sector\n"
-       "      boundaries in flash."
+       "    - Prints information about all images found at sector/block\n"
+       "      boundaries in nor/nand flash."
 );
 #endif