uboot/tools/dumpimage.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Based on mkimage.c.
   4 *
   5 * Written by Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
   6 */
   7
   8#include "dumpimage.h"
   9#include <image.h>
  10#include <version.h>
  11
  12static void usage(void);
  13
  14/* parameters initialized by core will be used by the image type code */
  15static struct image_tool_params params = {
  16        .type = IH_TYPE_KERNEL,
  17};
  18
  19/*
  20 * dumpimage_extract_subimage -
  21 *
  22 * It scans all registered image types,
  23 * verifies image_header for each supported image type
  24 * if verification is successful, it extracts the desired file,
  25 * indexed by pflag, from the image
  26 *
  27 * returns negative if input image format does not match with any of
  28 * supported image types
  29 */
  30static int dumpimage_extract_subimage(struct image_type_params *tparams,
  31                void *ptr, struct stat *sbuf)
  32{
  33        int retval = -1;
  34
  35        if (tparams->verify_header) {
  36                retval = tparams->verify_header((unsigned char *)ptr,
  37                                sbuf->st_size, &params);
  38                if (retval != 0) {
  39                        fprintf(stderr, "%s: failed to verify header of %s\n",
  40                                params.cmdname, tparams->name);
  41                        return -1;
  42                }
  43
  44                /*
  45                 * Extract the file from the image
  46                 * if verify is successful
  47                 */
  48                if (tparams->extract_subimage) {
  49                        retval = tparams->extract_subimage(ptr, &params);
  50                        if (retval != 0) {
  51                                fprintf(stderr, "%s: extract_subimage failed for %s\n",
  52                                        params.cmdname, tparams->name);
  53                                return -3;
  54                        }
  55                } else {
  56                        fprintf(stderr,
  57                                "%s: extract_subimage undefined for %s\n",
  58                                params.cmdname, tparams->name);
  59                        return -2;
  60                }
  61        }
  62
  63        return retval;
  64}
  65
  66int main(int argc, char **argv)
  67{
  68        int opt;
  69        int ifd = -1;
  70        struct stat sbuf;
  71        char *ptr;
  72        int retval = EXIT_SUCCESS;
  73        struct image_type_params *tparams = NULL;
  74
  75        params.cmdname = *argv;
  76
  77        while ((opt = getopt(argc, argv, "hlo:T:p:V")) != -1) {
  78                switch (opt) {
  79                case 'l':
  80                        params.lflag = 1;
  81                        break;
  82                case 'o':
  83                        params.outfile = optarg;
  84                        params.iflag = 1;
  85                        break;
  86                case 'T':
  87                        params.type = genimg_get_type_id(optarg);
  88                        if (params.type < 0) {
  89                                fprintf(stderr, "%s: Invalid type\n",
  90                                        params.cmdname);
  91                                exit(EXIT_FAILURE);
  92                        }
  93                        break;
  94                case 'p':
  95                        params.pflag = strtoul(optarg, &ptr, 10);
  96                        if (*ptr) {
  97                                fprintf(stderr,
  98                                        "%s: invalid file position %s\n",
  99                                        params.cmdname, *argv);
 100                                exit(EXIT_FAILURE);
 101                        }
 102                        break;
 103                case 'V':
 104                        printf("dumpimage version %s\n", PLAIN_VERSION);
 105                        exit(EXIT_SUCCESS);
 106                case 'h':
 107                default:
 108                        usage();
 109                        break;
 110                }
 111        }
 112
 113        if (argc < 2)
 114                usage();
 115
 116        if (optind >= argc) {
 117                fprintf(stderr, "%s: image file missing\n", params.cmdname);
 118                exit(EXIT_FAILURE);
 119        }
 120
 121        params.imagefile = argv[optind];
 122
 123        /* set tparams as per input type_id */
 124        tparams = imagetool_get_type(params.type);
 125        if (tparams == NULL) {
 126                fprintf(stderr, "%s: unsupported type: %s\n",
 127                        params.cmdname, genimg_get_type_name(params.type));
 128                exit(EXIT_FAILURE);
 129        }
 130
 131        /*
 132         * check the passed arguments parameters meets the requirements
 133         * as per image type to be generated/listed
 134         */
 135        if (tparams->check_params) {
 136                if (tparams->check_params(&params)) {
 137                        fprintf(stderr, "%s: Parameter check failed\n",
 138                                params.cmdname);
 139                        exit(EXIT_FAILURE);
 140                }
 141        }
 142
 143        if (!params.lflag && !params.outfile) {
 144                fprintf(stderr, "%s: No output file provided\n",
 145                        params.cmdname);
 146                exit(EXIT_FAILURE);
 147        }
 148
 149        ifd = open(params.imagefile, O_RDONLY|O_BINARY);
 150        if (ifd < 0) {
 151                fprintf(stderr, "%s: Can't open \"%s\": %s\n", params.cmdname,
 152                        params.imagefile, strerror(errno));
 153                exit(EXIT_FAILURE);
 154        }
 155
 156        if (fstat(ifd, &sbuf) < 0) {
 157                fprintf(stderr, "%s: Can't stat \"%s\": %s\n", params.cmdname,
 158                        params.imagefile, strerror(errno));
 159                exit(EXIT_FAILURE);
 160        }
 161
 162        if ((uint32_t)sbuf.st_size < tparams->header_size) {
 163                fprintf(stderr, "%s: Bad size: \"%s\" is not valid image\n",
 164                        params.cmdname, params.imagefile);
 165                exit(EXIT_FAILURE);
 166        }
 167
 168        ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0);
 169        if (ptr == MAP_FAILED) {
 170                fprintf(stderr, "%s: Can't read \"%s\": %s\n", params.cmdname,
 171                        params.imagefile, strerror(errno));
 172                exit(EXIT_FAILURE);
 173        }
 174
 175        /*
 176         * Both calls bellow scan through dumpimage registry for all
 177         * supported image types and verify the input image file
 178         * header for match
 179         */
 180        if (params.iflag) {
 181                /*
 182                 * Extract the data files from within the matched
 183                 * image type. Returns the error code if not matched
 184                 */
 185                retval = dumpimage_extract_subimage(tparams, ptr, &sbuf);
 186                if (retval)
 187                        fprintf(stderr, "%s: Can't extract subimage from %s\n",
 188                                params.cmdname, params.imagefile);
 189        } else {
 190                /*
 191                 * Print the image information for matched image type
 192                 * Returns the error code if not matched
 193                 */
 194                retval = imagetool_verify_print_header(ptr, &sbuf, tparams,
 195                                                       &params);
 196        }
 197
 198        (void)munmap((void *)ptr, sbuf.st_size);
 199        (void)close(ifd);
 200
 201        return retval;
 202}
 203
 204static void usage(void)
 205{
 206        fprintf(stderr, "Usage: %s -l image\n"
 207                "          -l ==> list image header information\n",
 208                params.cmdname);
 209        fprintf(stderr,
 210                "       %s [-T type] [-p position] [-o outfile] image\n"
 211                "          -T ==> declare image type as 'type'\n"
 212                "          -p ==> 'position' (starting at 0) of the component to extract from image\n"
 213                "          -o ==> extract component to file 'outfile'\n",
 214                params.cmdname);
 215        fprintf(stderr,
 216                "       %s -h ==> print usage information and exit\n",
 217                params.cmdname);
 218        fprintf(stderr,
 219                "       %s -V ==> print version information and exit\n",
 220                params.cmdname);
 221
 222        exit(EXIT_SUCCESS);
 223}
 224