]> git.sur5r.net Git - u-boot/blobdiff - common/cmd_bootm.c
[new uImage] Disable debuging output in preparation for merge with master
[u-boot] / common / cmd_bootm.c
index 8595ef6889b1ac7674ee5177add6ea35622dadfd..789ee03387e2f80b06a3ec7baaca2d8b2a63cb7f 100644 (file)
@@ -21,7 +21,6 @@
  * MA 02111-1307 USA
  */
 
-#define DEBUG
 
 /*
  * Boot support
@@ -66,7 +65,12 @@ static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 static void fixup_silent_linux (void);
 #endif
 
-static void *get_kernel (cmd_tbl_t *cmdtp, int flag,int argc, char *argv[],
+static image_header_t *image_get_kernel (ulong img_addr, int verify);
+#if defined(CONFIG_FIT)
+static int fit_check_kernel (const void *fit, int os_noffset, int verify);
+#endif
+
+static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag,int argc, char *argv[],
                bootm_headers_t *images, ulong *os_data, ulong *os_len);
 extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
@@ -143,15 +147,15 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        board_lmb_reserve(&lmb);
 
        /* get kernel image header, start address and length */
-       os_hdr = get_kernel (cmdtp, flag, argc, argv,
+       os_hdr = boot_get_kernel (cmdtp, flag, argc, argv,
                        &images, &os_data, &os_len);
-       if (os_len == 0)
+       if (os_len == 0) {
+               puts ("ERROR: can't get kernel image!\n");
                return 1;
-
-       show_boot_progress (6);
+       }
 
        /* get image parameters */
-       switch (gen_image_get_format (os_hdr)) {
+       switch (genimg_get_format (os_hdr)) {
        case IMAGE_FORMAT_LEGACY:
                type = image_get_type (os_hdr);
                comp = image_get_comp (os_hdr);
@@ -162,8 +166,36 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                break;
 #if defined(CONFIG_FIT)
        case IMAGE_FORMAT_FIT:
-               fit_unsupported ("bootm");
-               return 1;
+               if (fit_image_get_type (images.fit_hdr_os,
+                                       images.fit_noffset_os, &type)) {
+                       puts ("Can't get image type!\n");
+                       show_boot_progress (-109);
+                       return 1;
+               }
+
+               if (fit_image_get_comp (images.fit_hdr_os,
+                                       images.fit_noffset_os, &comp)) {
+                       puts ("Can't get image compression!\n");
+                       show_boot_progress (-110);
+                       return 1;
+               }
+
+               if (fit_image_get_os (images.fit_hdr_os,
+                                       images.fit_noffset_os, &os)) {
+                       puts ("Can't get image OS!\n");
+                       show_boot_progress (-111);
+                       return 1;
+               }
+
+               image_end = fit_get_end (images.fit_hdr_os);
+
+               if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os,
+                                       &load_start)) {
+                       puts ("Can't get image load address!\n");
+                       show_boot_progress (-112);
+                       return 1;
+               }
+               break;
 #endif
        default:
                puts ("ERROR: unknown image format type!\n");
@@ -172,7 +204,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 
        image_start = (ulong)os_hdr;
        load_end = 0;
-       type_name = image_get_type_name (type);
+       type_name = genimg_get_type_name (type);
 
        /*
         * We have reached the point of no return: we are going to
@@ -210,7 +242,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                printf ("   Uncompressing %s ... ", type_name);
                if (gunzip ((void *)load_start, unc_len,
                                        (uchar *)os_data, &os_len) != 0) {
-                       puts ("GUNZIP ERROR - must RESET board to recover\n");
+                       puts ("GUNZIP: uncompress or overwrite error "
+                               "- must RESET board to recover\n");
                        show_boot_progress (-6);
                        do_reset (cmdtp, flag, argc, argv);
                }
@@ -229,7 +262,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                                        &unc_len, (char *)os_data, os_len,
                                        CFG_MALLOC_LEN < (4096 * 1024), 0);
                if (i != BZ_OK) {
-                       printf ("BUNZIP2 ERROR %d - must RESET board to recover\n", i);
+                       printf ("BUNZIP2: uncompress or overwrite error %d "
+                               "- must RESET board to recover\n", i);
                        show_boot_progress (-6);
                        do_reset (cmdtp, flag, argc, argv);
                }
@@ -253,6 +287,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                debug ("load_start = 0x%lx, load_end = 0x%lx\n", load_start, load_end);
 
                puts ("ERROR: image overwritten - must RESET the board to recover.\n");
+               show_boot_progress (-113);
                do_reset (cmdtp, flag, argc, argv);
        }
 
@@ -303,22 +338,26 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        show_boot_progress (-9);
 #ifdef DEBUG
        puts ("\n## Control returned to monitor - resetting...\n");
-       do_reset (cmdtp, flag, argc, argv);
+       if (images.autostart)
+               do_reset (cmdtp, flag, argc, argv);
 #endif
+       if (!images.autostart && iflag)
+               enable_interrupts();
+
        return 1;
 }
 
 /**
- * get_kernel - find kernel image
- * @os_data: pointer to a ulong variable, will hold os data start address
- * @os_len: pointer to a ulong variable, will hold os data length
+ * image_get_kernel - verify legacy format kernel image
+ * @img_addr: in RAM address of the legacy format image to be verified
+ * @verify: data CRC verification flag
  *
- * get_kernel() tries to find a kernel image, verifies its integrity
- * and locates kernel data.
+ * image_get_kernel() verifies legacy image integrity and returns pointer to
+ * legacy image header if image verification was completed successfully.
  *
  * returns:
- *     pointer to image header if valid image was found, plus kernel start
- *     address and length, otherwise NULL
+ *     pointer to a legacy image header if valid image was found
+ *     otherwise return NULL
  */
 static image_header_t *image_get_kernel (ulong img_addr, int verify)
 {
@@ -360,18 +399,65 @@ static image_header_t *image_get_kernel (ulong img_addr, int verify)
 }
 
 /**
- * get_kernel - find kernel image
+ * fit_check_kernel - verify FIT format kernel subimage
+ * @fit_hdr: pointer to the FIT image header
+ * os_noffset: kernel subimage node offset within FIT image
+ * @verify: data CRC verification flag
+ *
+ * fit_check_kernel() verifies integrity of the kernel subimage and from
+ * specified FIT image.
+ *
+ * returns:
+ *     1, on success
+ *     0, on failure
+ */
+#if defined (CONFIG_FIT)
+static int fit_check_kernel (const void *fit, int os_noffset, int verify)
+{
+       fit_image_print (fit, os_noffset, "   ");
+
+       if (verify) {
+               puts ("   Verifying Hash Integrity ... ");
+               if (!fit_image_check_hashes (fit, os_noffset)) {
+                       puts ("Bad Data Hash\n");
+                       show_boot_progress (-104);
+                       return 0;
+               }
+               puts ("OK\n");
+       }
+       show_boot_progress (105);
+
+       if (!fit_image_check_target_arch (fit, os_noffset)) {
+               puts ("Unsupported Architecture\n");
+               show_boot_progress (-105);
+               return 0;
+       }
+
+       show_boot_progress (106);
+       if (!fit_image_check_type (fit, os_noffset, IH_TYPE_KERNEL)) {
+               puts ("Not a kernel image\n");
+               show_boot_progress (-106);
+               return 0;
+       }
+
+       show_boot_progress (107);
+       return 1;
+}
+#endif /* CONFIG_FIT */
+
+/**
+ * boot_get_kernel - find kernel image
  * @os_data: pointer to a ulong variable, will hold os data start address
  * @os_len: pointer to a ulong variable, will hold os data length
  *
- * get_kernel() tries to find a kernel image, verifies its integrity
+ * boot_get_kernel() tries to find a kernel image, verifies its integrity
  * and locates kernel data.
  *
  * returns:
  *     pointer to image header if valid image was found, plus kernel start
  *     address and length, otherwise NULL
  */
-static void *get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
+static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
                bootm_headers_t *images, ulong *os_data, ulong *os_len)
 {
        image_header_t  *hdr;
@@ -380,6 +466,10 @@ static void *get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
        void            *fit_hdr;
        const char      *fit_uname_config = NULL;
        const char      *fit_uname_kernel = NULL;
+       const void      *data;
+       size_t          len;
+       int             cfg_noffset;
+       int             os_noffset;
 #endif
 
        /* find out kernel image address */
@@ -403,21 +493,22 @@ static void *get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
        }
 
        show_boot_progress (1);
