uboot/common/cmd_ximg.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000-2004
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * (C) Copyright 2003
   6 * Kai-Uwe Bloem, Auerswald GmbH & Co KG, <linux-development@auerswald.de>
   7 *
   8 * See file CREDITS for list of people who contributed to this
   9 * project.
  10 *
  11 * This program is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU General Public License as
  13 * published by the Free Software Foundation; either version 2 of
  14 * the License, or (at your option) any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 * GNU General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24 * MA 02111-1307 USA
  25 */
  26
  27
  28/*
  29 * Multi Image extract
  30 */
  31#include <common.h>
  32#include <command.h>
  33#include <image.h>
  34#include <watchdog.h>
  35#if defined(CONFIG_BZIP2)
  36#include <bzlib.h>
  37#endif
  38#include <asm/byteorder.h>
  39
  40#ifndef CONFIG_SYS_XIMG_LEN
  41/* use 8MByte as default max gunzip size */
  42#define CONFIG_SYS_XIMG_LEN     0x800000
  43#endif
  44
  45int
  46do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
  47{
  48        ulong           addr = load_addr;
  49        ulong           dest = 0;
  50        ulong           data, len, count;
  51        int             verify;
  52        int             part = 0;
  53        char            pbuf[10];
  54        image_header_t  *hdr;
  55#if defined(CONFIG_FIT)
  56        const char      *uname = NULL;
  57        const void*     fit_hdr;
  58        int             noffset;
  59        const void      *fit_data;
  60        size_t          fit_len;
  61#endif
  62        uint            unc_len = CONFIG_SYS_XIMG_LEN;
  63        uint8_t         comp;
  64
  65        verify = getenv_yesno("verify");
  66
  67        if (argc > 1) {
  68                addr = simple_strtoul(argv[1], NULL, 16);
  69        }
  70        if (argc > 2) {
  71                part = simple_strtoul(argv[2], NULL, 16);
  72#if defined(CONFIG_FIT)
  73                uname = argv[2];
  74#endif
  75        }
  76        if (argc > 3) {
  77                dest = simple_strtoul(argv[3], NULL, 16);
  78        }
  79
  80        switch (genimg_get_format((void *)addr)) {
  81        case IMAGE_FORMAT_LEGACY:
  82
  83                printf("## Copying part %d from legacy image "
  84                        "at %08lx ...\n", part, addr);
  85
  86                hdr = (image_header_t *)addr;
  87                if (!image_check_magic(hdr)) {
  88                        printf("Bad Magic Number\n");
  89                        return 1;
  90                }
  91
  92                if (!image_check_hcrc(hdr)) {
  93                        printf("Bad Header Checksum\n");
  94                        return 1;
  95                }
  96#ifdef DEBUG
  97                image_print_contents(hdr);
  98#endif
  99
 100                if (!image_check_type(hdr, IH_TYPE_MULTI)) {
 101                        printf("Wrong Image Type for %s command\n",
 102                                        cmdtp->name);
 103                        return 1;
 104                }
 105
 106                comp = image_get_comp(hdr);
 107                if ((comp != IH_COMP_NONE) && (argc < 4)) {
 108                        printf("Must specify load address for %s command "
 109                                        "with compressed image\n",
 110                                        cmdtp->name);
 111                        return 1;
 112                }
 113
 114                if (verify) {
 115                        printf("   Verifying Checksum ... ");
 116                        if (!image_check_dcrc(hdr)) {
 117                                printf("Bad Data CRC\n");
 118                                return 1;
 119                        }
 120                        printf("OK\n");
 121                }
 122
 123                count = image_multi_count(hdr);
 124                if (part >= count) {
 125                        printf("Bad Image Part\n");
 126                        return 1;
 127                }
 128
 129                image_multi_getimg(hdr, part, &data, &len);
 130                break;
 131#if defined(CONFIG_FIT)
 132        case IMAGE_FORMAT_FIT:
 133                if (uname == NULL) {
 134                        puts("No FIT subimage unit name\n");
 135                        return 1;
 136                }
 137
 138                printf("## Copying '%s' subimage from FIT image "
 139                        "at %08lx ...\n", uname, addr);
 140
 141                fit_hdr = (const void *)addr;
 142                if (!fit_check_format(fit_hdr)) {
 143                        puts("Bad FIT image format\n");
 144                        return 1;
 145                }
 146
 147                /* get subimage node offset */
 148                noffset = fit_image_get_node(fit_hdr, uname);
 149                if (noffset < 0) {
 150                        printf("Can't find '%s' FIT subimage\n", uname);
 151                        return 1;
 152                }
 153
 154                if (fit_image_check_comp(fit_hdr, noffset, IH_COMP_NONE)
 155                    && (argc < 4)) {
 156                        printf("Must specify load address for %s command "
 157                                "with compressed image\n",
 158                                cmdtp->name);
 159                        return 1;
 160                }
 161
 162                /* verify integrity */
 163                if (verify) {
 164                        if (!fit_image_check_hashes(fit_hdr, noffset)) {
 165                                puts("Bad Data Hash\n");
 166                                return 1;
 167                        }
 168                }
 169
 170                /* get subimage data address and length */
 171                if (fit_image_get_data(fit_hdr, noffset,
 172                                        &fit_data, &fit_len)) {
 173                        puts("Could not find script subimage data\n");
 174                        return 1;
 175                }
 176
 177                if (fit_image_get_comp(fit_hdr, noffset, &comp)) {
 178                        puts("Could not find script subimage "
 179                                "compression type\n");
 180                        return 1;
 181                }
 182
 183                data = (ulong)fit_data;
 184                len = (ulong)fit_len;
 185                break;
 186#endif
 187        default:
 188                puts("Invalid image type for imxtract\n");
 189                return 1;
 190        }
 191
 192        if (argc > 3) {
 193                switch (comp) {
 194                case IH_COMP_NONE:
 195#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
 196                        {
 197                                size_t l = len;
 198                                size_t tail;
 199                                void *to = (void *) dest;
 200                                void *from = (void *)data;
 201
 202                                printf("   Loading part %d ... ", part);
 203
 204                                while (l > 0) {
 205                                        tail = (l > CHUNKSZ) ? CHUNKSZ : l;
 206                                        WATCHDOG_RESET();
 207                                        memmove(to, from, tail);
 208                                        to += tail;
 209                                        from += tail;
 210                                        l -= tail;
 211                                }
 212                        }
 213#else   /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
 214                        printf("   Loading part %d ... ", part);
 215                        memmove((char *) dest, (char *)data, len);
 216#endif  /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
 217                        break;
 218#ifdef CONFIG_GZIP
 219                case IH_COMP_GZIP:
 220                        printf("   Uncompressing part %d ... ", part);
 221                        if (gunzip((void *) dest, unc_len,
 222                                   (uchar *) data, &len) != 0) {
 223                                puts("GUNZIP ERROR - image not loaded\n");
 224                                return 1;
 225                        }
 226                        break;
 227#endif
 228#if defined(CONFIG_BZIP2)
 229                case IH_COMP_BZIP2:
 230                        {
 231                                int i;
 232
 233                                printf("   Uncompressing part %d ... ", part);
 234                                /*
 235                                 * If we've got less than 4 MB of malloc()
 236                                 * space, use slower decompression algorithm
 237                                 * which requires at most 2300 KB of memory.
 238                                 */
 239                                i = BZ2_bzBuffToBuffDecompress(
 240                                        (char *)ntohl(hdr->ih_load),
 241                                        &unc_len, (char *)data, len,
 242                                        CONFIG_SYS_MALLOC_LEN < (4096 * 1024),
 243                                        0);
 244                                if (i != BZ_OK) {
 245                                        printf("BUNZIP2 ERROR %d - "
 246                                                "image not loaded\n", i);
 247                                        return 1;
 248                                }
 249                        }
 250                        break;
 251#endif /* CONFIG_BZIP2 */
 252                default:
 253                        printf("Unimplemented compression type %d\n", comp);
 254                        return 1;
 255                }
 256                puts("OK\n");
 257        }
 258
 259        sprintf(pbuf, "%8lx", data);
 260        setenv("fileaddr", pbuf);
 261        sprintf(pbuf, "%8lx", len);
 262        setenv("filesize", pbuf);
 263
 264        return 0;
 265}
 266
 267U_BOOT_CMD(
 268        imxtract, 4, 1, do_imgextract,
 269        "extract a part of a multi-image",
 270        "addr part [dest]\n"
 271        "    - extract <part> from legacy image at <addr> and copy to <dest>"
 272#if defined(CONFIG_FIT)
 273        "\n"
 274        "addr uname [dest]\n"
 275        "    - extract <uname> subimage from FIT image at <addr> and copy to <dest>"
 276#endif
 277);
 278