[U-Boot] [PATCH 2/8] tools: mkimage: code abstraction generic and image specific

Prafulla Wadaskar prafulla at marvell.com
Tue Jul 28 20:04:24 CEST 2009


This is first step towards cleaning mkimage code for kwbimage
support in clean way. Current mkimage code is very specific to
uimge generation whereas the same framework can be used to
generate other image types like kwbimage.
For this, the architecture of mkimage code need to modified.

Here is the brief plan for the same:-
a) Abstract image specific code to saperate file (this patch)
b) Move image header code from mkimage.c to respective
	image specific code
c) Implement callback function for image specific functions
d) Add kwbimage type support to this framework

In this patch-
1. Image specific code abstracted from mkimage.c to
	default_image.c/h to make mkimage code more generic
2. struct mkimage_params introduced to pass basic mkimage
	specific flags and variables to image specific functions

Signed-off-by: Prafulla Wadaskar <prafulla at marvell.com>
---
 tools/Makefile        |    4 +
 tools/default_image.c |  227 ++++++++++++++++++++++++++++++
 tools/default_image.h |   36 +++++
 tools/mkimage.c       |  368 ++++++++++++++-----------------------------------
 tools/mkimage.h       |   25 ++++
 5 files changed, 394 insertions(+), 266 deletions(-)
 create mode 100644 tools/default_image.c
 create mode 100644 tools/default_image.h

diff --git a/tools/Makefile b/tools/Makefile
index b5a1e39..6ef15d9 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -171,6 +171,7 @@ $(obj)img2srec$(SFX):	$(obj)img2srec.o
 	$(STRIP) $@
 
 $(obj)mkimage$(SFX):	$(obj)mkimage.o $(obj)crc32.o $(obj)image.o $(obj)md5.o \
+			$(obj)default_image.o \
 			$(obj)sha1.o $(LIBFDT_OBJS) $(obj)os_support.o
 	$(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
 	$(STRIP) $@
@@ -203,6 +204,9 @@ $(obj)bin2header$(SFX): $(obj)bin2header.o
 $(obj)image.o: $(SRCTREE)/common/image.c
 	$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
 
+$(obj)default_image.o: $(SRCTREE)/tools/default_image.c
+	$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
+
 $(obj)mkimage.o: $(SRCTREE)/tools/mkimage.c
 	$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
 
diff --git a/tools/default_image.c b/tools/default_image.c
new file mode 100644
index 0000000..45afde1
--- /dev/null
+++ b/tools/default_image.c
@@ -0,0 +1,227 @@
+/*
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2004
+ * DENX Software Engineering
+ * Wolfgang Denk, wd at denx.de
+ * Updated-by: Prafulla Wadaskar <prafulla at marvell.com>
+ *		image specific code abstracted from mkimage.c
+ *		some functions added to address abstraction
+ * 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
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "mkimage.h"
+#include <image.h>
+#include "default_image.h"
+
+int image_check_params (struct mkimage_params *params)
+{
+	return	((params->dflag && (params->fflag || params->lflag)) ||
+		(params->fflag && (params->dflag || params->lflag)) ||
+		(params->lflag && (params->dflag || params->fflag)));
+}
+
+int
+image_verify_header (char *ptr, int image_size,
+			struct mkimage_params *params)
+{
+	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 (be32_to_cpu(hdr->ih_magic) != IH_MAGIC) {
+		fprintf (stderr,
+			"%s: Bad Magic Number: \"%s\" is no valid image\n",
+			params->cmdname, params->imagefile);
+		return -FDT_ERR_BADMAGIC;
+	}
+
+	data = (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",
+			params->cmdname, params->imagefile);
+		return -FDT_ERR_BADSTATE;
+	}
+
+	data = 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",
+			params->cmdname, params->imagefile);
+		return -FDT_ERR_BADSTRUCTURE;
+	}
+	return 0;
+}
+
+void image_print_header (char *ptr)
+{
+	image_header_t * hdr = (image_header_t *)ptr;
+
+	image_print_contents (hdr);
+}
+
+void image_set_header (char *ptr, struct stat *sbuf,
+				struct mkimage_params *params)
+{
+	uint32_t checksum;
+
+	image_header_t * 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, params->addr);
+	image_set_ep (hdr, params->ep);
+	image_set_dcrc (hdr, checksum);
+	image_set_os (hdr, params->opt_os);
+	image_set_arch (hdr, params->opt_arch);
+	image_set_type (hdr, params->opt_type);
+	image_set_comp (hdr, params->opt_comp);
+
+	image_set_name (hdr, params->imagename);
+
+	checksum = crc32 (0, (const char *)hdr, image_get_header_size ());
+
+	image_set_hcrc (hdr, checksum);
+}
+
+/**
+ * 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);
+ */
+void fit_handle_file (struct mkimage_params *params)
+{
+	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 (params->imagefile) +
+		strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 > sizeof (tmpfile)) {
+		fprintf (stderr, "%s: Image file name (%s) too long, "
+				"can't create tmpfile",
+				params->imagefile, params->cmdname);
+		exit (EXIT_FAILURE);
+	}
+	sprintf (tmpfile, "%s%s", params->imagefile, MKIMAGE_TMPFILE_SUFFIX);
+
+	/* dtc -I dts -O -p 200 datafile > tmpfile */
+	sprintf (cmd, "%s %s %s > %s",
+		MKIMAGE_DTC, params->opt_dtc, params->datafile, tmpfile);
+	debug ("Trying to execute \"%s\"\n", cmd);
+	if (system (cmd) == -1) {
+		fprintf (stderr, "%s: system(%s) failed: %s\n",
+				params->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",
+				params->cmdname, tmpfile, strerror(errno));
+		unlink (tmpfile);
+		exit (EXIT_FAILURE);
+	}
+
+	if (fstat (tfd, &sbuf) < 0) {
+		fprintf (stderr, "%s: Can't stat %s: %s\n",
+				params->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",
+				params->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", params->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",
+				params->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",
+				params->cmdname);
+		unlink (tmpfile);
+		exit (EXIT_FAILURE);
+	}
+	debug ("Added timestamp successfully\n");
+
+	munmap ((void *)ptr, sbuf.st_size);
+	close (tfd);
+
+	if (rename (tmpfile, params->imagefile) == -1) {
+		fprintf (stderr, "%s: Can't rename %s to %s: %s\n",
+				params->cmdname, tmpfile, params->imagefile,
+				strerror (errno));
+		unlink (tmpfile);
+		unlink (params->imagefile);
+		exit (EXIT_FAILURE);
+	}
+}
diff --git a/tools/default_image.h b/tools/default_image.h
new file mode 100644
index 0000000..6ebc689
--- /dev/null
+++ b/tools/default_image.h
@@ -0,0 +1,36 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _DEFAULT_IMAGE_H_
+#define _DEFAULT_IMAGE_H_
+
+int image_check_params (struct mkimage_params *params);
+int image_verify_header (char *ptr, int image_size,
+			struct mkimage_params *params);
+void image_print_header (char *ptr);
+void image_set_header (char *ptr, struct stat *sbuf,
+			struct mkimage_params *params);
+void fit_handle_file (struct mkimage_params *params);
+
+#endif /* _DEFAULT_IMAGE_H_ */
diff --git a/tools/mkimage.c b/tools/mkimage.c
index b7b383a..66d6c8e 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -24,28 +24,30 @@
 
 #include "mkimage.h"
 #include <image.h>
-
-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	int		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;
+#include "default_image.h"
+
+static void copy_file(int, const char *, int);
+static void usage(void);
+
+struct mkimage_params params = {
+	.dflag = 0,
+	.eflag = 0,
+	.fflag = 0,
+	.lflag = 0,
+	.vflag = 0,
+	.xflag = 0,
+	.opt_os = IH_OS_LINUX,
+	.opt_arch = IH_ARCH_PPC,
+	.opt_type = IH_TYPE_KERNEL,
+	.opt_comp = IH_COMP_GZIP,
+	.opt_dtc = MKIMAGE_DEFAULT_DTC_OPTIONS,
+	.addr = 0,
+	.ep = 0,
+	.imagename = "",
+	.datafile = "",
+	.imagefile = "",
+	.cmdname = "",
+};
 
 image_header_t header;
 image_header_t *hdr = &header;
@@ -54,96 +56,98 @@ 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;
 
-	cmdname = *argv;
+	params.cmdname = *argv;
 
-	addr = ep = 0;
+	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.opt_arch =
+					genimg_get_arch_id (*++argv)) < 0)
 					usage ();
 				goto NXTARG;
 			case 'C':
 				if ((--argc <= 0) ||
-				    (opt_comp = genimg_get_comp_id (*++argv)) < 0)
+					(params.opt_comp =
+					genimg_get_comp_id (*++argv)) < 0)
 					usage ();
 				goto NXTARG;
 			case 'D':
 				if (--argc <= 0)
 					usage ();
-				opt_dtc = *++argv;
+				params.opt_dtc = *++argv;
 				goto NXTARG;
 
 			case 'O':
 				if ((--argc <= 0) ||
-				    (opt_os = genimg_get_os_id (*++argv)) < 0)
+					(params.opt_os =
+					genimg_get_os_id (*++argv)) < 0)
 					usage ();
 				goto NXTARG;
 			case 'T':
 				if ((--argc <= 0) ||
-				    (opt_type = genimg_get_type_id (*++argv)) < 0)
+					(params.opt_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 ();
@@ -152,88 +156,89 @@ main (int argc, char **argv)
 NXTARG:		;
 	}
 
-	if ((argc != 1) ||
-		(dflag && (fflag || lflag)) ||
-		(fflag && (dflag || lflag)) ||
-		(lflag && (dflag || fflag)))
-		usage();
+	if ((argc != 1) || image_check_params (&params))
+		usage ();
 
