xref: /openbmc/u-boot/tools/mkimage.c (revision 89a4d6b12fd6394898b8a454cbabeaf1cd59bae5)
15b1d7137Swdenk /*
29d25438fSBartlomiej Sieka  * (C) Copyright 2008 Semihalf
39d25438fSBartlomiej Sieka  *
4*89a4d6b1SPrafulla Wadaskar  * (C) Copyright 2000-2009
55b1d7137Swdenk  * DENX Software Engineering
65b1d7137Swdenk  * Wolfgang Denk, wd@denx.de
70c852a28Swdenk  *
80c852a28Swdenk  * This program is free software; you can redistribute it and/or
90c852a28Swdenk  * modify it under the terms of the GNU General Public License as
100c852a28Swdenk  * published by the Free Software Foundation; either version 2 of
110c852a28Swdenk  * the License, or (at your option) any later version.
120c852a28Swdenk  *
130c852a28Swdenk  * This program is distributed in the hope that it will be useful,
140c852a28Swdenk  * but WITHOUT ANY WARRANTY; without even the implied warranty of
150c852a28Swdenk  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
160c852a28Swdenk  * GNU General Public License for more details.
170c852a28Swdenk  *
180c852a28Swdenk  * You should have received a copy of the GNU General Public License
190c852a28Swdenk  * along with this program; if not, write to the Free Software
200c852a28Swdenk  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
210c852a28Swdenk  * MA 02111-1307 USA
225b1d7137Swdenk  */
235b1d7137Swdenk 
24b97a2a0aSMarian Balakowicz #include "mkimage.h"
255b1d7137Swdenk #include <image.h>
265b1d7137Swdenk 
275b1d7137Swdenk static void copy_file(int, const char *, int);
285b1d7137Swdenk static void usage(void);
295b1d7137Swdenk 
30*89a4d6b1SPrafulla Wadaskar /* image_type_params link list to maintain registered image type supports */
31*89a4d6b1SPrafulla Wadaskar struct image_type_params *mkimage_tparams = NULL;
325b1d7137Swdenk 
33*89a4d6b1SPrafulla Wadaskar /* parameters initialized by core will be used by the image type code */
34*89a4d6b1SPrafulla Wadaskar struct mkimage_params params = {
35*89a4d6b1SPrafulla Wadaskar 	.os = IH_OS_LINUX,
36*89a4d6b1SPrafulla Wadaskar 	.arch = IH_ARCH_PPC,
37*89a4d6b1SPrafulla Wadaskar 	.type = IH_TYPE_KERNEL,
38*89a4d6b1SPrafulla Wadaskar 	.comp = IH_COMP_GZIP,
39*89a4d6b1SPrafulla Wadaskar 	.dtc = MKIMAGE_DEFAULT_DTC_OPTIONS,
40*89a4d6b1SPrafulla Wadaskar };
415b1d7137Swdenk 
42*89a4d6b1SPrafulla Wadaskar /*
43*89a4d6b1SPrafulla Wadaskar  * mkimage_register -
44*89a4d6b1SPrafulla Wadaskar  *
45*89a4d6b1SPrafulla Wadaskar  * It is used to register respective image generation/list support to the
46*89a4d6b1SPrafulla Wadaskar  * mkimage core
47*89a4d6b1SPrafulla Wadaskar  *
48*89a4d6b1SPrafulla Wadaskar  * the input struct image_type_params is checked and appended to the link
49*89a4d6b1SPrafulla Wadaskar  * list, if the input structure is already registered, error
50*89a4d6b1SPrafulla Wadaskar  */
51*89a4d6b1SPrafulla Wadaskar void mkimage_register (struct image_type_params *tparams)
52*89a4d6b1SPrafulla Wadaskar {
53*89a4d6b1SPrafulla Wadaskar 	struct image_type_params **tp;
54*89a4d6b1SPrafulla Wadaskar 
55*89a4d6b1SPrafulla Wadaskar 	if (!tparams) {
56*89a4d6b1SPrafulla Wadaskar 		fprintf (stderr, "%s: %s: Null input\n",
57*89a4d6b1SPrafulla Wadaskar 			params.cmdname, __FUNCTION__);
58*89a4d6b1SPrafulla Wadaskar 		exit (EXIT_FAILURE);
59*89a4d6b1SPrafulla Wadaskar 	}
60*89a4d6b1SPrafulla Wadaskar 
61*89a4d6b1SPrafulla Wadaskar 	/* scan the linked list, check for registry and point the last one */
62*89a4d6b1SPrafulla Wadaskar 	for (tp = &mkimage_tparams; *tp != NULL; tp = &(*tp)->next) {
63*89a4d6b1SPrafulla Wadaskar 		if (!strcmp((*tp)->name, tparams->name)) {
64*89a4d6b1SPrafulla Wadaskar 			fprintf (stderr, "%s: %s already registered\n",
65*89a4d6b1SPrafulla Wadaskar 				params.cmdname, tparams->name);
66*89a4d6b1SPrafulla Wadaskar 			return;
67*89a4d6b1SPrafulla Wadaskar 		}
68*89a4d6b1SPrafulla Wadaskar 	}
69*89a4d6b1SPrafulla Wadaskar 
70*89a4d6b1SPrafulla Wadaskar 	/* add input struct entry at the end of link list */
71*89a4d6b1SPrafulla Wadaskar 	*tp = tparams;
72*89a4d6b1SPrafulla Wadaskar 	/* mark input entry as last entry in the link list */
73*89a4d6b1SPrafulla Wadaskar 	tparams->next = NULL;
74*89a4d6b1SPrafulla Wadaskar 
75*89a4d6b1SPrafulla Wadaskar 	debug ("Registered %s\n", tparams->name);
76*89a4d6b1SPrafulla Wadaskar }
77*89a4d6b1SPrafulla Wadaskar 
78*89a4d6b1SPrafulla Wadaskar /*
79*89a4d6b1SPrafulla Wadaskar  * mkimage_get_type -
80*89a4d6b1SPrafulla Wadaskar  *
81*89a4d6b1SPrafulla Wadaskar  * It scans all registers image type supports
82*89a4d6b1SPrafulla Wadaskar  * checks the input type_id for each supported image type
83*89a4d6b1SPrafulla Wadaskar  *
84*89a4d6b1SPrafulla Wadaskar  * if successful,
85*89a4d6b1SPrafulla Wadaskar  * 	returns respective image_type_params pointer if success
86*89a4d6b1SPrafulla Wadaskar  * if input type_id is not supported by any of image_type_support
87*89a4d6b1SPrafulla Wadaskar  * 	returns NULL
88*89a4d6b1SPrafulla Wadaskar  */
89*89a4d6b1SPrafulla Wadaskar struct image_type_params *mkimage_get_type(int type)
90*89a4d6b1SPrafulla Wadaskar {
91*89a4d6b1SPrafulla Wadaskar 	struct image_type_params *curr;
92*89a4d6b1SPrafulla Wadaskar 
93*89a4d6b1SPrafulla Wadaskar 	for (curr = mkimage_tparams; curr != NULL; curr = curr->next) {
94*89a4d6b1SPrafulla Wadaskar 		if (curr->check_image_type) {
95*89a4d6b1SPrafulla Wadaskar 			if (!curr->check_image_type (type))
96*89a4d6b1SPrafulla Wadaskar 				return curr;
97*89a4d6b1SPrafulla Wadaskar 		}
98*89a4d6b1SPrafulla Wadaskar 	}
99*89a4d6b1SPrafulla Wadaskar 	return NULL;
100*89a4d6b1SPrafulla Wadaskar }
101*89a4d6b1SPrafulla Wadaskar 
102*89a4d6b1SPrafulla Wadaskar /*
103*89a4d6b1SPrafulla Wadaskar  * mkimage_verify_print_header -
104*89a4d6b1SPrafulla Wadaskar  *
105*89a4d6b1SPrafulla Wadaskar  * It scans mkimage_tparams link list,
106*89a4d6b1SPrafulla Wadaskar  * verifies image_header for each supported image type
107*89a4d6b1SPrafulla Wadaskar  * if verification is successful, prints respective header
108*89a4d6b1SPrafulla Wadaskar  *
109*89a4d6b1SPrafulla Wadaskar  * returns negative if input image format does not match with any of
110*89a4d6b1SPrafulla Wadaskar  * supported image types
111*89a4d6b1SPrafulla Wadaskar  */
112*89a4d6b1SPrafulla Wadaskar int mkimage_verify_print_header (void *ptr, struct stat *sbuf)
113*89a4d6b1SPrafulla Wadaskar {
114*89a4d6b1SPrafulla Wadaskar 	int retval = -1;
115*89a4d6b1SPrafulla Wadaskar 	struct image_type_params *curr;
116*89a4d6b1SPrafulla Wadaskar 
117*89a4d6b1SPrafulla Wadaskar 	for (curr = mkimage_tparams; curr != NULL; curr = curr->next ) {
118*89a4d6b1SPrafulla Wadaskar 		if (curr->verify_header) {
119*89a4d6b1SPrafulla Wadaskar 			retval = curr->verify_header (
120*89a4d6b1SPrafulla Wadaskar 				(unsigned char *)ptr, sbuf->st_size,
121*89a4d6b1SPrafulla Wadaskar 				&params);
122*89a4d6b1SPrafulla Wadaskar 
123*89a4d6b1SPrafulla Wadaskar 			if (retval == 0) {
124*89a4d6b1SPrafulla Wadaskar 				/*
125*89a4d6b1SPrafulla Wadaskar 				 * Print the image information
126*89a4d6b1SPrafulla Wadaskar 				 * if verify is successful
127*89a4d6b1SPrafulla Wadaskar 				 */
128*89a4d6b1SPrafulla Wadaskar 				if (curr->print_header)
129*89a4d6b1SPrafulla Wadaskar 					curr->print_header (ptr);
130*89a4d6b1SPrafulla Wadaskar 				else {
131*89a4d6b1SPrafulla Wadaskar 					fprintf (stderr,
132*89a4d6b1SPrafulla Wadaskar 					"%s: print_header undefined for %s\n",
133*89a4d6b1SPrafulla Wadaskar 					params.cmdname, curr->name);
134*89a4d6b1SPrafulla Wadaskar 				}
135*89a4d6b1SPrafulla Wadaskar 				break;
136*89a4d6b1SPrafulla Wadaskar 			}
137*89a4d6b1SPrafulla Wadaskar 		}
138*89a4d6b1SPrafulla Wadaskar 	}
139*89a4d6b1SPrafulla Wadaskar 	return retval;
140*89a4d6b1SPrafulla Wadaskar }
1415b1d7137Swdenk 
1425b1d7137Swdenk int
1435b1d7137Swdenk main (int argc, char **argv)
1445b1d7137Swdenk {
1459d25438fSBartlomiej Sieka 	int ifd = -1;
1465b1d7137Swdenk 	struct stat sbuf;
1475b1d7137Swdenk 	unsigned char *ptr;
148449609f5SPrafulla Wadaskar 	int retval = 0;
149*89a4d6b1SPrafulla Wadaskar 	struct image_type_params *tparams = NULL;
1505b1d7137Swdenk 
151*89a4d6b1SPrafulla Wadaskar 	/* Init FIT image generation/list support */
152*89a4d6b1SPrafulla Wadaskar 	init_fit_image_type ();
153*89a4d6b1SPrafulla Wadaskar 	/* Init Default image generation/list support */
154*89a4d6b1SPrafulla Wadaskar 	init_default_image_type ();
1555b1d7137Swdenk 
156*89a4d6b1SPrafulla Wadaskar 	params.cmdname = *argv;
157*89a4d6b1SPrafulla Wadaskar 	params.addr = params.ep = 0;
1585b1d7137Swdenk 
1595b1d7137Swdenk 	while (--argc > 0 && **++argv == '-') {
1605b1d7137Swdenk 		while (*++*argv) {
1615b1d7137Swdenk 			switch (**argv) {
1625b1d7137Swdenk 			case 'l':
163*89a4d6b1SPrafulla Wadaskar 				params.lflag = 1;
1645b1d7137Swdenk 				break;
1655b1d7137Swdenk 			case 'A':
1665b1d7137Swdenk 				if ((--argc <= 0) ||
167*89a4d6b1SPrafulla Wadaskar 					(params.arch =
168*89a4d6b1SPrafulla Wadaskar 					genimg_get_arch_id (*++argv)) < 0)
1695b1d7137Swdenk 					usage ();
1705b1d7137Swdenk 				goto NXTARG;
1715b1d7137Swdenk 			case 'C':
1725b1d7137Swdenk 				if ((--argc <= 0) ||
173*89a4d6b1SPrafulla Wadaskar 					(params.comp =
174*89a4d6b1SPrafulla Wadaskar 					genimg_get_comp_id (*++argv)) < 0)
1755b1d7137Swdenk 					usage ();
1765b1d7137Swdenk 				goto NXTARG;
1779d25438fSBartlomiej Sieka 			case 'D':
1789d25438fSBartlomiej Sieka 				if (--argc <= 0)
1799d25438fSBartlomiej Sieka 					usage ();
180*89a4d6b1SPrafulla Wadaskar 				params.dtc = *++argv;
1819d25438fSBartlomiej Sieka 				goto NXTARG;
1829d25438fSBartlomiej Sieka 
1835b1d7137Swdenk 			case 'O':
1845b1d7137Swdenk 				if ((--argc <= 0) ||
185*89a4d6b1SPrafulla Wadaskar 					(params.os =
186*89a4d6b1SPrafulla Wadaskar 					genimg_get_os_id (*++argv)) < 0)
1875b1d7137Swdenk 					usage ();
1885b1d7137Swdenk 				goto NXTARG;
1895b1d7137Swdenk 			case 'T':
1905b1d7137Swdenk 				if ((--argc <= 0) ||
191*89a4d6b1SPrafulla Wadaskar 					(params.type =
192*89a4d6b1SPrafulla Wadaskar 					genimg_get_type_id (*++argv)) < 0)
1935b1d7137Swdenk 					usage ();
1945b1d7137Swdenk 				goto NXTARG;
1955b1d7137Swdenk 
1965b1d7137Swdenk 			case 'a':
1975b1d7137Swdenk 				if (--argc <= 0)
1985b1d7137Swdenk 					usage ();
199*89a4d6b1SPrafulla Wadaskar 				params.addr = strtoul (*++argv,
200*89a4d6b1SPrafulla Wadaskar 					(char **)&ptr, 16);
2015b1d7137Swdenk 				if (*ptr) {
2025b1d7137Swdenk 					fprintf (stderr,
2035b1d7137Swdenk 						"%s: invalid load address %s\n",
204*89a4d6b1SPrafulla Wadaskar 						params.cmdname, *argv);
2055b1d7137Swdenk 					exit (EXIT_FAILURE);
2065b1d7137Swdenk 				}
2075b1d7137Swdenk 				goto NXTARG;
2085b1d7137Swdenk 			case 'd':
2095b1d7137Swdenk 				if (--argc <= 0)
2105b1d7137Swdenk 					usage ();
211*89a4d6b1SPrafulla Wadaskar 				params.datafile = *++argv;
212*89a4d6b1SPrafulla Wadaskar 				params.dflag = 1;
2135b1d7137Swdenk 				goto NXTARG;
2145b1d7137Swdenk 			case 'e':
2155b1d7137Swdenk 				if (--argc <= 0)
2165b1d7137Swdenk 					usage ();
217*89a4d6b1SPrafulla Wadaskar 				params.ep = strtoul (*++argv,
218*89a4d6b1SPrafulla Wadaskar 						(char **)&ptr, 16);
2195b1d7137Swdenk 				if (*ptr) {
2205b1d7137Swdenk 					fprintf (stderr,
2215b1d7137Swdenk 						"%s: invalid entry point %s\n",
222*89a4d6b1SPrafulla Wadaskar 						params.cmdname, *argv);
2235b1d7137Swdenk 					exit (EXIT_FAILURE);
2245b1d7137Swdenk 				}
225*89a4d6b1SPrafulla Wadaskar 				params.eflag = 1;
2265b1d7137Swdenk 				goto NXTARG;
2279d25438fSBartlomiej Sieka 			case 'f':
2289d25438fSBartlomiej Sieka 				if (--argc <= 0)
2299d25438fSBartlomiej Sieka 					usage ();
230*89a4d6b1SPrafulla Wadaskar 				params.datafile = *++argv;
231*89a4d6b1SPrafulla Wadaskar 				params.fflag = 1;
2329d25438fSBartlomiej Sieka 				goto NXTARG;
2335b1d7137Swdenk 			case 'n':
2345b1d7137Swdenk 				if (--argc <= 0)
2355b1d7137Swdenk 					usage ();
236*89a4d6b1SPrafulla Wadaskar 				params.imagename = *++argv;
2375b1d7137Swdenk 				goto NXTARG;
2385b1d7137Swdenk 			case 'v':
239*89a4d6b1SPrafulla Wadaskar 				params.vflag++;
2405b1d7137Swdenk 				break;
2415b1d7137Swdenk 			case 'x':
242*89a4d6b1SPrafulla Wadaskar 				params.xflag++;
2435b1d7137Swdenk 				break;
2445b1d7137Swdenk 			default:
2455b1d7137Swdenk 				usage ();
2465b1d7137Swdenk 			}
2475b1d7137Swdenk 		}
2485b1d7137Swdenk NXTARG:		;
2495b1d7137Swdenk 	}
2505b1d7137Swdenk 
251*89a4d6b1SPrafulla Wadaskar 	if (argc != 1)
2525b1d7137Swdenk 		usage ();
2535b1d7137Swdenk 
254*89a4d6b1SPrafulla Wadaskar 	/* set tparams as per input type_id */
255*89a4d6b1SPrafulla Wadaskar 	tparams = mkimage_get_type(params.type);
256*89a4d6b1SPrafulla Wadaskar 	if (tparams == NULL) {
257*89a4d6b1SPrafulla Wadaskar 		fprintf (stderr, "%s: unsupported type %s\n",
258*89a4d6b1SPrafulla Wadaskar 			params.cmdname, genimg_get_type_name(params.type));
259*89a4d6b1SPrafulla Wadaskar 		exit (EXIT_FAILURE);
260*89a4d6b1SPrafulla Wadaskar 	}
261*89a4d6b1SPrafulla Wadaskar 
262*89a4d6b1SPrafulla Wadaskar 	/*
263*89a4d6b1SPrafulla Wadaskar 	 * check the passed arguments parameters meets the requirements
264*89a4d6b1SPrafulla Wadaskar 	 * as per image type to be generated/listed
265*89a4d6b1SPrafulla Wadaskar 	 */
266*89a4d6b1SPrafulla Wadaskar 	if (tparams->check_params)
267*89a4d6b1SPrafulla Wadaskar 		if (tparams->check_params (&params))
268*89a4d6b1SPrafulla Wadaskar 			usage ();
269*89a4d6b1SPrafulla Wadaskar 
270*89a4d6b1SPrafulla Wadaskar 	if (!params.eflag) {
271*89a4d6b1SPrafulla Wadaskar 		params.ep = params.addr;
2725b1d7137Swdenk 		/* If XIP, entry point must be after the U-Boot header */
273*89a4d6b1SPrafulla Wadaskar 		if (params.xflag)
274*89a4d6b1SPrafulla Wadaskar 			params.ep += tparams->header_size;
2755b1d7137Swdenk 	}
2765b1d7137Swdenk 
2775b1d7137Swdenk 	/*
2785b1d7137Swdenk 	 * If XIP, ensure the entry point is equal to the load address plus
2795b1d7137Swdenk 	 * the size of the U-Boot header.
2805b1d7137Swdenk 	 */
281*89a4d6b1SPrafulla Wadaskar 	if (params.xflag) {
282*89a4d6b1SPrafulla Wadaskar 		if (params.ep != params.addr + tparams->header_size) {
2833577d3a3SWolfgang Denk 			fprintf (stderr,
2843577d3a3SWolfgang Denk 				"%s: For XIP, the entry point must be the load addr + %lu\n",
285*89a4d6b1SPrafulla Wadaskar 				params.cmdname,
286*89a4d6b1SPrafulla Wadaskar 				(unsigned long)tparams->header_size);
2875b1d7137Swdenk 			exit (EXIT_FAILURE);
2885b1d7137Swdenk 		}
2895b1d7137Swdenk 	}
2905b1d7137Swdenk 
291*89a4d6b1SPrafulla Wadaskar 	params.imagefile = *argv;
2925b1d7137Swdenk 
293*89a4d6b1SPrafulla Wadaskar 	if (!params.fflag){
294*89a4d6b1SPrafulla Wadaskar 		if (params.lflag) {
295*89a4d6b1SPrafulla Wadaskar 			ifd = open (params.imagefile, O_RDONLY|O_BINARY);
2965b1d7137Swdenk 		} else {
297*89a4d6b1SPrafulla Wadaskar 			ifd = open (params.imagefile,
2989d25438fSBartlomiej Sieka 				O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666);
2995b1d7137Swdenk 		}
3005b1d7137Swdenk 
3015b1d7137Swdenk 		if (ifd < 0) {
3025b1d7137Swdenk 			fprintf (stderr, "%s: Can't open %s: %s\n",
303*89a4d6b1SPrafulla Wadaskar 				params.cmdname, params.imagefile,
304*89a4d6b1SPrafulla Wadaskar 				strerror(errno));
3055b1d7137Swdenk 			exit (EXIT_FAILURE);
3065b1d7137Swdenk 		}
3079d25438fSBartlomiej Sieka 	}
3085b1d7137Swdenk 
309*89a4d6b1SPrafulla Wadaskar 	if (params.lflag) {
3105b1d7137Swdenk 		/*
3115b1d7137Swdenk 		 * list header information of existing image
3125b1d7137Swdenk 		 */
3135b1d7137Swdenk 		if (fstat(ifd, &sbuf) < 0) {
3145b1d7137Swdenk 			fprintf (stderr, "%s: Can't stat %s: %s\n",
315*89a4d6b1SPrafulla Wadaskar 				params.cmdname, params.imagefile,
316*89a4d6b1SPrafulla Wadaskar 				strerror(errno));
3175b1d7137Swdenk 			exit (EXIT_FAILURE);
3185b1d7137Swdenk 		}
3195b1d7137Swdenk 
320*89a4d6b1SPrafulla Wadaskar 		if ((unsigned)sbuf.st_size < tparams->header_size) {
3215b1d7137Swdenk 			fprintf (stderr,
322*89a4d6b1SPrafulla Wadaskar 				"%s: Bad size: \"%s\" is not valid image\n",
323*89a4d6b1SPrafulla Wadaskar 				params.cmdname, params.imagefile);
3245b1d7137Swdenk 			exit (EXIT_FAILURE);
3255b1d7137Swdenk 		}
3265b1d7137Swdenk 
327fa956fdeSMike Frysinger 		ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0);
328fa956fdeSMike Frysinger 		if (ptr == MAP_FAILED) {
3295b1d7137Swdenk 			fprintf (stderr, "%s: Can't read %s: %s\n",
330*89a4d6b1SPrafulla Wadaskar 				params.cmdname, params.imagefile,
331*89a4d6b1SPrafulla Wadaskar 				strerror(errno));
3325b1d7137Swdenk 			exit (EXIT_FAILURE);
3335b1d7137Swdenk 		}
3345b1d7137Swdenk 
335*89a4d6b1SPrafulla Wadaskar 		/*
336*89a4d6b1SPrafulla Wadaskar 		 * scan through mkimage registry for all supported image types
337*89a4d6b1SPrafulla Wadaskar 		 * and verify the input image file header for match
338*89a4d6b1SPrafulla Wadaskar 		 * Print the image information for matched image type
339*89a4d6b1SPrafulla Wadaskar 		 * Returns the error code if not matched
340*89a4d6b1SPrafulla Wadaskar 		 */
341*89a4d6b1SPrafulla Wadaskar 		retval = mkimage_verify_print_header (ptr, &sbuf);
3425b1d7137Swdenk 
3435b1d7137Swdenk 		(void) munmap((void *)ptr, sbuf.st_size);
3445b1d7137Swdenk 		(void) close (ifd);
3455b1d7137Swdenk 
346f7644c0bSPrafulla Wadaskar 		exit (retval);
347*89a4d6b1SPrafulla Wadaskar 	} else if (params.fflag) {
348*89a4d6b1SPrafulla Wadaskar 		if (tparams->fflag_handle)
349*89a4d6b1SPrafulla Wadaskar 			/*
350*89a4d6b1SPrafulla Wadaskar 			 * in some cases, some additional processing needs
351*89a4d6b1SPrafulla Wadaskar 			 * to be done if fflag is defined
352*89a4d6b1SPrafulla Wadaskar 			 *
353*89a4d6b1SPrafulla Wadaskar 			 * For ex. fit_handle_file for Fit file support
354*89a4d6b1SPrafulla Wadaskar 			 */
355*89a4d6b1SPrafulla Wadaskar 			retval = tparams->fflag_handle(&params);
356*89a4d6b1SPrafulla Wadaskar 
357f7644c0bSPrafulla Wadaskar 		exit (retval);
3585b1d7137Swdenk 	}
3595b1d7137Swdenk 
3605b1d7137Swdenk 	/*
3615b1d7137Swdenk 	 * Must be -w then:
3625b1d7137Swdenk 	 *
3635b1d7137Swdenk 	 * write dummy header, to be fixed later
3645b1d7137Swdenk 	 */
365*89a4d6b1SPrafulla Wadaskar 	memset (tparams->hdr, 0, tparams->header_size);
3665b1d7137Swdenk 
367*89a4d6b1SPrafulla Wadaskar 	if (write(ifd, tparams->hdr, tparams->header_size)
368*89a4d6b1SPrafulla Wadaskar 					!= tparams->header_size) {
3695b1d7137Swdenk 		fprintf (stderr, "%s: Write error on %s: %s\n",
370*89a4d6b1SPrafulla Wadaskar 			params.cmdname, params.imagefile, strerror(errno));
3715b1d7137Swdenk 		exit (EXIT_FAILURE);
3725b1d7137Swdenk 	}
3735b1d7137Swdenk 
374*89a4d6b1SPrafulla Wadaskar 	if (params.type == IH_TYPE_MULTI || params.type == IH_TYPE_SCRIPT) {
375*89a4d6b1SPrafulla Wadaskar 		char *file = params.datafile;
3763bb66806SWolfgang Denk 		uint32_t size;
3775b1d7137Swdenk 
3785b1d7137Swdenk 		for (;;) {
3795b1d7137Swdenk 			char *sep = NULL;
3805b1d7137Swdenk 
3815b1d7137Swdenk 			if (file) {
3825b1d7137Swdenk 				if ((sep = strchr(file, ':')) != NULL) {
3835b1d7137Swdenk 					*sep = '\0';
3845b1d7137Swdenk 				}
3855b1d7137Swdenk 
3865b1d7137Swdenk 				if (stat (file, &sbuf) < 0) {
3875b1d7137Swdenk 					fprintf (stderr, "%s: Can't stat %s: %s\n",
388*89a4d6b1SPrafulla Wadaskar 						params.cmdname, file, strerror(errno));
3895b1d7137Swdenk 					exit (EXIT_FAILURE);
3905b1d7137Swdenk 				}
3919a4daad0SMarian Balakowicz 				size = cpu_to_uimage (sbuf.st_size);
3925b1d7137Swdenk 			} else {
3935b1d7137Swdenk 				size = 0;
3945b1d7137Swdenk 			}
3955b1d7137Swdenk 
3965b1d7137Swdenk 			if (write(ifd, (char *)&size, sizeof(size)) != sizeof(size)) {
3975b1d7137Swdenk 				fprintf (stderr, "%s: Write error on %s: %s\n",
398*89a4d6b1SPrafulla Wadaskar 					params.cmdname, params.imagefile,
399*89a4d6b1SPrafulla Wadaskar 					strerror(errno));
4005b1d7137Swdenk 				exit (EXIT_FAILURE);
4015b1d7137Swdenk 			}
4025b1d7137Swdenk 
4035b1d7137Swdenk 			if (!file) {
4045b1d7137Swdenk 				break;
4055b1d7137Swdenk 			}
4065b1d7137Swdenk 
4075b1d7137Swdenk 			if (sep) {
4085b1d7137Swdenk 				*sep = ':';
4095b1d7137Swdenk 				file = sep + 1;
4105b1d7137Swdenk 			} else {
4115b1d7137Swdenk 				file = NULL;
4125b1d7137Swdenk 			}
4135b1d7137Swdenk 		}
4145b1d7137Swdenk 
415*89a4d6b1SPrafulla Wadaskar 		file = params.datafile;
4165b1d7137Swdenk 
4175b1d7137Swdenk 		for (;;) {
4185b1d7137Swdenk 			char *sep = strchr(file, ':');
4195b1d7137Swdenk 			if (sep) {
4205b1d7137Swdenk 				*sep = '\0';
4215b1d7137Swdenk 				copy_file (ifd, file, 1);
4225b1d7137Swdenk 				*sep++ = ':';
4235b1d7137Swdenk 				file = sep;
4245b1d7137Swdenk 			} else {
4255b1d7137Swdenk 				copy_file (ifd, file, 0);
4265b1d7137Swdenk 				break;
4275b1d7137Swdenk 			}
4285b1d7137Swdenk 		}
4295b1d7137Swdenk 	} else {
430*89a4d6b1SPrafulla Wadaskar 		copy_file (ifd, params.datafile, 0);
4315b1d7137Swdenk 	}
4325b1d7137Swdenk 
4335b1d7137Swdenk 	/* We're a bit of paranoid */
434*89a4d6b1SPrafulla Wadaskar #if defined(_POSIX_SYNCHRONIZED_IO) && \
435*89a4d6b1SPrafulla Wadaskar    !defined(__sun__) && \
436*89a4d6b1SPrafulla Wadaskar    !defined(__FreeBSD__) && \
437*89a4d6b1SPrafulla Wadaskar    !defined(__APPLE__)
4385b1d7137Swdenk 	(void) fdatasync (ifd);
4395b1d7137Swdenk #else
4405b1d7137Swdenk 	(void) fsync (ifd);
4415b1d7137Swdenk #endif
4425b1d7137Swdenk 
4435b1d7137Swdenk 	if (fstat(ifd, &sbuf) < 0) {
4445b1d7137Swdenk 		fprintf (stderr, "%s: Can't stat %s: %s\n",
445*89a4d6b1SPrafulla Wadaskar 			params.cmdname, params.imagefile, strerror(errno));
4465b1d7137Swdenk 		exit (EXIT_FAILURE);
4475b1d7137Swdenk 	}
4485b1d7137Swdenk 
449fa956fdeSMike Frysinger 	ptr = mmap(0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0);
450fa956fdeSMike Frysinger 	if (ptr == MAP_FAILED) {
4515b1d7137Swdenk 		fprintf (stderr, "%s: Can't map %s: %s\n",
452*89a4d6b1SPrafulla Wadaskar 			params.cmdname, params.imagefile, strerror(errno));
4535b1d7137Swdenk 		exit (EXIT_FAILURE);
4545b1d7137Swdenk 	}
4555b1d7137Swdenk 
456*89a4d6b1SPrafulla Wadaskar 	/* Setup the image header as per input image type*/
457*89a4d6b1SPrafulla Wadaskar 	if (tparams->set_header)
458*89a4d6b1SPrafulla Wadaskar 		tparams->set_header (ptr, &sbuf, ifd, &params);
459*89a4d6b1SPrafulla Wadaskar 	else {
460*89a4d6b1SPrafulla Wadaskar 		fprintf (stderr, "%s: Can't set header for %s: %s\n",
461*89a4d6b1SPrafulla Wadaskar 			params.cmdname, tparams->name, strerror(errno));
462*89a4d6b1SPrafulla Wadaskar 		exit (EXIT_FAILURE);
463*89a4d6b1SPrafulla Wadaskar 	}
4645b1d7137Swdenk 
465*89a4d6b1SPrafulla Wadaskar 	/* Print the image information by processing image header */
466*89a4d6b1SPrafulla Wadaskar 	if (tparams->print_header)
467*89a4d6b1SPrafulla Wadaskar 		tparams->print_header (ptr);
468*89a4d6b1SPrafulla Wadaskar 	else {
469*89a4d6b1SPrafulla Wadaskar 		fprintf (stderr, "%s: Can't print header for %s: %s\n",
470*89a4d6b1SPrafulla Wadaskar 			params.cmdname, tparams->name, strerror(errno));
471*89a4d6b1SPrafulla Wadaskar 		exit (EXIT_FAILURE);
472*89a4d6b1SPrafulla Wadaskar 	}
4735b1d7137Swdenk 
4745b1d7137Swdenk 	(void) munmap((void *)ptr, sbuf.st_size);
4755b1d7137Swdenk 
4765b1d7137Swdenk 	/* We're a bit of paranoid */
477*89a4d6b1SPrafulla Wadaskar #if defined(_POSIX_SYNCHRONIZED_IO) && \
478*89a4d6b1SPrafulla Wadaskar    !defined(__sun__) && \
479*89a4d6b1SPrafulla Wadaskar    !defined(__FreeBSD__) && \
480*89a4d6b1SPrafulla Wadaskar    !defined(__APPLE__)
4815b1d7137Swdenk 	(void) fdatasync (ifd);
4825b1d7137Swdenk #else
4835b1d7137Swdenk 	(void) fsync (ifd);
4845b1d7137Swdenk #endif
4855b1d7137Swdenk 
4865b1d7137Swdenk 	if (close(ifd)) {
4875b1d7137Swdenk 		fprintf (stderr, "%s: Write error on %s: %s\n",
488*89a4d6b1SPrafulla Wadaskar 			params.cmdname, params.imagefile, strerror(errno));
4895b1d7137Swdenk 		exit (EXIT_FAILURE);
4905b1d7137Swdenk 	}
4915b1d7137Swdenk 
4925b1d7137Swdenk 	exit (EXIT_SUCCESS);
4935b1d7137Swdenk }
4945b1d7137Swdenk 
4955b1d7137Swdenk static void
4965b1d7137Swdenk copy_file (int ifd, const char *datafile, int pad)
4975b1d7137Swdenk {
4985b1d7137Swdenk 	int dfd;
4995b1d7137Swdenk 	struct stat sbuf;
5005b1d7137Swdenk 	unsigned char *ptr;
5015b1d7137Swdenk 	int tail;
5025b1d7137Swdenk 	int zero = 0;
5035b1d7137Swdenk 	int offset = 0;
5045b1d7137Swdenk 	int size;
505*89a4d6b1SPrafulla Wadaskar 	struct image_type_params *tparams = mkimage_get_type (params.type);
5065b1d7137Swdenk 
507*89a4d6b1SPrafulla Wadaskar 	if (params.vflag) {
5085b1d7137Swdenk 		fprintf (stderr, "Adding Image %s\n", datafile);
5095b1d7137Swdenk 	}
5105b1d7137Swdenk 
511ef1464ccSwdenk 	if ((dfd = open(datafile, O_RDONLY|O_BINARY)) < 0) {
5125b1d7137Swdenk 		fprintf (stderr, "%s: Can't open %s: %s\n",
513*89a4d6b1SPrafulla Wadaskar 			params.cmdname, datafile, strerror(errno));
5145b1d7137Swdenk 		exit (EXIT_FAILURE);
5155b1d7137Swdenk 	}
5165b1d7137Swdenk 
5175b1d7137Swdenk 	if (fstat(dfd, &sbuf) < 0) {
5185b1d7137Swdenk 		fprintf (stderr, "%s: Can't stat %s: %s\n",
519*89a4d6b1SPrafulla Wadaskar 			params.cmdname, datafile, strerror(errno));
5205b1d7137Swdenk 		exit (EXIT_FAILURE);
5215b1d7137Swdenk 	}
5225b1d7137Swdenk 
523fa956fdeSMike Frysinger 	ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, dfd, 0);
524fa956fdeSMike Frysinger 	if (ptr == MAP_FAILED) {
5255b1d7137Swdenk 		fprintf (stderr, "%s: Can't read %s: %s\n",
526*89a4d6b1SPrafulla Wadaskar 			params.cmdname, datafile, strerror(errno));
5275b1d7137Swdenk 		exit (EXIT_FAILURE);
5285b1d7137Swdenk 	}
5295b1d7137Swdenk 
530*89a4d6b1SPrafulla Wadaskar 	if (params.xflag) {
5315b1d7137Swdenk 		unsigned char *p = NULL;
5325b1d7137Swdenk 		/*
5335b1d7137Swdenk 		 * XIP: do not append the image_header_t at the
5345b1d7137Swdenk 		 * beginning of the file, but consume the space
5355b1d7137Swdenk 		 * reserved for it.
5365b1d7137Swdenk 		 */
5375b1d7137Swdenk 
538*89a4d6b1SPrafulla Wadaskar 		if ((unsigned)sbuf.st_size < tparams->header_size) {
5395b1d7137Swdenk 			fprintf (stderr,
5405b1d7137Swdenk 				"%s: Bad size: \"%s\" is too small for XIP\n",
541*89a4d6b1SPrafulla Wadaskar 				params.cmdname, datafile);
5425b1d7137Swdenk 			exit (EXIT_FAILURE);
5435b1d7137Swdenk 		}
5445b1d7137Swdenk 
545*89a4d6b1SPrafulla Wadaskar 		for (p = ptr; p < ptr + tparams->header_size; p++) {
5465b1d7137Swdenk 			if ( *p != 0xff ) {
5475b1d7137Swdenk 				fprintf (stderr,
5485b1d7137Swdenk 					"%s: Bad file: \"%s\" has invalid buffer for XIP\n",
549*89a4d6b1SPrafulla Wadaskar 					params.cmdname, datafile);
5505b1d7137Swdenk 				exit (EXIT_FAILURE);
5515b1d7137Swdenk 			}
5525b1d7137Swdenk 		}
5535b1d7137Swdenk 
554*89a4d6b1SPrafulla Wadaskar 		offset = tparams->header_size;
5555b1d7137Swdenk 	}
5565b1d7137Swdenk 
5575b1d7137Swdenk 	size = sbuf.st_size - offset;
5585b1d7137Swdenk 	if (write(ifd, ptr + offset, size) != size) {
5595b1d7137Swdenk 		fprintf (stderr, "%s: Write error on %s: %s\n",
560*89a4d6b1SPrafulla Wadaskar 			params.cmdname, params.imagefile, strerror(errno));
5615b1d7137Swdenk 		exit (EXIT_FAILURE);
5625b1d7137Swdenk 	}
5635b1d7137Swdenk 
5645b1d7137Swdenk 	if (pad && ((tail = size % 4) != 0)) {
5655b1d7137Swdenk 
5665b1d7137Swdenk 		if (write(ifd, (char *)&zero, 4-tail) != 4-tail) {
5675b1d7137Swdenk 			fprintf (stderr, "%s: Write error on %s: %s\n",
568*89a4d6b1SPrafulla Wadaskar 				params.cmdname, params.imagefile,
569*89a4d6b1SPrafulla Wadaskar 				strerror(errno));
5705b1d7137Swdenk 			exit (EXIT_FAILURE);
5715b1d7137Swdenk 		}
5725b1d7137Swdenk 	}
5735b1d7137Swdenk 
5745b1d7137Swdenk 	(void) munmap((void *)ptr, sbuf.st_size);
5755b1d7137Swdenk 	(void) close (dfd);
5765b1d7137Swdenk }
5775b1d7137Swdenk 
5785b1d7137Swdenk void
5795b1d7137Swdenk usage ()
5805b1d7137Swdenk {
5815b1d7137Swdenk 	fprintf (stderr, "Usage: %s -l image\n"
5829d25438fSBartlomiej Sieka 			 "          -l ==> list image header information\n",
583*89a4d6b1SPrafulla Wadaskar 		params.cmdname);
5849d25438fSBartlomiej Sieka 	fprintf (stderr, "       %s [-x] -A arch -O os -T type -C comp "
5859d25438fSBartlomiej Sieka 			 "-a addr -e ep -n name -d data_file[:data_file...] image\n"
5869d25438fSBartlomiej Sieka 			 "          -A ==> set architecture to 'arch'\n"
5875b1d7137Swdenk 			 "          -O ==> set operating system to 'os'\n"
5885b1d7137Swdenk 			 "          -T ==> set image type to 'type'\n"
5895b1d7137Swdenk 			 "          -C ==> set compression type 'comp'\n"
5905b1d7137Swdenk 			 "          -a ==> set load address to 'addr' (hex)\n"
5915b1d7137Swdenk 			 "          -e ==> set entry point to 'ep' (hex)\n"
5925b1d7137Swdenk 			 "          -n ==> set image name to 'name'\n"
5935b1d7137Swdenk 			 "          -d ==> use image data from 'datafile'\n"
5949d25438fSBartlomiej Sieka 			 "          -x ==> set XIP (execute in place)\n",
595*89a4d6b1SPrafulla Wadaskar 		params.cmdname);
5969d25438fSBartlomiej Sieka 	fprintf (stderr, "       %s [-D dtc_options] -f fit-image.its fit-image\n",
597*89a4d6b1SPrafulla Wadaskar 		params.cmdname);
5989d25438fSBartlomiej Sieka 
5995b1d7137Swdenk 	exit (EXIT_FAILURE);
6005b1d7137Swdenk }
601