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