-       printf ("## Booting kernel image at %08lx ...\n", img_addr);
 
        /* copy from dataflash if needed */
-       img_addr = gen_get_image (img_addr);
+       img_addr = genimg_get_image (img_addr);
 
        /* check image type, for FIT images get FIT kernel node */
-       switch (gen_image_get_format ((void *)img_addr)) {
+       *os_data = *os_len = 0;
+       switch (genimg_get_format ((void *)img_addr)) {
        case IMAGE_FORMAT_LEGACY:
-
-               debug ("*  kernel: legacy format image\n");
+               printf ("## Booting kernel from Legacy Image at %08lx ...\n",
+                               img_addr);
                hdr = image_get_kernel (img_addr, images->verify);
                if (!hdr)
                        return NULL;
                show_boot_progress (5);
 
+               /* get os_data and os_len */
                switch (image_get_type (hdr)) {
                case IH_TYPE_KERNEL:
                        *os_data = image_get_data (hdr);
@@ -434,21 +525,81 @@ static void *get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
                images->legacy_hdr_os = hdr;
                images->legacy_hdr_valid = 1;
 
+               show_boot_progress (6);
                break;
 #if defined(CONFIG_FIT)
        case IMAGE_FORMAT_FIT:
                fit_hdr = (void *)img_addr;
-               debug ("*  kernel: FIT format image\n");
-               fit_unsupported ("kernel");
-               return NULL;
+               printf ("## Booting kernel from FIT Image at %08lx ...\n",
+                               img_addr);
+
+               if (!fit_check_format (fit_hdr)) {
+                       puts ("Bad FIT kernel image format!\n");
+                       show_boot_progress (-100);
+                       return NULL;
+               }
+               show_boot_progress (100);
+
+               if (!fit_uname_kernel) {
+                       /*
+                        * no kernel image node unit name, try to get config
+                        * node first. If config unit node name is NULL
+                        * fit_conf_get_node() will try to find default config node
+                        */
+                       show_boot_progress (101);
+                       cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
+                       if (cfg_noffset < 0) {
+                               show_boot_progress (-101);
+                               return NULL;
+                       }
+                       /* save configuration uname provided in the first
+                        * bootm argument
+                        */
+                       images->fit_uname_cfg = fdt_get_name (fit_hdr, cfg_noffset, NULL);
+                       printf ("   Using '%s' configuration\n", images->fit_uname_cfg);
+                       show_boot_progress (103);
+
+                       os_noffset = fit_conf_get_kernel_node (fit_hdr, cfg_noffset);
+                       fit_uname_kernel = fit_get_name (fit_hdr, os_noffset, NULL);
+               } else {
+                       /* get kernel component image node offset */
+                       show_boot_progress (102);
+                       os_noffset = fit_image_get_node (fit_hdr, fit_uname_kernel);
+               }
+               if (os_noffset < 0) {
+                       show_boot_progress (-103);
+                       return NULL;
+               }
+
+               printf ("   Trying '%s' kernel subimage\n", fit_uname_kernel);
+
+               show_boot_progress (104);
+               if (!fit_check_kernel (fit_hdr, os_noffset, images->verify))
+                       return NULL;
+
+               /* get kernel image data address and length */
+               if (fit_image_get_data (fit_hdr, os_noffset, &data, &len)) {
+                       puts ("Could not find kernel subimage data!\n");
+                       show_boot_progress (-107);
+                       return NULL;
+               }
+               show_boot_progress (108);
+
+               *os_len = len;
+               *os_data = (ulong)data;
+               images->fit_hdr_os = fit_hdr;
+               images->fit_uname_os = fit_uname_kernel;
+               images->fit_noffset_os = os_noffset;
+               break;
 #endif
        default:
                printf ("Wrong Image Format for %s command\n", cmdtp->name);
+               show_boot_progress (-108);
                return NULL;
        }
 
-       debug ("   kernel data at 0x%08lx, end = 0x%08lx\n",
-                       *os_data, *os_data + *os_len);
+       debug ("   kernel data at 0x%08lx, len = 0x%08lx (%d)\n",
+                       *os_data, *os_len, *os_len);
 
        return (void *)img_addr;
 }
@@ -466,6 +617,14 @@ U_BOOT_CMD(
        "\tuse a '-' for the second argument. If you do not pass a third\n"
        "\ta bd_info struct will be passed instead\n"
 #endif
+#if defined(CONFIG_FIT)
+       "\t\nFor the new multi component uImage format (FIT) addresses\n"
+       "\tmust be extened to include component or configuration unit name:\n"
+       "\taddr:<subimg_uname> - direct component image specification\n"
+       "\taddr#<conf_uname>   - configuration specification\n"
+       "\tUse iminfo command to get the list of existing component\n"
+       "\timages and configurations.\n"
+#endif
 );
 
 /*******************************************************************/
@@ -531,7 +690,7 @@ static int image_info (ulong addr)
 
        printf ("\n## Checking Image at %08lx ...\n", addr);
 
-       switch (gen_image_get_format (hdr)) {
+       switch (genimg_get_format (hdr)) {
        case IMAGE_FORMAT_LEGACY:
                puts ("   Legacy image found\n");
                if (!image_check_magic (hdr)) {
@@ -556,7 +715,13 @@ static int image_info (ulong addr)
 #if defined(CONFIG_FIT)
        case IMAGE_FORMAT_FIT:
                puts ("   FIT image found\n");
-               fit_unsupported ("iminfo");
+
+               if (!fit_check_format (hdr)) {
+                       puts ("Bad FIT image format!\n");
+                       return 1;
+               }
+
+               fit_print_contents (hdr);
                return 0;
 #endif
        default:
@@ -599,11 +764,8 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                        if (!hdr)
                                goto next_sector;
 
-                       switch (gen_image_get_format (hdr)) {
+                       switch (genimg_get_format (hdr)) {
                        case IMAGE_FORMAT_LEGACY:
-                               if (!image_check_magic (hdr))
-                                       goto next_sector;
-
                                if (!image_check_hcrc (hdr))
                                        goto next_sector;
 
@@ -619,8 +781,11 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                                break;
 #if defined(CONFIG_FIT)
                        case IMAGE_FORMAT_FIT:
+                               if (!fit_check_format (hdr))
+                                       goto next_sector;
+
                                printf ("FIT Image at %08lX:\n", (ulong)hdr);
-                               fit_unsupported ("imls");
+                               fit_print_contents (hdr);
                                break;
 #endif
                        default: