]> git.sur5r.net Git - u-boot/commitdiff
add ability to handle compressed images to imxtract
authorWolfgang Wegner <w.wegner@astro-kom.de>
Thu, 10 Dec 2009 09:11:21 +0000 (10:11 +0100)
committerWolfgang Denk <wd@denx.de>
Tue, 26 Jan 2010 18:36:07 +0000 (19:36 +0100)
imxtract currently can not handle compressed images. This patch adds
handling for bzip2 and zip compression. In both cases, a destination
address has to be specified for extraction.

Signed-off-by: Wolfgang Wegner <w.wegner@astro-kom.de>
common/cmd_ximg.c

index 5593b2d24b7ab8f417cea3f4dc511320df9e5240..3e5fb44475b60fb98a228a8b40c8a15b3bdb85da 100644 (file)
 #include <common.h>
 #include <command.h>
 #include <image.h>
+#include <watchdog.h>
+#if defined(CONFIG_BZIP2)
+#include <bzlib.h>
+#endif
 #include <asm/byteorder.h>
 
+#ifndef CONFIG_SYS_XIMG_LEN
+/* use 8MByte as default max gunzip size */
+#define CONFIG_SYS_XIMG_LEN    0x800000
+#endif
+
 int
 do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 {
@@ -50,6 +59,8 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
        const void      *fit_data;
        size_t          fit_len;
 #endif
+       uint            unc_len = CONFIG_SYS_XIMG_LEN;
+       uint8_t         comp;
 
        verify = getenv_yesno ("verify");
 
@@ -92,8 +103,10 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                        return 1;
                }
 
-               if (image_get_comp (hdr) != IH_COMP_NONE) {
-                       printf("Wrong Compression Type for %s command\n",
+               comp = image_get_comp (hdr);
+               if ((comp != IH_COMP_NONE) && (argc < 4)) {
+                       printf("Must specify load address for %s command "
+                                       "with compressed image\n",
                                        cmdtp->name);
                        return 1;
                }
@@ -138,9 +151,11 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                        return 1;
                }
 
-               if (fit_image_check_comp (fit_hdr, noffset, IH_COMP_NONE)) {
-                       printf("Wrong Compression Type for %s command\n",
-                                       cmdtp->name);
+               if (fit_image_check_comp (fit_hdr, noffset, IH_COMP_NONE)
+                   && (argc < 4)) {
+                       printf("Must specify load address for %s command "
+                               "with compressed image\n",
+                               cmdtp->name);
                        return 1;
                }
 
@@ -153,11 +168,18 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                }
 
                /* get subimage data address and length */
-               if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) {
+               if (fit_image_get_data (fit_hdr, noffset,
+                                       &fit_data, &fit_len)) {
                        puts ("Could not find script subimage data\n");
                        return 1;
                }
 
+               if (fit_image_get_comp (fit_hdr, noffset, &comp)) {
+                       puts ("Could not find script subimage "
+                               "compression type\n");
+                       return 1;
+               }
+
                data = (ulong)fit_data;
                len = (ulong)fit_len;
                break;
@@ -168,7 +190,63 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
        }
 
        if (argc > 3) {
-               memcpy((char *) dest, (char *) data, len);
+               switch (comp) {
+               case IH_COMP_NONE:
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+                       {
+                               size_t l = len;
+                               size_t tail;
+                               void *to = (void *) dest;
+                               void *from = (void *)data;
+
+                               printf ("   Loading part %d ... ", part);
+
+                               while (l > 0) {
+                                       tail = (l > CHUNKSZ) ? CHUNKSZ : l;
+                                       WATCHDOG_RESET();
+                                       memmove (to, from, tail);
+                                       to += tail;
+                                       from += tail;
+                                       l -= tail;
+                               }
+                       }
+#else  /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
+                       printf ("   Loading part %d ... ", part);
+                       memmove ((char *) dest, (char *)data, len);
+#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
+                       break;
+               case IH_COMP_GZIP:
+                       printf ("   Uncompressing part %d ... ", part);
+                       if (gunzip ((void *) dest, unc_len,
+                                   (uchar *) data, &len) != 0) {
+                               puts ("GUNZIP ERROR - image not loaded\n");
+                               return 1;
+                       }
+                       break;
+#if defined(CONFIG_BZIP2)
+               case IH_COMP_BZIP2:
+                       printf ("   Uncompressing part %d ... ", part);
+                       /*
+                        * If we've got less than 4 MB of malloc() space,
+                        * use slower decompression algorithm which requires
+                        * at most 2300 KB of memory.
+                        */
+                       i = BZ2_bzBuffToBuffDecompress
+                               ((char*)ntohl(hdr->ih_load),
+                                &unc_len, (char *)data, len,
+                                CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
+                       if (i != BZ_OK) {
+                               printf ("BUNZIP2 ERROR %d - "
+                                       "image not loaded\n", i);
+                               return 1;
+                       }
+                       break;
+#endif /* CONFIG_BZIP2 */
+               default:
+                       printf ("Unimplemented compression type %d\n", comp);
+                       return 1;
+               }
+               puts ("OK\n");
        }
 
        sprintf(pbuf, "%8lx", data);