X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=tools%2Fmkimage.c;h=d312844e9c303abf66592ff3b4e1aa7b5efa2533;hb=5a34d9bf31a021987f97f20aefa812b97b58584e;hp=6e1ff2b1e2f12ca0c0da28c272bc56a0b16f78f9;hpb=27f33e9f45ef7f9685cbdc65066a1828e85dde4f;p=karo-tx-uboot.git diff --git a/tools/mkimage.c b/tools/mkimage.c index 6e1ff2b1e2..d312844e9c 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -1,10 +1,9 @@ /* * (C) Copyright 2008 Semihalf * - * (C) Copyright 2000-2004 + * (C) Copyright 2000-2009 * DENX Software Engineering * Wolfgang Denk, wd@denx.de - * All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -24,131 +23,276 @@ #include "mkimage.h" #include +#include -extern int errno; +static void copy_file(int, const char *, int); +static void usage(void); -#ifndef MAP_FAILED -#define MAP_FAILED (-1) -#endif +/* image_type_params link list to maintain registered image type supports */ +struct image_type_params *mkimage_tparams = NULL; + +/* parameters initialized by core will be used by the image type code */ +struct mkimage_params params = { + .os = IH_OS_LINUX, + .arch = IH_ARCH_PPC, + .type = IH_TYPE_KERNEL, + .comp = IH_COMP_GZIP, + .dtc = MKIMAGE_DEFAULT_DTC_OPTIONS, + .imagename = "", + .imagename2 = "", +}; + +/* + * mkimage_register - + * + * It is used to register respective image generation/list support to the + * mkimage core + * + * the input struct image_type_params is checked and appended to the link + * list, if the input structure is already registered, error + */ +void mkimage_register (struct image_type_params *tparams) +{ + struct image_type_params **tp; + + if (!tparams) { + fprintf (stderr, "%s: %s: Null input\n", + params.cmdname, __FUNCTION__); + exit (EXIT_FAILURE); + } + + /* scan the linked list, check for registry and point the last one */ + for (tp = &mkimage_tparams; *tp != NULL; tp = &(*tp)->next) { + if (!strcmp((*tp)->name, tparams->name)) { + fprintf (stderr, "%s: %s already registered\n", + params.cmdname, tparams->name); + return; + } + } + + /* add input struct entry at the end of link list */ + *tp = tparams; + /* mark input entry as last entry in the link list */ + tparams->next = NULL; + + debug ("Registered %s\n", tparams->name); +} + +/* + * mkimage_get_type - + * + * It scans all registers image type supports + * checks the input type_id for each supported image type + * + * if successful, + * returns respective image_type_params pointer if success + * if input type_id is not supported by any of image_type_support + * returns NULL + */ +struct image_type_params *mkimage_get_type(int type) +{ + struct image_type_params *curr; + + for (curr = mkimage_tparams; curr != NULL; curr = curr->next) { + if (curr->check_image_type) { + if (!curr->check_image_type (type)) + return curr; + } + } + return NULL; +} -extern unsigned long crc32 (unsigned long crc, const char *buf, unsigned int len); -static void copy_file (int, const char *, int); -static void usage (void); -static void image_verify_header (char *, int); -static void fit_handle_file (void); - -char *datafile; -char *imagefile; -char *cmdname; - -int dflag = 0; -int eflag = 0; -int fflag = 0; -int lflag = 0; -int vflag = 0; -int xflag = 0; -int opt_os = IH_OS_LINUX; -int opt_arch = IH_ARCH_PPC; -int opt_type = IH_TYPE_KERNEL; -int opt_comp = IH_COMP_GZIP; -char *opt_dtc = MKIMAGE_DEFAULT_DTC_OPTIONS; - -image_header_t header; -image_header_t *hdr = &header; +/* + * mkimage_verify_print_header - + * + * It scans mkimage_tparams link list, + * verifies image_header for each supported image type + * if verification is successful, prints respective header + * + * returns negative if input image format does not match with any of + * supported image types + */ +int mkimage_verify_print_header (void *ptr, struct stat *sbuf) +{ + int retval = -1; + struct image_type_params *curr; + + for (curr = mkimage_tparams; curr != NULL; curr = curr->next ) { + if (curr->verify_header) { + retval = curr->verify_header ( + (unsigned char *)ptr, sbuf->st_size, + ¶ms); + + if (retval == 0) { + /* + * Print the image information + * if verify is successful + */ + if (curr->print_header) + curr->print_header (ptr); + else { + fprintf (stderr, + "%s: print_header undefined for %s\n", + params.cmdname, curr->name); + } + break; + } + } + } + return retval; +} int main (int argc, char **argv) { int ifd = -1; - uint32_t checksum; - uint32_t addr; - uint32_t ep; struct stat sbuf; - unsigned char *ptr; - char *name = ""; - - cmdname = *argv; - - addr = ep = 0; + char *ptr; + int retval = 0; + struct image_type_params *tparams = NULL; + + /* Init Freescale PBL Boot image generation/list support */ + init_pbl_image_type(); + /* Init Kirkwood Boot image generation/list support */ + init_kwb_image_type (); + /* Init Freescale imx Boot image generation/list support */ + init_imx_image_type (); + /* Init FIT image generation/list support */ + init_fit_image_type (); + /* Init TI OMAP Boot image generation/list support */ + init_omap_image_type(); + /* Init Default image generation/list support */ + init_default_image_type (); + /* Init Davinci UBL support */ + init_ubl_image_type(); + /* Init Davinci AIS support */ + init_ais_image_type(); + + params.cmdname = *argv; + params.addr = params.ep = 0; while (--argc > 0 && **++argv == '-') { while (*++*argv) { switch (**argv) { case 'l': - lflag = 1; + params.lflag = 1; break; case 'A': if ((--argc <= 0) || - (opt_arch = genimg_get_arch_id (*++argv)) < 0) + (params.arch = + genimg_get_arch_id (*++argv)) < 0) usage (); goto NXTARG; + case 'c': + if (--argc <= 0) + usage(); + params.comment = *++argv; + goto NXTARG; case 'C': if ((--argc <= 0) || - (opt_comp = genimg_get_comp_id (*++argv)) < 0) + (params.comp = + genimg_get_comp_id (*++argv)) < 0) usage (); goto NXTARG; case 'D': if (--argc <= 0) usage (); - opt_dtc = *++argv; + params.dtc = *++argv; goto NXTARG; case 'O': if ((--argc <= 0) || - (opt_os = genimg_get_os_id (*++argv)) < 0) + (params.os = + genimg_get_os_id (*++argv)) < 0) usage (); goto NXTARG; case 'T': if ((--argc <= 0) || - (opt_type = genimg_get_type_id (*++argv)) < 0) + (params.type = + genimg_get_type_id (*++argv)) < 0) usage (); goto NXTARG; case 'a': if (--argc <= 0) usage (); - addr = strtoul (*++argv, (char **)&ptr, 16); + params.addr = strtoul (*++argv, &ptr, 16); if (*ptr) { fprintf (stderr, "%s: invalid load address %s\n", - cmdname, *argv); + params.cmdname, *argv); exit (EXIT_FAILURE); } goto NXTARG; case 'd': if (--argc <= 0) usage (); - datafile = *++argv; - dflag = 1; + params.datafile = *++argv; + params.dflag = 1; goto NXTARG; case 'e': if (--argc <= 0) usage (); - ep = strtoul (*++argv, (char **)&ptr, 16); + params.ep = strtoul (*++argv, &ptr, 16); if (*ptr) { fprintf (stderr, "%s: invalid entry point %s\n", - cmdname, *argv); + params.cmdname, *argv); exit (EXIT_FAILURE); } - eflag = 1; + params.eflag = 1; goto NXTARG; case 'f': if (--argc <= 0) usage (); - datafile = *++argv; - fflag = 1; + params.datafile = *++argv; + /* no break */ + case 'F': + /* + * The flattened image tree (FIT) format + * requires a flattened device tree image type + */ + params.type = IH_TYPE_FLATDT; + params.fflag = 1; + goto NXTARG; + case 'k': + if (--argc <= 0) + usage(); + params.keydir = *++argv; + goto NXTARG; + case 'K': + if (--argc <= 0) + usage(); + params.keydest = *++argv; goto NXTARG; case 'n': if (--argc <= 0) usage (); - name = *++argv; + params.imagename = *++argv; + goto NXTARG; + case 'r': + params.require_keys = 1; + break; + case 'R': + if (--argc <= 0) + usage(); + /* + * This entry is for the second configuration + * file, if only one is not enough. + */ + params.imagename2 = *++argv; goto NXTARG; + case 's': + params.skipcpy = 1; + break; case 'v': - vflag++; + params.vflag++; break; + case 'V': + printf("mkimage version %s\n", PLAIN_VERSION); + exit(EXIT_SUCCESS); case 'x': - xflag++; + params.xflag++; break; default: usage (); @@ -157,168 +301,190 @@ main (int argc, char **argv) NXTARG: ; } - if ((argc != 1) || - (dflag && (fflag || lflag)) || - (fflag && (dflag || lflag)) || - (lflag && (dflag || fflag))) - usage(); + if (argc != 1) + usage (); - if (!eflag) { - ep = addr; - /* If XIP, entry point must be after the U-Boot header */ - if (xflag) - ep += image_get_header_size (); + /* set tparams as per input type_id */ + tparams = mkimage_get_type(params.type); + if (tparams == NULL) { + fprintf (stderr, "%s: unsupported type %s\n", + params.cmdname, genimg_get_type_name(params.type)); + exit (EXIT_FAILURE); } /* - * If XIP, ensure the entry point is equal to the load address plus - * the size of the U-Boot header. + * check the passed arguments parameters meets the requirements + * as per image type to be generated/listed */ - if (xflag) { - if (ep != addr + image_get_header_size ()) { - fprintf (stderr, - "%s: For XIP, the entry point must be the load addr + %lu\n", - cmdname, - (unsigned long)image_get_header_size ()); - exit (EXIT_FAILURE); - } + if (tparams->check_params) + if (tparams->check_params (¶ms)) + usage (); + + if (!params.eflag) { + params.ep = params.addr; + /* If XIP, entry point must be after the U-Boot header */ + if (params.xflag) + params.ep += tparams->header_size; } - imagefile = *argv; + params.imagefile = *argv; - if (!fflag){ - if (lflag) { - ifd = open (imagefile, O_RDONLY|O_BINARY); - } else { - ifd = open (imagefile, - O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666); - } + if (params.fflag){ + if (tparams->fflag_handle) + /* + * in some cases, some additional processing needs + * to be done if fflag is defined + * + * For ex. fit_handle_file for Fit file support + */ + retval = tparams->fflag_handle(¶ms); - if (ifd < 0) { - fprintf (stderr, "%s: Can't open %s: %s\n", - cmdname, imagefile, strerror(errno)); - exit (EXIT_FAILURE); - } + if (retval != EXIT_SUCCESS) + exit (retval); + } + + if (params.lflag || params.fflag) { + ifd = open (params.imagefile, O_RDONLY|O_BINARY); + } else { + ifd = open (params.imagefile, + O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666); + } + + if (ifd < 0) { + fprintf (stderr, "%s: Can't open %s: %s\n", + params.cmdname, params.imagefile, + strerror(errno)); + exit (EXIT_FAILURE); } - if (lflag) { + if (params.lflag || params.fflag) { /* * list header information of existing image */ if (fstat(ifd, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", - cmdname, imagefile, strerror(errno)); + params.cmdname, params.imagefile, + strerror(errno)); exit (EXIT_FAILURE); } - if ((unsigned)sbuf.st_size < image_get_header_size ()) { + if ((unsigned)sbuf.st_size < tparams->header_size) { fprintf (stderr, - "%s: Bad size: \"%s\" is no valid image\n", - cmdname, imagefile); + "%s: Bad size: \"%s\" is not valid image\n", + params.cmdname, params.imagefile); exit (EXIT_FAILURE); } - ptr = (unsigned char *)mmap(0, sbuf.st_size, - PROT_READ, MAP_SHARED, ifd, 0); - if ((caddr_t)ptr == (caddr_t)-1) { + ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0); + if (ptr == MAP_FAILED) { fprintf (stderr, "%s: Can't read %s: %s\n", - cmdname, imagefile, strerror(errno)); + params.cmdname, params.imagefile, + strerror(errno)); exit (EXIT_FAILURE); } - if (fdt_check_header (ptr)) { - /* old-style image */ - image_verify_header ((char *)ptr, sbuf.st_size); - image_print_contents_noindent ((image_header_t *)ptr); - } else { - /* FIT image */ - fit_print_contents_noindent (ptr); - } + /* + * scan through mkimage registry for all supported image types + * and verify the input image file header for match + * Print the image information for matched image type + * Returns the error code if not matched + */ + retval = mkimage_verify_print_header (ptr, &sbuf); (void) munmap((void *)ptr, sbuf.st_size); (void) close (ifd); - exit (EXIT_SUCCESS); - } else if (fflag) { - /* Flattened Image Tree (FIT) format handling */ - debug ("FIT format handling\n"); - fit_handle_file (); - exit (EXIT_SUCCESS); + exit (retval); } /* - * Must be -w then: - * - * write dummy header, to be fixed later + * In case there an header with a variable + * length will be added, the corresponding + * function is called. This is responsible to + * allocate memory for the header itself. */ - memset (hdr, 0, image_get_header_size ()); + if (tparams->vrec_header) + tparams->vrec_header(¶ms, tparams); + else + memset(tparams->hdr, 0, tparams->header_size); - if (write(ifd, hdr, image_get_header_size ()) != image_get_header_size ()) { + if (write(ifd, tparams->hdr, tparams->header_size) + != tparams->header_size) { fprintf (stderr, "%s: Write error on %s: %s\n", - cmdname, imagefile, strerror(errno)); + params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } - if (opt_type == IH_TYPE_MULTI || opt_type == IH_TYPE_SCRIPT) { - char *file = datafile; - uint32_t size; - - for (;;) { - char *sep = NULL; - - if (file) { - if ((sep = strchr(file, ':')) != NULL) { - *sep = '\0'; + if (!params.skipcpy) { + if (params.type == IH_TYPE_MULTI || + params.type == IH_TYPE_SCRIPT) { + char *file = params.datafile; + uint32_t size; + + for (;;) { + char *sep = NULL; + + if (file) { + if ((sep = strchr(file, ':')) != NULL) { + *sep = '\0'; + } + + if (stat (file, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + params.cmdname, file, strerror(errno)); + exit (EXIT_FAILURE); + } + size = cpu_to_uimage (sbuf.st_size); + } else { + size = 0; } - if (stat (file, &sbuf) < 0) { - fprintf (stderr, "%s: Can't stat %s: %s\n", - cmdname, file, strerror(errno)); + if (write(ifd, (char *)&size, sizeof(size)) != sizeof(size)) { + fprintf (stderr, "%s: Write error on %s: %s\n", + params.cmdname, params.imagefile, + strerror(errno)); exit (EXIT_FAILURE); } - size = cpu_to_uimage (sbuf.st_size); - } else { - size = 0; - } - if (write(ifd, (char *)&size, sizeof(size)) != sizeof(size)) { - fprintf (stderr, "%s: Write error on %s: %s\n", - cmdname, imagefile, strerror(errno)); - exit (EXIT_FAILURE); - } + if (!file) { + break; + } - if (!file) { - break; + if (sep) { + *sep = ':'; + file = sep + 1; + } else { + file = NULL; + } } - if (sep) { - *sep = ':'; - file = sep + 1; - } else { - file = NULL; - } - } + file = params.datafile; - file = datafile; - - for (;;) { - char *sep = strchr(file, ':'); - if (sep) { - *sep = '\0'; - copy_file (ifd, file, 1); - *sep++ = ':'; - file = sep; - } else { - copy_file (ifd, file, 0); - break; + for (;;) { + char *sep = strchr(file, ':'); + if (sep) { + *sep = '\0'; + copy_file (ifd, file, 1); + *sep++ = ':'; + file = sep; + } else { + copy_file (ifd, file, 0); + break; + } } + } else if (params.type == IH_TYPE_PBLIMAGE) { + /* PBL has special Image format, implements its' own */ + pbl_load_uboot(ifd, ¶ms); + } else { + copy_file (ifd, params.datafile, 0); } - } else { - copy_file (ifd, datafile, 0); } /* We're a bit of paranoid */ -#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) && !defined(__APPLE__) +#if defined(_POSIX_SYNCHRONIZED_IO) && \ + !defined(__sun__) && \ + !defined(__FreeBSD__) && \ + !defined(__APPLE__) (void) fdatasync (ifd); #else (void) fsync (ifd); @@ -326,49 +492,42 @@ NXTARG: ; if (fstat(ifd, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", - cmdname, imagefile, strerror(errno)); + params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } - ptr = (unsigned char *)mmap(0, sbuf.st_size, - PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0); - if (ptr == (unsigned char *)MAP_FAILED) { + ptr = mmap(0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0); + if (ptr == MAP_FAILED) { fprintf (stderr, "%s: Can't map %s: %s\n", - cmdname, imagefile, strerror(errno)); + params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } - hdr = (image_header_t *)ptr; - - checksum = crc32 (0, - (const char *)(ptr + image_get_header_size ()), - sbuf.st_size - image_get_header_size () - ); - - /* Build new header */ - image_set_magic (hdr, IH_MAGIC); - image_set_time (hdr, sbuf.st_mtime); - image_set_size (hdr, sbuf.st_size - image_get_header_size ()); - image_set_load (hdr, addr); - image_set_ep (hdr, ep); - image_set_dcrc (hdr, checksum); - image_set_os (hdr, opt_os); - image_set_arch (hdr, opt_arch); - image_set_type (hdr, opt_type); - image_set_comp (hdr, opt_comp); - - image_set_name (hdr, name); - - checksum = crc32 (0, (const char *)hdr, image_get_header_size ()); - - image_set_hcrc (hdr, checksum); + /* Setup the image header as per input image type*/ + if (tparams->set_header) + tparams->set_header (ptr, &sbuf, ifd, ¶ms); + else { + fprintf (stderr, "%s: Can't set header for %s: %s\n", + params.cmdname, tparams->name, strerror(errno)); + exit (EXIT_FAILURE); + } - image_print_contents_noindent (hdr); + /* Print the image information by processing image header */ + if (tparams->print_header) + tparams->print_header (ptr); + else { + fprintf (stderr, "%s: Can't print header for %s: %s\n", + params.cmdname, tparams->name, strerror(errno)); + exit (EXIT_FAILURE); + } (void) munmap((void *)ptr, sbuf.st_size); /* We're a bit of paranoid */ -#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) && !defined(__APPLE__) +#if defined(_POSIX_SYNCHRONIZED_IO) && \ + !defined(__sun__) && \ + !defined(__FreeBSD__) && \ + !defined(__APPLE__) (void) fdatasync (ifd); #else (void) fsync (ifd); @@ -376,7 +535,7 @@ NXTARG: ; if (close(ifd)) { fprintf (stderr, "%s: Write error on %s: %s\n", - cmdname, imagefile, strerror(errno)); + params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } @@ -393,32 +552,32 @@ copy_file (int ifd, const char *datafile, int pad) int zero = 0; int offset = 0; int size; + struct image_type_params *tparams = mkimage_get_type (params.type); - if (vflag) { + if (params.vflag) { fprintf (stderr, "Adding Image %s\n", datafile); } if ((dfd = open(datafile, O_RDONLY|O_BINARY)) < 0) { fprintf (stderr, "%s: Can't open %s: %s\n", - cmdname, datafile, strerror(errno)); + params.cmdname, datafile, strerror(errno)); exit (EXIT_FAILURE); } if (fstat(dfd, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", - cmdname, datafile, strerror(errno)); + params.cmdname, datafile, strerror(errno)); exit (EXIT_FAILURE); } - ptr = (unsigned char *)mmap(0, sbuf.st_size, - PROT_READ, MAP_SHARED, dfd, 0); - if (ptr == (unsigned char *)MAP_FAILED) { + ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, dfd, 0); + if (ptr == MAP_FAILED) { fprintf (stderr, "%s: Can't read %s: %s\n", - cmdname, datafile, strerror(errno)); + params.cmdname, datafile, strerror(errno)); exit (EXIT_FAILURE); } - if (xflag) { + if (params.xflag) { unsigned char *p = NULL; /* * XIP: do not append the image_header_t at the @@ -426,29 +585,29 @@ copy_file (int ifd, const char *datafile, int pad) * reserved for it. */ - if ((unsigned)sbuf.st_size < image_get_header_size ()) { + if ((unsigned)sbuf.st_size < tparams->header_size) { fprintf (stderr, "%s: Bad size: \"%s\" is too small for XIP\n", - cmdname, datafile); + params.cmdname, datafile); exit (EXIT_FAILURE); } - for (p = ptr; p < ptr + image_get_header_size (); p++) { + for (p = ptr; p < ptr + tparams->header_size; p++) { if ( *p != 0xff ) { fprintf (stderr, "%s: Bad file: \"%s\" has invalid buffer for XIP\n", - cmdname, datafile); + params.cmdname, datafile); exit (EXIT_FAILURE); } } - offset = image_get_header_size (); + offset = tparams->header_size; } size = sbuf.st_size - offset; if (write(ifd, ptr + offset, size) != size) { fprintf (stderr, "%s: Write error on %s: %s\n", - cmdname, imagefile, strerror(errno)); + params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } @@ -456,7 +615,8 @@ copy_file (int ifd, const char *datafile, int pad) if (write(ifd, (char *)&zero, 4-tail) != 4-tail) { fprintf (stderr, "%s: Write error on %s: %s\n", - cmdname, imagefile, strerror(errno)); + params.cmdname, params.imagefile, + strerror(errno)); exit (EXIT_FAILURE); } } @@ -470,7 +630,7 @@ usage () { fprintf (stderr, "Usage: %s -l image\n" " -l ==> list image header information\n", - cmdname); + params.cmdname); fprintf (stderr, " %s [-x] -A arch -O os -T type -C comp " "-a addr -e ep -n name -d data_file[:data_file...] image\n" " -A ==> set architecture to 'arch'\n" @@ -482,157 +642,23 @@ usage () " -n ==> set image name to 'name'\n" " -d ==> use image data from 'datafile'\n" " -x ==> set XIP (execute in place)\n", - cmdname); - fprintf (stderr, " %s [-D dtc_options] -f fit-image.its fit-image\n", - cmdname); + params.cmdname); + fprintf(stderr, " %s [-D dtc_options] [-f fit-image.its|-F] fit-image\n", + params.cmdname); + fprintf(stderr, " -D => set options for device tree compiler\n" + " -f => input filename for FIT source\n"); +#ifdef CONFIG_FIT_SIGNATURE + fprintf(stderr, "Signing / verified boot options: [-k keydir] [-K dtb] [ -c ] [-r]\n" + " -k => set directory containing private keys\n" + " -K => write public keys to this .dtb file\n" + " -c => add comment in signature node\n" + " -F => re-sign existing FIT image\n" + " -r => mark keys used as 'required' in dtb\n"); +#else + fprintf(stderr, "Signing / verified boot not supported (CONFIG_FIT_SIGNATURE undefined)\n"); +#endif + fprintf (stderr, " %s -V ==> print version information and exit\n", + params.cmdname); exit (EXIT_FAILURE); } - -static void -image_verify_header (char *ptr, int image_size) -{ - int len; - char *data; - uint32_t checksum; - image_header_t header; - image_header_t *hdr = &header; - - /* - * create copy of header so that we can blank out the - * checksum field for checking - this can't be done - * on the PROT_READ mapped data. - */ - memcpy (hdr, ptr, sizeof(image_header_t)); - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - fprintf (stderr, - "%s: Bad Magic Number: \"%s\" is no valid image\n", - cmdname, imagefile); - exit (EXIT_FAILURE); - } - - data = (char *)hdr; - len = sizeof(image_header_t); - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = htonl(0); /* clear for re-calculation */ - - if (crc32 (0, data, len) != checksum) { - fprintf (stderr, - "%s: ERROR: \"%s\" has bad header checksum!\n", - cmdname, imagefile); - exit (EXIT_FAILURE); - } - - data = ptr + sizeof(image_header_t); - len = image_size - sizeof(image_header_t) ; - - if (crc32 (0, data, len) != ntohl(hdr->ih_dcrc)) { - fprintf (stderr, - "%s: ERROR: \"%s\" has corrupted data!\n", - cmdname, imagefile); - exit (EXIT_FAILURE); - } -} - -/** - * fit_handle_file - main FIT file processing function - * - * fit_handle_file() runs dtc to convert .its to .itb, includes - * binary data, updates timestamp property and calculates hashes. - * - * datafile - .its file - * imagefile - .itb file - * - * returns: - * only on success, otherwise calls exit (EXIT_FAILURE); - */ -static void fit_handle_file (void) -{ - char tmpfile[MKIMAGE_MAX_TMPFILE_LEN]; - char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN]; - int tfd; - struct stat sbuf; - unsigned char *ptr; - - /* call dtc to include binary properties into the tmp file */ - if (strlen (imagefile) + strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 > - sizeof (tmpfile)) { - fprintf (stderr, "%s: Image file name (%s) too long, " - "can't create tmpfile", - imagefile, cmdname); - exit (EXIT_FAILURE); - } - sprintf (tmpfile, "%s%s", imagefile, MKIMAGE_TMPFILE_SUFFIX); - - /* dtc -I dts -O -p 200 datafile > tmpfile */ - sprintf (cmd, "%s %s %s > %s", - MKIMAGE_DTC, opt_dtc, datafile, tmpfile); - debug ("Trying to execute \"%s\"\n", cmd); - if (system (cmd) == -1) { - fprintf (stderr, "%s: system(%s) failed: %s\n", - cmdname, cmd, strerror(errno)); - unlink (tmpfile); - exit (EXIT_FAILURE); - } - - /* load FIT blob into memory */ - tfd = open (tmpfile, O_RDWR|O_BINARY); - - if (tfd < 0) { - fprintf (stderr, "%s: Can't open %s: %s\n", - cmdname, tmpfile, strerror(errno)); - unlink (tmpfile); - exit (EXIT_FAILURE); - } - - if (fstat (tfd, &sbuf) < 0) { - fprintf (stderr, "%s: Can't stat %s: %s\n", - cmdname, tmpfile, strerror(errno)); - unlink (tmpfile); - exit (EXIT_FAILURE); - } - - ptr = (unsigned char *)mmap (0, sbuf.st_size, - PROT_READ|PROT_WRITE, MAP_SHARED, tfd, 0); - if ((caddr_t)ptr == (caddr_t)-1) { - fprintf (stderr, "%s: Can't read %s: %s\n", - cmdname, tmpfile, strerror(errno)); - unlink (tmpfile); - exit (EXIT_FAILURE); - } - - /* check if ptr has a valid blob */ - if (fdt_check_header (ptr)) { - fprintf (stderr, "%s: Invalid FIT blob\n", cmdname); - unlink (tmpfile); - exit (EXIT_FAILURE); - } - - /* set hashes for images in the blob */ - if (fit_set_hashes (ptr)) { - fprintf (stderr, "%s Can't add hashes to FIT blob", cmdname); - unlink (tmpfile); - exit (EXIT_FAILURE); - } - - /* add a timestamp at offset 0 i.e., root */ - if (fit_set_timestamp (ptr, 0, sbuf.st_mtime)) { - fprintf (stderr, "%s: Can't add image timestamp\n", cmdname); - unlink (tmpfile); - exit (EXIT_FAILURE); - } - debug ("Added timestamp successfully\n"); - - munmap ((void *)ptr, sbuf.st_size); - close (tfd); - - if (rename (tmpfile, imagefile) == -1) { - fprintf (stderr, "%s: Can't rename %s to %s: %s\n", - cmdname, tmpfile, imagefile, strerror (errno)); - unlink (tmpfile); - unlink (imagefile); - exit (EXIT_FAILURE); - } -}