tools: mkimage: split code into core, default and FIT image specific
This is a first step towards reorganizing the mkimage code to make it
easier to add support for additional images types. Current mkimage
code is specific to generating uImage and FIT image files, but the
same framework can be used to generate other image types like
Kirkwood boot images (kwbimage-TBD). For this, the mkimage code gets
reworked:
Here is the brief plan for the same:-
a) Split mkimage code into core and image specific support
b) Implement callback functions for image specific code
c) Move image type specific code to respective C files
Currently there are two types of file generation/list
supported (i.e uImage, FIT), the code is abstracted from
mkimage.c/.h and put in default_image.c and fit_image.c;
all code in these file is static except init function call
d) mkimage_register API is added to add new image type support
All above is addressed in this patch
e) Add kwbimage type support to this new framework (TBD)
This will be implemented in a following commit.
Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>
Edit commit message, fix coding style and typos.
Signed-off-by: Wolfgang Denk <wd@denx.de>
diff --git a/tools/mkimage.c b/tools/mkimage.c
index b0c02eb..c43b207 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -1,7 +1,7 @@
/*
* (C) Copyright 2008 Semihalf
*
- * (C) Copyright 2000-2004
+ * (C) Copyright 2000-2009
* DENX Software Engineering
* Wolfgang Denk, wd@denx.de
*
@@ -23,126 +23,223 @@
#include "mkimage.h"
#include <image.h>
-#include <u-boot/crc.h>
-static void copy_file (int, const char *, int);
-static void usage (void);
-static int image_verify_header (char *, int);
-static void fit_handle_file (void);
+static void copy_file(int, const char *, int);
+static void usage(void);
-char *datafile;
-char *imagefile;
-char *cmdname;
+/* image_type_params link list to maintain registered image type supports */
+struct image_type_params *mkimage_tparams = NULL;
-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;
+/* 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,
+};
-image_header_t header;
-image_header_t *hdr = &header;
+/*
+ * 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;
+}
+
+/*
+ * 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 = "";
int retval = 0;
+ struct image_type_params *tparams = NULL;
- cmdname = *argv;
+ /* Init FIT image generation/list support */
+ init_fit_image_type ();
+ /* Init Default image generation/list support */
+ init_default_image_type ();
- addr = ep = 0;
+ 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) ||
- (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,
+ (char **)&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,
+ (char **)&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;
+ params.fflag = 1;
goto NXTARG;
case 'n':
if (--argc <= 0)
usage ();
- name = *++argv;
+ params.imagename = *++argv;
goto NXTARG;
case 'v':
- vflag++;
+ params.vflag++;
break;
case 'x':
- xflag++;
+ params.xflag++;
break;
default:
usage ();
@@ -151,91 +248,112 @@
NXTARG: ;
}
- if ((argc != 1) ||
- (dflag && (fflag || lflag)) ||
- (fflag && (dflag || lflag)) ||
- (lflag && (dflag || fflag)))
- usage();
+ if (argc != 1)
+ usage ();
- if (!eflag) {
- ep = addr;
+ /* 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 (xflag)
- ep += image_get_header_size ();
+ if (params.xflag)
+ params.ep += tparams->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 ()) {
+ if (params.xflag) {
+ if (params.ep != params.addr + tparams->header_size) {
fprintf (stderr,
"%s: For XIP, the entry point must be the load addr + %lu\n",
- cmdname,
- (unsigned long)image_get_header_size ());
+ params.cmdname,
+ (unsigned long)tparams->header_size);
exit (EXIT_FAILURE);
}
}
- imagefile = *argv;
+ params.imagefile = *argv;
- if (!fflag){
- if (lflag) {
- ifd = open (imagefile, O_RDONLY|O_BINARY);
+ if (!params.fflag){
+ if (params.lflag) {
+ ifd = open (params.imagefile, O_RDONLY|O_BINARY);
} else {
- ifd = open (imagefile,
+ 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",
- cmdname, imagefile, strerror(errno));
+ params.cmdname, params.imagefile,
+ strerror(errno));
exit (EXIT_FAILURE);
}
}
- if (lflag) {
+ if (params.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));
+ 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 = 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 (!(retval = fdt_check_header (ptr))) {
- /* FIT image */
- fit_print_contents (ptr);
- } else if (!(retval = image_verify_header ((char *)ptr,
- sbuf.st_size))) {
- /* old-style image */
- image_print_contents ((image_header_t *)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 (retval);
- } else if (fflag) {
- /* Flattened Image Tree (FIT) format handling */
- debug ("FIT format handling\n");
- fit_handle_file ();
+ } else 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);
+
exit (retval);
}
@@ -244,16 +362,17 @@
*
* write dummy header, to be fixed later
*/
- memset (hdr, 0, image_get_header_size ());
+ 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;
+ if (params.type == IH_TYPE_MULTI || params.type == IH_TYPE_SCRIPT) {
+ char *file = params.datafile;
uint32_t size;
for (;;) {
@@ -266,7 +385,7 @@
if (stat (file, &sbuf) < 0) {
fprintf (stderr, "%s: Can't stat %s: %s\n",
- cmdname, file, strerror(errno));
+ params.cmdname, file, strerror(errno));
exit (EXIT_FAILURE);
}
size = cpu_to_uimage (sbuf.st_size);
@@ -276,7 +395,8 @@
if (write(ifd, (char *)&size, sizeof(size)) != sizeof(size)) {
fprintf (stderr, "%s: Write error on %s: %s\n",
- cmdname, imagefile, strerror(errno));
+ params.cmdname, params.imagefile,
+ strerror(errno));
exit (EXIT_FAILURE);
}
@@ -292,7 +412,7 @@
}
}
- file = datafile;
+ file = params.datafile;
for (;;) {
char *sep = strchr(file, ':');
@@ -307,11 +427,14 @@
}
}
} else {
- copy_file (ifd, datafile, 0);
+ copy_file (ifd, params.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);
@@ -319,50 +442,42 @@
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 = 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;
+ /* 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);
+ }
- checksum = crc32 (0,
- (const unsigned 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 unsigned char *)hdr,
- image_get_header_size ());
-
- image_set_hcrc (hdr, checksum);
-
- image_print_contents (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);
@@ -370,7 +485,7 @@
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);
}
@@ -387,31 +502,32 @@
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 = 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
@@ -419,29 +535,29 @@
* 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);
}
@@ -449,7 +565,8 @@
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);
}
}
@@ -463,7 +580,7 @@
{
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"
@@ -475,157 +592,9 @@
" -n ==> set image name to 'name'\n"
" -d ==> use image data from 'datafile'\n"
" -x ==> set XIP (execute in place)\n",
- cmdname);
+ params.cmdname);
fprintf (stderr, " %s [-D dtc_options] -f fit-image.its fit-image\n",
- cmdname);
+ params.cmdname);
exit (EXIT_FAILURE);
}
-
-static int
-image_verify_header (char *ptr, int image_size)
-{
- int len;
- const unsigned 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 (be32_to_cpu(hdr->ih_magic) != IH_MAGIC) {
- fprintf (stderr,
- "%s: Bad Magic Number: \"%s\" is no valid image\n",
- cmdname, imagefile);
- return -FDT_ERR_BADMAGIC;
- }
-
- data = (const unsigned char *)hdr;
- len = sizeof(image_header_t);
-
- checksum = be32_to_cpu(hdr->ih_hcrc);
- hdr->ih_hcrc = cpu_to_be32(0); /* clear for re-calculation */
-
- if (crc32 (0, data, len) != checksum) {
- fprintf (stderr,
- "%s: ERROR: \"%s\" has bad header checksum!\n",
- cmdname, imagefile);
- return -FDT_ERR_BADSTATE;
- }
-
- data = (const unsigned char *)ptr + sizeof(image_header_t);
- len = image_size - sizeof(image_header_t) ;
-
- if (crc32 (0, data, len) != be32_to_cpu(hdr->ih_dcrc)) {
- fprintf (stderr,
- "%s: ERROR: \"%s\" has corrupted data!\n",
- cmdname, imagefile);
- return -FDT_ERR_BADSTRUCTURE;
- }
- return 0;
-}
-
-/**
- * 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 = mmap (0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, tfd, 0);
- if (ptr == MAP_FAILED) {
- 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);
- }
-}