uboot/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 * SPDX-License-Identifier:     GPL-2.0+
   9 */
  10
  11
  12/*
  13 * Multi Image extract
  14 */
  15#include <common.h>
  16#include <command.h>
  17#include <image.h>
  18#include <mapmem.h>
  19#include <watchdog.h>
  20#if defined(CONFIG_BZIP2)
  21#include <bzlib.h>
  22#endif
  23#include <asm/byteorder.h>
  24#include <asm/io.h>
  25
  26#ifndef CONFIG_SYS_XIMG_LEN
  27/* use 8MByte as default max gunzip size */
  28#define CONFIG_SYS_XIMG_LEN     0x800000
  29#endif
  30
  31static int
  32do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
  33{
  34        ulong           addr = load_addr;
  35        ulong           dest = 0;
  36        ulong           data, len;
  37        int             verify;
  38        int             part = 0;
  39#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
  40        ulong           count;
  41        image_header_t  *hdr = NULL;
  42#endif
  43#if defined(CONFIG_FIT)
  44        const char      *uname = NULL;
  45        const void*     fit_hdr;
  46        int             noffset;
  47        const void      *fit_data;
  48        size_t          fit_len;
  49#endif
  50#ifdef CONFIG_GZIP
  51        uint            unc_len = CONFIG_SYS_XIMG_LEN;
  52#endif
  53        uint8_t         comp;
  54
  55        verify = getenv_yesno("verify");
  56
  57        if (argc > 1) {
  58                addr = simple_strtoul(argv[1], NULL, 16);
  59        }
  60        if (argc > 2) {
  61                part = simple_strtoul(argv[2], NULL, 16);
  62#if defined(CONFIG_FIT)
  63                uname = argv[2];
  64#endif
  65        }
  66        if (argc > 3) {
  67                dest = simple_strtoul(argv[3], NULL, 16);
  68        }
  69
  70        switch (genimg_get_format((void *)addr)) {
  71#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
  72        case IMAGE_FORMAT_LEGACY:
  73
  74                printf("## Copying part %d from legacy image "
  75                        "at %08lx ...\n", part, addr);
  76
  77                hdr = (image_header_t *)addr;
  78                if (!image_check_magic(hdr)) {
  79                        printf("Bad Magic Number\n");
  80                        return 1;
  81                }
  82
  83                if (!image_check_hcrc(hdr)) {
  84                        printf("Bad Header Checksum\n");
  85                        return 1;
  86                }
  87#ifdef DEBUG
  88                image_print_contents(hdr);
  89#endif
  90
  91                if (!image_check_type(hdr, IH_TYPE_MULTI) &&
  92                    !image_check_type(hdr, IH_TYPE_SCRIPT)) {
  93                        printf("Wrong Image Type for %s command\n",
  94                                        cmdtp->name);
  95                        return 1;
  96                }
  97
  98                comp = image_get_comp(hdr);
  99                if ((comp != IH_COMP_NONE) && (argc < 4)) {
 100                        printf("Must specify load address for %s command "
 101                                        "with compressed image\n",
 102                                        cmdtp->name);
 103                        return 1;
 104                }
 105
 106                if (verify) {
 107                        printf("   Verifying Checksum ... ");
 108                        if (!image_check_dcrc(hdr)) {
 109                                printf("Bad Data CRC\n");
 110                                return 1;
 111                        }
 112                        printf("OK\n");
 113                }
 114
 115                count = image_multi_count(hdr);
 116                if (part >= count) {
 117                        printf("Bad Image Part\n");
 118                        return 1;
 119                }
 120
 121                image_multi_getimg(hdr, part, &data, &len);
 122                break;
 123#endif
 124#if defined(CONFIG_FIT)
 125        case IMAGE_FORMAT_FIT:
 126                if (uname == NULL) {
 127                        puts("No FIT subimage unit name\n");
 128                        return 1;
 129                }
 130
 131                printf("## Copying '%s' subimage from FIT image "
 132                        "at %08lx ...\n", uname, addr);
 133
 134                fit_hdr = (const void *)addr;
 135                if (!fit_check_format(fit_hdr)) {
 136                        puts("Bad FIT image format\n");
 137                        return 1;
 138                }
 139
 140                /* get subimage node offset */
 141                noffset = fit_image_get_node(fit_hdr, uname);
 142                if (noffset < 0) {
 143                        printf("Can't find '%s' FIT subimage\n", uname);
 144                        return 1;
 145                }
 146
 147                if (fit_image_check_comp(fit_hdr, noffset, IH_COMP_NONE)
 148                    && (argc < 4)) {
 149                        printf("Must specify load address for %s command "
 150                                "with compressed image\n",
 151                                cmdtp->name);
 152                        return 1;
 153                }
 154
 155                /* verify integrity */
 156                if (verify) {
 157                        if (!fit_image_verify(fit_hdr, noffset)) {
 158                                puts("Bad Data Hash\n");
 159                                return 1;
 160                        }
 161                }
 162
 163                /* get subimage data address and length */
 164                if (fit_image_get_data(fit_hdr, noffset,
 165                                        &fit_data, &fit_len)) {
 166                        puts("Could not find script subimage data\n");
 167                        return 1;
 168                }
 169
 170                if (fit_image_get_comp(fit_hdr, noffset, &comp)) {
 171                        puts("Could not find script subimage "
 172                                "compression type\n");
 173                        return 1;
 174                }
 175
 176                data = (ulong)fit_data;
 177                len = (ulong)fit_len;
 178                break;
 179#endif
 180        default:
 181                puts("Invalid image type for imxtract\n");
 182                return 1;
 183        }
 184
 185        if (argc > 3) {
 186                switch (comp) {
 187                case IH_COMP_NONE:
 188#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
 189                        {
 190                                size_t l = len;
 191                                size_t tail;
 192                                void *to = (void *) dest;
 193                                void *from = (void *)data;
 194
 195                                printf("   Loading part %d ... ", part);
 196
 197                                while (l > 0) {
 198                                        tail = (l > CHUNKSZ) ? CHUNKSZ : l;
 199                                        WATCHDOG_RESET();
 200                                        memmove(to, from, tail);
 201                                        to += tail;
 202                                        from += tail;
 203                                        l -= tail;
 204                                }
 205                        }
 206#else   /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
 207                        printf("   Loading part %d ... ", part);
 208                        memmove((char *) dest, (char *)data, len);
 209#endif  /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
 210                        break;
 211#ifdef CONFIG_GZIP
 212                case IH_COMP_GZIP:
 213                        printf("   Uncompressing part %d ... ", part);
 214                        if (gunzip((void *) dest, unc_len,
 215                                   (uchar *) data, &len) != 0) {
 216                                puts("GUNZIP ERROR - image not loaded\n");
 217                                return 1;
 218                        }
 219                        break;
 220#endif
 221#if defined(CONFIG_BZIP2) && defined(CONFIG_IMAGE_FORMAT_LEGACY)
 222                case IH_COMP_BZIP2:
 223                        {
 224                                int i;
 225
 226                                printf("   Uncompressing part %d ... ", part);
 227                                /*
 228                                 * If we've got less than 4 MB of malloc()
 229                                 * space, use slower decompression algorithm
 230                                 * which requires at most 2300 KB of memory.
 231                                 */
 232                                i = BZ2_bzBuffToBuffDecompress(
 233                                        map_sysmem(ntohl(hdr->ih_load), 0),
 234                                        &unc_len, (char *)data, len,
 235                                        CONFIG_SYS_MALLOC_LEN < (4096 * 1024),
 236                                        0);
 237                                if (i != BZ_OK) {
 238                                        printf("BUNZIP2 ERROR %d - "
 239                                                "image not loaded\n", i);
 240                                        return 1;
 241                                }
 242                        }
 243                        break;
 244#endif /* CONFIG_BZIP2 */
 245                default:
 246                        printf("Unimplemented compression type %d\n", comp);
 247                        return 1;
 248                }
 249                puts("OK\n");
 250        }
 251
 252        flush_cache(dest, len);
 253
 254        setenv_hex("fileaddr", data);
 255        setenv_hex("filesize", len);
 256
 257        return 0;
 258}
 259
 260#ifdef CONFIG_SYS_LONGHELP
 261static char imgextract_help_text[] =
 262        "addr part [dest]\n"
 263        "    - extract <part> from legacy image at <addr> and copy to <dest>"
 264#if defined(CONFIG_FIT)
 265        "\n"
 266        "addr uname [dest]\n"
 267        "    - extract <uname> subimage from FIT image at <addr> and copy to <dest>"
 268#endif
 269        "";
 270#endif
 271
 272U_BOOT_CMD(
 273        imxtract, 4, 1, do_imgextract,
 274        "extract a part of a multi-image", imgextract_help_text
 275);
 276