/** * fit_image_get_os - get os id for a given component image node * @fit: pointer to the FIT format image header * @noffset: component image node offset * @os: pointer to the uint8_t, will hold os numeric id * * fit_image_get_os() finds os property in a given component image node. * If the property is found, its (string) value is translated to the numeric * id which is returned to the caller. * * returns: * 0, on success * -1, on failure */ int fit_image_get_os(const void *fit, int noffset, uint8_t *os) { int len; const void *data; /* Get OS name from property data */ data = fdt_getprop(fit, noffset, FIT_OS_PROP, &len); if (data == NULL) { fit_get_debug(fit, noffset, FIT_OS_PROP, len); *os = -1; return -1; } /* Translate OS name to id */ *os = genimg_get_os_id(data); return 0; }
static void process_args(int argc, char **argv) { char *ptr; int type = IH_TYPE_INVALID; char *datafile = NULL; int opt; while ((opt = getopt(argc, argv, "a:A:b:c:C:d:D:e:Ef:Fk:K:ln:p:O:rR:qsT:vVx")) != -1) { switch (opt) { case 'a': params.addr = strtoull(optarg, &ptr, 16); if (*ptr) { fprintf(stderr, "%s: invalid load address %s\n", params.cmdname, optarg); exit(EXIT_FAILURE); } break; case 'A': params.arch = genimg_get_arch_id(optarg); if (params.arch < 0) { show_valid_options(IH_ARCH); usage("Invalid architecture"); } break; case 'b': if (add_content(IH_TYPE_FLATDT, optarg)) { fprintf(stderr, "%s: Out of memory adding content '%s'", params.cmdname, optarg); exit(EXIT_FAILURE); } break; case 'c': params.comment = optarg; break; case 'C': params.comp = genimg_get_comp_id(optarg); if (params.comp < 0) { show_valid_options(IH_COMP); usage("Invalid compression type"); } break; case 'd': params.datafile = optarg; params.dflag = 1; break; case 'D': params.dtc = optarg; break; case 'e': params.ep = strtoull(optarg, &ptr, 16); if (*ptr) { fprintf(stderr, "%s: invalid entry point %s\n", params.cmdname, optarg); exit(EXIT_FAILURE); } params.eflag = 1; break; case 'E': params.external_data = true; break; case 'f': datafile = optarg; params.auto_its = !strcmp(datafile, "auto"); /* 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; break; case 'k': params.keydir = optarg; break; case 'K': params.keydest = optarg; break; case 'l': params.lflag = 1; break; case 'n': params.imagename = optarg; break; case 'O': params.os = genimg_get_os_id(optarg); if (params.os < 0) { show_valid_options(IH_OS); usage("Invalid operating system"); } break; case 'p': params.external_offset = strtoull(optarg, &ptr, 16); if (*ptr) { fprintf(stderr, "%s: invalid offset size %s\n", params.cmdname, optarg); exit(EXIT_FAILURE); } break; case 'q': params.quiet = 1; break; case 'r': params.require_keys = 1; break; case 'R': /* * This entry is for the second configuration * file, if only one is not enough. */ params.imagename2 = optarg; break; case 's': params.skipcpy = 1; break; case 'T': type = genimg_get_type_id(optarg); if (type < 0) { show_valid_options(IH_TYPE); usage("Invalid image type"); } break; case 'v': params.vflag++; break; case 'V': printf("mkimage version %s\n", PLAIN_VERSION); exit(EXIT_SUCCESS); case 'x': params.xflag++; break; default: usage("Invalid option"); } } /* The last parameter is expected to be the imagefile */ if (optind < argc) params.imagefile = argv[optind]; /* * For auto-generated FIT images we need to know the image type to put * in the FIT, which is separate from the file's image type (which * will always be IH_TYPE_FLATDT in this case). */ if (params.type == IH_TYPE_FLATDT) { params.fit_image_type = type ? type : IH_TYPE_KERNEL; /* For auto_its, datafile is always 'auto' */ if (!params.auto_its) params.datafile = datafile; else if (!params.datafile) usage("Missing data file for auto-FIT (use -d)"); } else if (type != IH_TYPE_INVALID) { params.type = type; } if (!params.imagefile) usage("Missing output filename"); }
int main(int argc, char **argv) { int ifd = -1; struct stat sbuf; char *ptr; int retval = 0; struct image_type_params *tparams = NULL; int pad_len = 0; int dfd; params.cmdname = *argv; params.addr = params.ep = 0; while (--argc > 0 && **++argv == '-') { while (*++*argv) { switch (**argv) { case 'l': params.lflag = 1; break; case 'A': if ((--argc <= 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) || (params.comp = genimg_get_comp_id (*++argv)) < 0) usage (); goto NXTARG; case 'D': if (--argc <= 0) usage (); params.dtc = *++argv; goto NXTARG; case 'O': if ((--argc <= 0) || (params.os = genimg_get_os_id (*++argv)) < 0) usage (); goto NXTARG; case 'T': params.type = -1; if (--argc >= 0 && argv[1]) { params.type = genimg_get_type_id(*++argv); } if (params.type < 0) { show_image_types(); usage(); } goto NXTARG; case 'a': if (--argc <= 0) usage (); params.addr = strtoull(*++argv, &ptr, 16); if (*ptr) { fprintf (stderr, "%s: invalid load address %s\n", params.cmdname, *argv); exit (EXIT_FAILURE); } goto NXTARG; case 'd': if (--argc <= 0) usage (); params.datafile = *++argv; params.dflag = 1; goto NXTARG; case 'e': if (--argc <= 0) usage (); params.ep = strtoull(*++argv, &ptr, 16); if (*ptr) { fprintf (stderr, "%s: invalid entry point %s\n", params.cmdname, *argv); exit (EXIT_FAILURE); } params.eflag = 1; goto NXTARG; case 'f': if (--argc <= 0) usage (); 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 (); 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': params.vflag++; break; case 'V': printf("mkimage version %s\n", PLAIN_VERSION); exit(EXIT_SUCCESS); case 'x': params.xflag++; break; default: usage (); } } NXTARG: ; } if (argc != 1) usage (); /* set tparams as per input type_id */ tparams = imagetool_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); } /* * check the passed arguments parameters meets the requirements * as per image type to be generated/listed */ 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; } params.imagefile = *argv; 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 (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 (params.lflag || params.fflag) { /* * list header information of existing image */ if (fstat(ifd, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } if ((unsigned)sbuf.st_size < tparams->header_size) { fprintf (stderr, "%s: Bad size: \"%s\" is not valid image\n", params.cmdname, params.imagefile); exit (EXIT_FAILURE); } 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", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } /* * 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 = imagetool_verify_print_header(ptr, &sbuf, tparams, ¶ms); (void) munmap((void *)ptr, sbuf.st_size); (void) close (ifd); exit (retval); } if ((params.type != IH_TYPE_MULTI) && (params.type != IH_TYPE_SCRIPT)) { dfd = open(params.datafile, O_RDONLY | O_BINARY); if (dfd < 0) { fprintf(stderr, "%s: Can't open %s: %s\n", params.cmdname, params.datafile, strerror(errno)); exit(EXIT_FAILURE); } if (fstat(dfd, &sbuf) < 0) { fprintf(stderr, "%s: Can't stat %s: %s\n", params.cmdname, params.datafile, strerror(errno)); exit(EXIT_FAILURE); } params.file_size = sbuf.st_size + tparams->header_size; close(dfd); } /* * 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. */ if (tparams->vrec_header) pad_len = tparams->vrec_header(¶ms, tparams); else memset(tparams->hdr, 0, tparams->header_size); if (write(ifd, tparams->hdr, tparams->header_size) != tparams->header_size) { fprintf (stderr, "%s: Write error on %s: %s\n", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } 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 (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); } if (!file) { break; } if (sep) { *sep = ':'; file = sep + 1; } else { file = NULL; } } file = params.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; } } } 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, pad_len); } } /* We're a bit of paranoid */ #if defined(_POSIX_SYNCHRONIZED_IO) && \ !defined(__sun__) && \ !defined(__FreeBSD__) && \ !defined(__OpenBSD__) && \ !defined(__APPLE__) (void) fdatasync (ifd); #else (void) fsync (ifd); #endif if (fstat(ifd, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } params.file_size = sbuf.st_size; 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", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } /* 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); } /* 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(__OpenBSD__) && \ !defined(__APPLE__) (void) fdatasync (ifd); #else (void) fsync (ifd); #endif if (close(ifd)) { fprintf (stderr, "%s: Write error on %s: %s\n", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } exit (EXIT_SUCCESS); }
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; while (--argc > 0 && **++argv == '-') { while (*++*argv) { switch (**argv) { case 'l': lflag = 1; break; case 'A': if ((--argc <= 0) || (opt_arch = genimg_get_arch_id (*++argv)) < 0) usage (); goto NXTARG; case 'C': if ((--argc <= 0) || (opt_comp = genimg_get_comp_id (*++argv)) < 0) usage (); goto NXTARG; case 'D': if (--argc <= 0) usage (); opt_dtc = *++argv; goto NXTARG; case 'O': if ((--argc <= 0) || (opt_os = genimg_get_os_id (*++argv)) < 0) usage (); goto NXTARG; case 'T': if ((--argc <= 0) || (opt_type = genimg_get_type_id (*++argv)) < 0) usage (); goto NXTARG; case 'a': if (--argc <= 0) usage (); addr = strtoul (*++argv, (char **)&ptr, 16); if (*ptr) { fprintf (stderr, "%s: invalid load address %s\n", cmdname, *argv); exit (EXIT_FAILURE); } goto NXTARG; case 'd': if (--argc <= 0) usage (); datafile = *++argv; dflag = 1; goto NXTARG; case 'e': if (--argc <= 0) usage (); ep = strtoul (*++argv, (char **)&ptr, 16); if (*ptr) { fprintf (stderr, "%s: invalid entry point %s\n", cmdname, *argv); exit (EXIT_FAILURE); } eflag = 1; goto NXTARG; case 'f': if (--argc <= 0) usage (); datafile = *++argv; fflag = 1; goto NXTARG; case 'n': if (--argc <= 0) usage (); name = *++argv; goto NXTARG; case 'v': vflag++; break; case 'x': xflag++; break; default: usage (); } } NXTARG: ; } if ((argc != 1) || (dflag && (fflag || lflag)) || (fflag && (dflag || lflag)) || (lflag && (dflag || fflag))) usage(); if (!eflag) { ep = addr; /* If XIP, entry point must be after the U-Boot header */ if (xflag) ep += image_get_header_size (); } /* * If XIP, ensure the entry point is equal to the load address plus * the size of the U-Boot header. */ 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); } } 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 (ifd < 0) { fprintf (stderr, "%s: Can't open %s: %s\n", cmdname, imagefile, strerror(errno)); exit (EXIT_FAILURE); } } if (lflag) { /* * list header information of existing image */ if (fstat(ifd, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", cmdname, imagefile, strerror(errno)); exit (EXIT_FAILURE); } if ((unsigned)sbuf.st_size < image_get_header_size ()) { fprintf (stderr, "%s: Bad size: \"%s\" is no valid image\n", cmdname, imagefile); exit (EXIT_FAILURE); } 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)); exit (EXIT_FAILURE); } if (fdt_check_header (ptr)) { /* old-style image */ image_verify_header ((char *)ptr, sbuf.st_size); image_print_contents ((image_header_t *)ptr); } else { /* FIT image */ fit_print_contents (ptr); } (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); } /* * Must be -w then: * * write dummy header, to be fixed later */ memset (hdr, 0, image_get_header_size ()); if (write(ifd, hdr, image_get_header_size ()) != image_get_header_size ()) { fprintf (stderr, "%s: Write error on %s: %s\n", cmdname, 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 (stat (file, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", cmdname, file, 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 (sep) { *sep = ':'; file = sep + 1; } else { file = NULL; } } 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; } } } else { copy_file (ifd, datafile, 0); } /* We're a bit of paranoid */ #if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) && !defined(__APPLE__) (void) fdatasync (ifd); #else (void) fsync (ifd); #endif if (fstat(ifd, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", cmdname, imagefile, strerror(errno)); exit (EXIT_FAILURE); } 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)); 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); image_print_contents (hdr); (void) munmap((void *)ptr, sbuf.st_size); /* We're a bit of paranoid */ #if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) && !defined(__APPLE__) (void) fdatasync (ifd); #else (void) fsync (ifd); #endif if (close(ifd)) { fprintf (stderr, "%s: Write error on %s: %s\n", cmdname, imagefile, strerror(errno)); exit (EXIT_FAILURE); } exit (EXIT_SUCCESS); }
int main (int argc, char **argv) { int ifd = -1; struct stat sbuf; unsigned char *ptr; int retval = 0; struct image_type_params *tparams = NULL; /* 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 Default image generation/list support */ init_default_image_type (); params.cmdname = *argv; params.addr = params.ep = 0; while (--argc > 0 && **++argv == '-') { while (*++*argv) { switch (**argv) { case 'l': params.lflag = 1; break; case 'A': if ((--argc <= 0) || (params.arch = genimg_get_arch_id (*++argv)) < 0) usage (); goto NXTARG; case 'C': if ((--argc <= 0) || (params.comp = genimg_get_comp_id (*++argv)) < 0) usage (); goto NXTARG; case 'D': if (--argc <= 0) usage (); params.dtc = *++argv; goto NXTARG; case 'O': if ((--argc <= 0) || (params.os = genimg_get_os_id (*++argv)) < 0) usage (); goto NXTARG; case 'T': if ((--argc <= 0) || (params.type = genimg_get_type_id (*++argv)) < 0) usage (); goto NXTARG; case 'a': if (--argc <= 0) usage (); params.addr = strtoul (*++argv, (char **)&ptr, 16); if (*ptr) { fprintf (stderr, "%s: invalid load address %s\n", params.cmdname, *argv); exit (EXIT_FAILURE); } goto NXTARG; case 'd': if (--argc <= 0) usage (); params.datafile = *++argv; params.dflag = 1; goto NXTARG; case 'e': if (--argc <= 0) usage (); params.ep = strtoul (*++argv, (char **)&ptr, 16); if (*ptr) { fprintf (stderr, "%s: invalid entry point %s\n", params.cmdname, *argv); exit (EXIT_FAILURE); } params.eflag = 1; goto NXTARG; case 'f': if (--argc <= 0) usage (); /* * The flattened image tree (FIT) format * requires a flattened device tree image type */ params.type = IH_TYPE_FLATDT; params.datafile = *++argv; params.fflag = 1; goto NXTARG; case 'n': if (--argc <= 0) usage (); params.imagename = *++argv; goto NXTARG; case 'v': params.vflag++; break; case 'x': params.xflag++; break; default: usage (); } } NXTARG: ; } if (argc != 1) usage (); /* 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); } /* * check the passed arguments parameters meets the requirements * as per image type to be generated/listed */ 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; } params.imagefile = *argv; 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 (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 (params.lflag || params.fflag) { /* * list header information of existing image */ if (fstat(ifd, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } if ((unsigned)sbuf.st_size < tparams->header_size) { fprintf (stderr, "%s: Bad size: \"%s\" is not valid image\n", params.cmdname, params.imagefile); exit (EXIT_FAILURE); } 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", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } /* * 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 (retval); } /* * Must be -w then: * * write dummy header, to be fixed later */ memset (tparams->hdr, 0, tparams->header_size); if (write(ifd, tparams->hdr, tparams->header_size) != tparams->header_size) { fprintf (stderr, "%s: Write error on %s: %s\n", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } 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 (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); } if (!file) { break; } if (sep) { *sep = ':'; file = sep + 1; } else { file = NULL; } } file = params.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; } } } else { copy_file (ifd, params.datafile, 0); } /* We're a bit of paranoid */ #if defined(_POSIX_SYNCHRONIZED_IO) && \ !defined(__sun__) && \ !defined(__FreeBSD__) && \ !defined(__APPLE__) (void) fdatasync (ifd); #else (void) fsync (ifd); #endif if (fstat(ifd, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } 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", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } /* 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); } /* 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__) (void) fdatasync (ifd); #else (void) fsync (ifd); #endif if (close(ifd)) { fprintf (stderr, "%s: Write error on %s: %s\n", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } exit (EXIT_SUCCESS); }
int main (int argc, char **argv) { long imagelen; /* CWWeng 2014/4/30 */ int aes_blockno; /* CWWeng 2014/4/30 */ aes_context ctx; /* CWWeng 2014/5/12 add */ int ifd = -1; struct stat sbuf; 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': params.lflag = 1; break; case 'A': if ((--argc <= 0) || (params.arch = genimg_get_arch_id (*++argv)) < 0) usage (); goto NXTARG; case 'C': if ((--argc <= 0) || (params.comp = genimg_get_comp_id (*++argv)) < 0) usage (); goto NXTARG; case 'D': if (--argc <= 0) usage (); params.dtc = *++argv; goto NXTARG; case 'E': /* CWWeng 2014/4/29 add */ if ((--argc <= 0) || (params.encrypt = genimg_get_encrypt_id (*++argv)) < 0) usage (); goto NXTARG; case 'K': /* CWWeng 2015/2/6 add */ if (--argc <= 0) usage (); params.keyfile = *++argv; params.kflag = 1; goto NXTARG; case 'O': if ((--argc <= 0) || (params.os = genimg_get_os_id (*++argv)) < 0) usage (); goto NXTARG; case 'S': /* CWWeng 2015/3/5 add */ if ((--argc <= 0) || (params.checksum = genimg_get_checksum_id (*++argv)) < 0) usage (); goto NXTARG; case 'T': if ((--argc <= 0) || (params.type = genimg_get_type_id (*++argv)) < 0) usage (); goto NXTARG; case 'a': if (--argc <= 0) usage (); params.addr = strtoul (*++argv, &ptr, 16); if (*ptr) { fprintf (stderr, "%s: invalid load address %s\n", params.cmdname, *argv); exit (EXIT_FAILURE); } goto NXTARG; case 'd': if (--argc <= 0) usage (); params.datafile = *++argv; params.dflag = 1; goto NXTARG; case 'e': if (--argc <= 0) usage (); params.ep = strtoul (*++argv, &ptr, 16); if (*ptr) { fprintf (stderr, "%s: invalid entry point %s\n", params.cmdname, *argv); exit (EXIT_FAILURE); } params.eflag = 1; goto NXTARG; case 'f': if (--argc <= 0) usage (); /* * The flattened image tree (FIT) format * requires a flattened device tree image type */ params.type = IH_TYPE_FLATDT; params.datafile = *++argv; params.fflag = 1; goto NXTARG; case 'n': if (--argc <= 0) usage (); params.imagename = *++argv; goto NXTARG; 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': params.vflag++; break; case 'V': printf("mkimage version %s\n", PLAIN_VERSION); exit(EXIT_SUCCESS); case 'x': params.xflag++; break; default: usage (); } } NXTARG: ; } if (argc != 1) usage (); /* 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); } /* * check the passed arguments parameters meets the requirements * as per image type to be generated/listed */ 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; } params.imagefile = *argv; 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 (retval != EXIT_SUCCESS) exit (retval); } /* CWWeng 2015/2/6 add to read key file */ if (params.kflag) _read_key(params.cmdname, params.keyfile); 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 (params.lflag || params.fflag) { /* * list header information of existing image */ if (fstat(ifd, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } if ((unsigned)sbuf.st_size < tparams->header_size) { fprintf (stderr, "%s: Bad size: \"%s\" is not valid image\n", params.cmdname, params.imagefile); exit (EXIT_FAILURE); } /* CWWeng 2014/5/28 : append 0 to the end of image * aes_encrypt() encrypt one 128 bit block * if the image is not multiple of 16 byte (128 bit), * patch 0 to the end of the image */ if (params.encrypt == IH_ENCRPT_AES) { char ch[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; lseek(ifd,0,SEEK_END); if (sbuf.st_size % 16) write(ifd,ch, 16 - (sbuf.st_size % 16)); } 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", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } /* * 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); /* * CWWeng 2014/4/30 : encrypt the image * aes_encrypt() encrypt one 128 bit block * if the image is not multiple of 16 byte (128 bit), * patch 0 to the end of the image */ if (params.encrypt == IH_ENCRPT_AES) { int i; u8 temp_key; for (i=0; i<32; i+=4) { temp_key = otp_key[i]; otp_key[i] = otp_key[i+3]; otp_key[i+3] = temp_key; temp_key = otp_key[i+1]; otp_key[i+1] = otp_key[i+2]; otp_key[i+2] = temp_key; } for (i=0; i<32; i+=4) printf("Key%d = 0x%02x%02x%02x%02x\n",i/4,otp_key[i],otp_key[i+1],otp_key[i+2],otp_key[i+3]); aes_set_key(&ctx, (u8 *)otp_key, 256); imagelen = sbuf.st_size + 64; aes_blockno = 0; do { aes_encrypt(&ctx, (u8 *)(ptr+(16*aes_blockno)), (u8 *)(ptr+(16*aes_blockno))); imagelen -= 16; aes_blockno++; } while (imagelen > 0); } (void) munmap((void *)ptr, sbuf.st_size); (void) close (ifd); exit (retval); } /* * 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. */ if (tparams->vrec_header) tparams->vrec_header(¶ms, tparams); else memset(tparams->hdr, 0, tparams->header_size); if (write(ifd, tparams->hdr, tparams->header_size) != tparams->header_size) { fprintf (stderr, "%s: Write error on %s: %s\n", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } 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 (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); } if (!file) { break; } if (sep) { *sep = ':'; file = sep + 1; } else { file = NULL; } } file = params.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; } } } 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); } } /* We're a bit of paranoid */ #if defined(_POSIX_SYNCHRONIZED_IO) && \ !defined(__sun__) && \ !defined(__FreeBSD__) && \ !defined(__APPLE__) (void) fdatasync (ifd); #else (void) fsync (ifd); #endif if (fstat(ifd, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } /* CWWeng 2014/5/28 : append 0 to the end of image * aes_encrypt() encrypt one 128 bit block * if the image is not multiple of 16 byte (128 bit), * patch 0 to the end of the image */ if (params.encrypt == IH_ENCRPT_AES) { char ch[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; lseek(ifd,0,SEEK_END); if (sbuf.st_size % 16) write(ifd,ch, 16 - (sbuf.st_size % 16)); } 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", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } /* 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); } /* 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); } /* * CWWeng 2014/4/30 : encrypt the image * aes_encrypt() encrypt one 128 bit block * if the image is not multiple of 16 byte (128 bit), * patch 0 to the end of the image */ if (params.encrypt == IH_ENCRPT_AES) { int i; u8 temp_key; for (i=0; i<32; i+=4) { temp_key = otp_key[i]; otp_key[i] = otp_key[i+3]; otp_key[i+3] = temp_key; temp_key = otp_key[i+1]; otp_key[i+1] = otp_key[i+2]; otp_key[i+2] = temp_key; } for (i=0; i<32; i+=4) printf("Key%d = 0x%02x%02x%02x%02x\n",i/4,otp_key[i],otp_key[i+1],otp_key[i+2],otp_key[i+3]); aes_set_key(&ctx, (u8 *)otp_key, 256); imagelen = sbuf.st_size + 64; aes_blockno = 0; do { aes_encrypt(&ctx, (u8 *)(ptr+(16*aes_blockno)), (u8 *)(ptr+(16*aes_blockno))); imagelen -= 16; aes_blockno++; } while (imagelen > 0); } (void) munmap((void *)ptr, sbuf.st_size); /* We're a bit of paranoid */ #if defined(_POSIX_SYNCHRONIZED_IO) && \ !defined(__sun__) && \ !defined(__FreeBSD__) && \ !defined(__APPLE__) (void) fdatasync (ifd); #else (void) fsync (ifd); #endif if (close(ifd)) { fprintf (stderr, "%s: Write error on %s: %s\n", params.cmdname, params.imagefile, strerror(errno)); exit (EXIT_FAILURE); } exit (EXIT_SUCCESS); }