All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bartlomiej Sieka <tur@semihalf.com>
To: u-boot@lists.denx.de
Subject: [U-Boot-Users] [PATCH 02/20] [new uImage] Add support for new uImage format to	mkimage tool
Date: Wed, 12 Mar 2008 21:10:37 +0100	[thread overview]
Message-ID: <20080312201037.6444.12357.stgit@pollux.denx.de> (raw)
In-Reply-To: <20080312201023.6444.52806.stgit@pollux.denx.de>

Support for the new uImage format (FIT) is added to mkimage tool.
Commandline syntax is appropriately extended:

mkimage [-D dtc_options] -f fit-image.its fit-image

mkimage (together with dtc) takes fit-image.its and referenced therein
binaries (like vmlinux.bin.gz) as inputs, and produces fit-image file -- the
final image that can be transferred to the target (e.g., via tftp) and then
booted using the bootm command in U-Boot.

Signed-off-by: Bartlomiej Sieka <tur@semihalf.com>
---

 include/image.h |   15 ++-
 tools/mkimage.c |  257 ++++++++++++++++++++++++++++++++++++++++++++-----------
 tools/mkimage.h |    6 +
 3 files changed, 222 insertions(+), 56 deletions(-)

diff --git a/include/image.h b/include/image.h
index bbd481d..681c753 100644
--- a/include/image.h
+++ b/include/image.h
@@ -40,14 +40,21 @@
 #include <lmb.h>
 #include <linux/string.h>
 #include <asm/u-boot.h>
-#endif /* USE_HOSTCC */
 
-/* new uImage format support enabled by default */
+/* new uImage format support enabled on target
+ * To be moved to board configuration file */
 #define CONFIG_FIT		1
 #define CONFIG_OF_LIBFDT	1
+#define CONFIG_FIT_VERBOSE	1 /* enable fit_format_{error,warning}() */
+
+#else
 
-/* enable fit_format_error(), fit_format_warning() */
-#define CONFIG_FIT_VERBOSE	1
+/* new uImage format support enabled on host */
+#define CONFIG_FIT		1
+#define CONFIG_OF_LIBFDT	1
+#define CONFIG_FIT_VERBOSE	1 /* enable fit_format_{error,warning}() */
+
+#endif /* USE_HOSTCC */
 
 #if defined(CONFIG_FIT) && !defined(CONFIG_OF_LIBFDT)
 #error "CONFIG_OF_LIBFDT not enabled, required by CONFIG_FIT!"
diff --git a/tools/mkimage.c b/tools/mkimage.c
index 5cb2bc7..6e1ff2b 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -1,4 +1,6 @@
 /*
+ * (C) Copyright 2008 Semihalf
+ *
  * (C) Copyright 2000-2004
  * DENX Software Engineering
  * Wolfgang Denk, wd at denx.de
@@ -32,6 +34,8 @@ extern int errno;
 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;
@@ -39,6 +43,7 @@ char	*cmdname;
 
 int dflag    = 0;
 int eflag    = 0;
+int fflag    = 0;
 int lflag    = 0;
 int vflag    = 0;
 int xflag    = 0;
@@ -46,6 +51,7 @@ 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;
@@ -53,7 +59,7 @@ image_header_t *hdr = &header;
 int
 main (int argc, char **argv)
 {
-	int ifd;
+	int ifd = -1;
 	uint32_t checksum;
 	uint32_t addr;
 	uint32_t ep;
@@ -81,6 +87,12 @@ main (int argc, char **argv)
 				    (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)
@@ -121,6 +133,12 @@ main (int argc, char **argv)
 				}
 				eflag = 1;
 				goto NXTARG;
+			case 'f':
+				if (--argc <= 0)
+					usage ();
+				datafile = *++argv;
+				fflag = 1;
+				goto NXTARG;
 			case 'n':
 				if (--argc <= 0)
 					usage ();
@@ -139,7 +157,10 @@ main (int argc, char **argv)
 NXTARG:		;
 	}
 
-	if ((argc != 1) || ((lflag ^ dflag) == 0))
+	if ((argc != 1) ||
+		(dflag && (fflag || lflag)) ||
+		(fflag && (dflag || lflag)) ||
+		(lflag && (dflag || fflag)))
 		usage();
 
 	if (!eflag) {
@@ -165,21 +186,22 @@ NXTARG:		;
 
 	imagefile = *argv;
 
-	if (lflag) {
-		ifd = open(imagefile, O_RDONLY|O_BINARY);
-	} else {
-		ifd = open(imagefile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666);
-	}
+	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 (ifd < 0) {
+			fprintf (stderr, "%s: Can't open %s: %s\n",
+				cmdname, imagefile, strerror(errno));
+			exit (EXIT_FAILURE);
+		}
 	}
 
 	if (lflag) {
-		int len;
-		char *data;
 		/*
 		 * list header information of existing image
 		 */
