xref: /openbmc/u-boot/tools/imagetool.c (revision e8e3f2d2d48f97b2c79b698eccedce8f4f880993)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2f86ed6a8SGuilherme Maciel Ferreira /*
3f86ed6a8SGuilherme Maciel Ferreira  * (C) Copyright 2013
4f86ed6a8SGuilherme Maciel Ferreira  *
5f86ed6a8SGuilherme Maciel Ferreira  * Written by Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
6f86ed6a8SGuilherme Maciel Ferreira  */
7f86ed6a8SGuilherme Maciel Ferreira 
8f86ed6a8SGuilherme Maciel Ferreira #include "imagetool.h"
9f86ed6a8SGuilherme Maciel Ferreira 
100ca6691cSGuilherme Maciel Ferreira #include <image.h>
110ca6691cSGuilherme Maciel Ferreira 
imagetool_get_type(int type)12a93648d1SGuilherme Maciel Ferreira struct image_type_params *imagetool_get_type(int type)
130ca6691cSGuilherme Maciel Ferreira {
141fddd7b6SAndreas Bießmann 	struct image_type_params **curr;
151fddd7b6SAndreas Bießmann 	INIT_SECTION(image_type);
161fddd7b6SAndreas Bießmann 
171fddd7b6SAndreas Bießmann 	struct image_type_params **start = __start_image_type;
181fddd7b6SAndreas Bießmann 	struct image_type_params **end = __stop_image_type;
190ca6691cSGuilherme Maciel Ferreira 
20a93648d1SGuilherme Maciel Ferreira 	for (curr = start; curr != end; curr++) {
211fddd7b6SAndreas Bießmann 		if ((*curr)->check_image_type) {
221fddd7b6SAndreas Bießmann 			if (!(*curr)->check_image_type(type))
231fddd7b6SAndreas Bießmann 				return *curr;
240ca6691cSGuilherme Maciel Ferreira 		}
250ca6691cSGuilherme Maciel Ferreira 	}
260ca6691cSGuilherme Maciel Ferreira 	return NULL;
270ca6691cSGuilherme Maciel Ferreira }
280ca6691cSGuilherme Maciel Ferreira 
imagetool_verify_print_header(void * ptr,struct stat * sbuf,struct image_type_params * tparams,struct image_tool_params * params)290ca6691cSGuilherme Maciel Ferreira int imagetool_verify_print_header(
300ca6691cSGuilherme Maciel Ferreira 	void *ptr,
310ca6691cSGuilherme Maciel Ferreira 	struct stat *sbuf,
320ca6691cSGuilherme Maciel Ferreira 	struct image_type_params *tparams,
330ca6691cSGuilherme Maciel Ferreira 	struct image_tool_params *params)
340ca6691cSGuilherme Maciel Ferreira {
350ca6691cSGuilherme Maciel Ferreira 	int retval = -1;
361fddd7b6SAndreas Bießmann 	struct image_type_params **curr;
371fddd7b6SAndreas Bießmann 	INIT_SECTION(image_type);
380ca6691cSGuilherme Maciel Ferreira 
391fddd7b6SAndreas Bießmann 	struct image_type_params **start = __start_image_type;
401fddd7b6SAndreas Bießmann 	struct image_type_params **end = __stop_image_type;
41a93648d1SGuilherme Maciel Ferreira 
42a93648d1SGuilherme Maciel Ferreira 	for (curr = start; curr != end; curr++) {
431fddd7b6SAndreas Bießmann 		if ((*curr)->verify_header) {
441fddd7b6SAndreas Bießmann 			retval = (*curr)->verify_header((unsigned char *)ptr,
450ca6691cSGuilherme Maciel Ferreira 						     sbuf->st_size, params);
460ca6691cSGuilherme Maciel Ferreira 
470ca6691cSGuilherme Maciel Ferreira 			if (retval == 0) {
480ca6691cSGuilherme Maciel Ferreira 				/*
490ca6691cSGuilherme Maciel Ferreira 				 * Print the image information if verify is
500ca6691cSGuilherme Maciel Ferreira 				 * successful
510ca6691cSGuilherme Maciel Ferreira 				 */
521fddd7b6SAndreas Bießmann 				if ((*curr)->print_header) {
53bd6e1420SSimon Glass 					if (!params->quiet)
541fddd7b6SAndreas Bießmann 						(*curr)->print_header(ptr);
550ca6691cSGuilherme Maciel Ferreira 				} else {
560ca6691cSGuilherme Maciel Ferreira 					fprintf(stderr,
570ca6691cSGuilherme Maciel Ferreira 						"%s: print_header undefined for %s\n",
581fddd7b6SAndreas Bießmann 						params->cmdname, (*curr)->name);
590ca6691cSGuilherme Maciel Ferreira 				}
600ca6691cSGuilherme Maciel Ferreira 				break;
610ca6691cSGuilherme Maciel Ferreira 			}
620ca6691cSGuilherme Maciel Ferreira 		}
63*d32aa3caSJordan Hand 	}
64*d32aa3caSJordan Hand 
65*d32aa3caSJordan Hand 	return retval;
66*d32aa3caSJordan Hand }
67*d32aa3caSJordan Hand 
imagetool_verify_print_header_by_type(void * ptr,struct stat * sbuf,struct image_type_params * tparams,struct image_tool_params * params)68*d32aa3caSJordan Hand int imagetool_verify_print_header_by_type(
69*d32aa3caSJordan Hand 	void *ptr,
70*d32aa3caSJordan Hand 	struct stat *sbuf,
71*d32aa3caSJordan Hand 	struct image_type_params *tparams,
72*d32aa3caSJordan Hand 	struct image_tool_params *params)
73*d32aa3caSJordan Hand {
74*d32aa3caSJordan Hand 	int retval;
75*d32aa3caSJordan Hand 
76*d32aa3caSJordan Hand 	retval = tparams->verify_header((unsigned char *)ptr, sbuf->st_size,
77*d32aa3caSJordan Hand 			params);
78*d32aa3caSJordan Hand 
79*d32aa3caSJordan Hand 	if (retval == 0) {
80*d32aa3caSJordan Hand 		/*
81*d32aa3caSJordan Hand 		 * Print the image information if verify is successful
82*d32aa3caSJordan Hand 		 */
83*d32aa3caSJordan Hand 		if (tparams->print_header) {
84*d32aa3caSJordan Hand 			if (!params->quiet)
85*d32aa3caSJordan Hand 				tparams->print_header(ptr);
86*d32aa3caSJordan Hand 		} else {
87*d32aa3caSJordan Hand 			fprintf(stderr,
88*d32aa3caSJordan Hand 				"%s: print_header undefined for %s\n",
89*d32aa3caSJordan Hand 				params->cmdname, tparams->name);
90*d32aa3caSJordan Hand 		}
91*d32aa3caSJordan Hand 	} else {
92*d32aa3caSJordan Hand 		fprintf(stderr,
93*d32aa3caSJordan Hand 			"%s: verify_header failed for %s with exit code %d\n",
94*d32aa3caSJordan Hand 			params->cmdname, tparams->name, retval);
950ca6691cSGuilherme Maciel Ferreira 	}
960ca6691cSGuilherme Maciel Ferreira 
970ca6691cSGuilherme Maciel Ferreira 	return retval;
980ca6691cSGuilherme Maciel Ferreira }
99067d1560SGuilherme Maciel Ferreira 
imagetool_save_subimage(const char * file_name,ulong file_data,ulong file_len)10067f946cdSGuilherme Maciel Ferreira int imagetool_save_subimage(
101067d1560SGuilherme Maciel Ferreira 	const char *file_name,
102067d1560SGuilherme Maciel Ferreira 	ulong file_data,
103067d1560SGuilherme Maciel Ferreira 	ulong file_len)
104067d1560SGuilherme Maciel Ferreira {
105067d1560SGuilherme Maciel Ferreira 	int dfd;
106067d1560SGuilherme Maciel Ferreira 
107067d1560SGuilherme Maciel Ferreira 	dfd = open(file_name, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
108067d1560SGuilherme Maciel Ferreira 		   S_IRUSR | S_IWUSR);
109067d1560SGuilherme Maciel Ferreira 	if (dfd < 0) {
110067d1560SGuilherme Maciel Ferreira 		fprintf(stderr, "Can't open \"%s\": %s\n",
111067d1560SGuilherme Maciel Ferreira 			file_name, strerror(errno));
112067d1560SGuilherme Maciel Ferreira 		return -1;
113067d1560SGuilherme Maciel Ferreira 	}
114067d1560SGuilherme Maciel Ferreira 
115067d1560SGuilherme Maciel Ferreira 	if (write(dfd, (void *)file_data, file_len) != (ssize_t)file_len) {
116067d1560SGuilherme Maciel Ferreira 		fprintf(stderr, "Write error on \"%s\": %s\n",
117067d1560SGuilherme Maciel Ferreira 			file_name, strerror(errno));
118067d1560SGuilherme Maciel Ferreira 		close(dfd);
119067d1560SGuilherme Maciel Ferreira 		return -1;
120067d1560SGuilherme Maciel Ferreira 	}
121067d1560SGuilherme Maciel Ferreira 
122067d1560SGuilherme Maciel Ferreira 	close(dfd);
123067d1560SGuilherme Maciel Ferreira 
124067d1560SGuilherme Maciel Ferreira 	return 0;
125067d1560SGuilherme Maciel Ferreira }
1263837ce65SSimon Glass 
imagetool_get_filesize(struct image_tool_params * params,const char * fname)1273837ce65SSimon Glass int imagetool_get_filesize(struct image_tool_params *params, const char *fname)
1283837ce65SSimon Glass {
1293837ce65SSimon Glass 	struct stat sbuf;
1303837ce65SSimon Glass 	int fd;
1313837ce65SSimon Glass 
1323837ce65SSimon Glass 	fd = open(fname, O_RDONLY | O_BINARY);
1333837ce65SSimon Glass 	if (fd < 0) {
1343837ce65SSimon Glass 		fprintf(stderr, "%s: Can't open %s: %s\n",
1353837ce65SSimon Glass 			params->cmdname, fname, strerror(errno));
1363837ce65SSimon Glass 		return -1;
1373837ce65SSimon Glass 	}
1383837ce65SSimon Glass 
1393837ce65SSimon Glass 	if (fstat(fd, &sbuf) < 0) {
1403837ce65SSimon Glass 		fprintf(stderr, "%s: Can't stat %s: %s\n",
1413837ce65SSimon Glass 			params->cmdname, fname, strerror(errno));
142b12a81c4SSimon Glass 		close(fd);
1433837ce65SSimon Glass 		return -1;
1443837ce65SSimon Glass 	}
1453837ce65SSimon Glass 	close(fd);
1463837ce65SSimon Glass 
1473837ce65SSimon Glass 	return sbuf.st_size;
1483837ce65SSimon Glass }
1495847084fSVagrant Cascadian 
imagetool_get_source_date(const char * cmdname,time_t fallback)1505847084fSVagrant Cascadian time_t imagetool_get_source_date(
15187925df2SAlex Kiernan 	 const char *cmdname,
1525847084fSVagrant Cascadian 	 time_t fallback)
1535847084fSVagrant Cascadian {
1545847084fSVagrant Cascadian 	char *source_date_epoch = getenv("SOURCE_DATE_EPOCH");
1555847084fSVagrant Cascadian 
1565847084fSVagrant Cascadian 	if (source_date_epoch == NULL)
1575847084fSVagrant Cascadian 		return fallback;
1585847084fSVagrant Cascadian 
1595847084fSVagrant Cascadian 	time_t time = (time_t) strtol(source_date_epoch, NULL, 10);
1605847084fSVagrant Cascadian 
1615847084fSVagrant Cascadian 	if (gmtime(&time) == NULL) {
1625847084fSVagrant Cascadian 		fprintf(stderr, "%s: SOURCE_DATE_EPOCH is not valid\n",
16387925df2SAlex Kiernan 			cmdname);
1645847084fSVagrant Cascadian 		time = 0;
1655847084fSVagrant Cascadian 	}
1665847084fSVagrant Cascadian 
1675847084fSVagrant Cascadian 	return time;
1685847084fSVagrant Cascadian }
169