-	if (!eflag) {
-		ep = addr;
+	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 += 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 ()) {
+	if (params.xflag) {
+		if (params.ep != params.addr + image_get_header_size ()) {
 			fprintf (stderr,
 				"%s: For XIP, the entry point must be the load addr + %lu\n",
-				cmdname,
+				params.cmdname,
 				(unsigned long)image_get_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 ()) {
 			fprintf (stderr,
 				"%s: Bad size: \"%s\" is no valid image\n",
-				cmdname, imagefile);
+				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 */
+				(char *)ptr, sbuf.st_size,
+				&params))) /* old-style image */
 			image_print_contents ((image_header_t *)ptr);
 
 		(void) munmap((void *)ptr, sbuf.st_size);
 		(void) close (ifd);
 
 		exit (retval);
-	} else if (fflag) {
+	} else if (params.fflag) {
 		/* Flattened Image Tree (FIT) format  handling */
 		debug ("FIT format handling\n");
-		fit_handle_file ();
+		fit_handle_file (&params);
 		exit (retval);
 	}
 
@@ -246,12 +251,12 @@ NXTARG:		;
 
 	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));
+			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.opt_type == IH_TYPE_MULTI || params.opt_type == IH_TYPE_SCRIPT) {
+		char *file = params.datafile;
 		uint32_t size;
 
 		for (;;) {
@@ -264,7 +269,7 @@ NXTARG:		;
 
 				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);
@@ -274,7 +279,8 @@ NXTARG:		;
 
 			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);
 			}
 
@@ -290,7 +296,7 @@ NXTARG:		;
 			}
 		}
 
-		file = datafile;
+		file = params.datafile;
 
 		for (;;) {
 			char *sep = strchr(file, ':');
@@ -305,7 +311,7 @@ NXTARG:		;
 			}
 		}
 	} else {
-		copy_file (ifd, datafile, 0);
+		copy_file (ifd, params.datafile, 0);
 	}
 
 	/* We're a bit of paranoid */
@@ -317,43 +323,20 @@ 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 = 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);
+	image_set_header (ptr, &sbuf, &params);
 
-	checksum = crc32 (0, (const char *)hdr, image_get_header_size ());
-
-	image_set_hcrc (hdr, checksum);
-
-	image_print_contents (hdr);
+	image_print_header (ptr);
 
 	(void) munmap((void *)ptr, sbuf.st_size);
 
@@ -366,7 +349,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);
 	}
 
@@ -384,30 +367,30 @@ copy_file (int ifd, const char *datafile, int pad)
 	int offset = 0;
 	int size;
 
-	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
@@ -418,7 +401,7 @@ copy_file (int ifd, const char *datafile, int pad)
 		if ((unsigned)sbuf.st_size < image_get_header_size ()) {
 			fprintf (stderr,
 				"%s: Bad size: \"%s\" is too small for XIP\n",
-				cmdname, datafile);
+				params.cmdname, datafile);
 			exit (EXIT_FAILURE);
 		}
 
@@ -426,7 +409,7 @@ copy_file (int ifd, const char *datafile, int pad)
 			if ( *p != 0xff ) {
 				fprintf (stderr,
 					"%s: Bad file: \"%s\" has invalid buffer for XIP\n",
-					cmdname, datafile);
+					params.cmdname, datafile);
 				exit (EXIT_FAILURE);
 			}
 		}
@@ -437,7 +420,7 @@ copy_file (int ifd, const char *datafile, int pad)
 	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);
 	}
 
@@ -445,7 +428,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);
 		}
 	}
@@ -459,7 +443,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"
@@ -471,157 +455,9 @@ usage ()
 			 "          -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;
-	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 = (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 = 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);
-	}
-}
diff --git a/tools/mkimage.h b/tools/mkimage.h
index 70c53ad..0418644 100644
--- a/tools/mkimage.h
+++ b/tools/mkimage.h
@@ -20,6 +20,9 @@
  * MA 02111-1307 USA
  */
 
+#ifndef _MKIIMAGE_H_
+#define _MKIIMAGE_H_
+
 #include "os_support.h"
 #include <errno.h>
 #include <fcntl.h>
@@ -45,3 +48,25 @@
 #define MKIMAGE_DEFAULT_DTC_OPTIONS	"-I dts -O dtb -p 500"
 #define MKIMAGE_MAX_DTC_CMDLINE_LEN	512
 #define MKIMAGE_DTC			"dtc"   /* assume dtc is in $PATH */
+
+struct mkimage_params {
+	int dflag;
+	int eflag;
+	int fflag;
+	int lflag;
+	int vflag;
+	int xflag;
+	int opt_os;
+	int opt_arch;
+	int opt_type;
+	int opt_comp;
+	char *opt_dtc;
+	uint32_t addr;
+	uint32_t ep;
+	char *imagename;
+	char *datafile;
+	char *imagefile;
+	char *cmdname;
+};
+
+#endif /* _MKIIMAGE_H_ */
-- 
1.5.3.3



More information about the U-Boot mailing list