@@ -204,44 +226,24 @@ NXTARG:		;
 			exit (EXIT_FAILURE);
 		}
 
-		/*
-		 * image_check_hcrc() creates 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.
-		 */
-		hdr = (image_header_t *)ptr;
-
-		if (!image_check_magic (hdr)) {
-			fprintf (stderr,
-				"%s: Bad Magic Number: \"%s\" is no valid image\n",
-				cmdname, imagefile);
-			exit (EXIT_FAILURE);
-		}
-
-		if (!image_check_hcrc (hdr)) {
-			fprintf (stderr,
-				"%s: ERROR: \"%s\" has bad header checksum!\n",
-				cmdname, imagefile);
-			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);
 		}
 
-		data = (char *)image_get_data (hdr);
-		len  = sbuf.st_size - image_get_header_size ();
-
-		if (crc32(0, data, len) != image_get_dcrc (hdr)) {
-			fprintf (stderr,
-				"%s: ERROR: \"%s\" has corrupted data!\n",
-				cmdname, imagefile);
-			exit (EXIT_FAILURE);
-		}
-
-		/* for multi-file images we need the data part, too */
-		image_print_contents_noindent ((image_header_t *)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);
 	}
 
 	/*
@@ -467,11 +469,11 @@ void
 usage ()
 {
 	fprintf (stderr, "Usage: %s -l image\n"
-			 "          -l ==> list image header information\n"
-			 "       %s [-x] -A arch -O os -T type -C comp "
-			 "-a addr -e ep -n name -d data_file[:data_file...] image\n",
-		cmdname, cmdname);
-	fprintf (stderr, "          -A ==> set architecture to 'arch'\n"
+			 "          -l ==> list image header information\n",
+		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"
 			 "          -O ==> set operating system to 'os'\n"
 			 "          -T ==> set image type to 'type'\n"
 			 "          -C ==> set compression type 'comp'\n"
@@ -479,7 +481,158 @@ usage ()
 			 "          -e ==> set entry point to 'ep' (hex)\n"
 			 "          -n ==> set image name to 'name'\n"
 			 "          -d ==> use image data from 'datafile'\n"
-			 "          -x ==> set XIP (execute in place)\n"
-		);
+			 "          -x ==> set XIP (execute in place)\n",
+		cmdname);
+	fprintf (stderr, "       %s [-D dtc_options] -f fit-image.its fit-image\n",
+		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@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 41cd156..a2d5248 100644
--- a/tools/mkimage.h
+++ b/tools/mkimage.h
@@ -43,6 +43,12 @@
 #define debug(fmt,args...)
 #endif /* MKIMAGE_DEBUG */
 
+#define MKIMAGE_TMPFILE_SUFFIX		".tmp"
+#define MKIMAGE_MAX_TMPFILE_LEN		256
+#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 */
+
 #if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__)
 #include <inttypes.h>
 #endif

  parent reply	other threads:[~2008-03-12 20:10 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-12 20:10 [U-Boot-Users] [PATCH 00/20] [new uImage] patchset 7 - core functionality Bartlomiej Sieka
2008-03-12 20:10 ` [U-Boot-Users] [PATCH 01/20] [new uImage] Make node unit names const in struct bootm_headers Bartlomiej Sieka
2008-03-12 20:10 ` Bartlomiej Sieka [this message]
2008-03-14 14:54   ` [U-Boot-Users] [PATCH 02/20] [new uImage] Add support for new uImage format to mkimage tool Luigi 'Comio' Mantellini
2008-03-14 16:19     ` Bartlomiej Sieka
2008-03-12 20:10 ` [U-Boot-Users] [PATCH 03/20] [new uImage] Add new uImage format support for imls and iminfo commands Bartlomiej Sieka
2008-03-12 20:10 ` [U-Boot-Users] [PATCH 04/20] [new uImage] Add new uImage format support for kernel booting Bartlomiej Sieka
2008-03-12 20:10 ` [U-Boot-Users] [PATCH 05/20] [new uImage] Add new uImage format support for ramdisk handling Bartlomiej Sieka
2008-03-12 20:11 ` [U-Boot-Users] [PATCH 06/20] [new uImage] Remove unnecessary arguments passed to ramdisk routines Bartlomiej Sieka
2008-03-12 20:11 ` [U-Boot-Users] [PATCH 07/20] [new uImage] Re-enable interrupts for non automatic booting Bartlomiej Sieka
2008-03-12 20:11 ` [U-Boot-Users] [PATCH 08/20] [new uImage] ppc: Add new uImage format support to FDT handling routines Bartlomiej Sieka
2008-03-12 20:11 ` [U-Boot-Users] [PATCH 09/20] [new uImage] Add node offsets for FIT images listed in struct bootm_headers Bartlomiej Sieka
2008-03-12 20:11 ` [U-Boot-Users] [PATCH 10/20] [new uImage] Add new uImage format support to arch specific do_bootm_linux() routines Bartlomiej Sieka
2008-03-12 20:11 ` [U-Boot-Users] [PATCH 11/20] [new uImage] Add new uImage format support to autoscript routine Bartlomiej Sieka
2008-03-12 20:11 ` [U-Boot-Users] [PATCH 12/20] [new uImage] Add new uImage format support to imgextract command Bartlomiej Sieka
2008-03-12 20:11 ` [U-Boot-Users] [PATCH 13/20] [new uImage] Add new uImage format handling to other bootm related commands Bartlomiej Sieka
2008-03-12 20:11 ` [U-Boot-Users] [PATCH 14/20] [new uImage] Add new uImage fromat support to fpga command Bartlomiej Sieka
2008-03-12 20:12 ` [U-Boot-Users] [PATCH 15/20] [new uImage] Use show_boot_progress() for new uImage format Bartlomiej Sieka
2008-03-12 20:12 ` [U-Boot-Users] [PATCH 16/20] [new uImage] More verbose kernel image uncompress error message Bartlomiej Sieka
2008-03-12 20:12 ` [U-Boot-Users] [PATCH 17/20] [new uImage] Add proper ramdisk/FDT handling when FIT configuration is used Bartlomiej Sieka
2008-03-12 20:12 ` [U-Boot-Users] [PATCH 18/20] [new uImage] Fix build problems on trab board Bartlomiej Sieka
2008-03-12 20:55   ` Wolfgang Denk
2008-03-19  9:01     ` Bartlomiej Sieka
2008-03-12 20:12 ` [U-Boot-Users] [PATCH 19/20] [new uImage] Fix definition of common bootm_headers_t fields Bartlomiej Sieka
2008-03-12 20:12 ` [U-Boot-Users] [PATCH 20/20] [new uImage] Add new uImage format documentation and examples Bartlomiej Sieka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080312201037.6444.12357.stgit@pollux.denx.de \
    --to=tur@semihalf.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.