xref: /OK3568_Linux_fs/u-boot/tools/imagetool.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2013
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Written by Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #ifndef _IMAGETOOL_H_
10*4882a593Smuzhiyun #define _IMAGETOOL_H_
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include "os_support.h"
13*4882a593Smuzhiyun #include <errno.h>
14*4882a593Smuzhiyun #include <fcntl.h>
15*4882a593Smuzhiyun #include <stdbool.h>
16*4882a593Smuzhiyun #include <stdio.h>
17*4882a593Smuzhiyun #include <stdlib.h>
18*4882a593Smuzhiyun #include <string.h>
19*4882a593Smuzhiyun #include <sys/stat.h>
20*4882a593Smuzhiyun #include <sys/types.h>
21*4882a593Smuzhiyun #include <time.h>
22*4882a593Smuzhiyun #include <unistd.h>
23*4882a593Smuzhiyun #include <u-boot/sha1.h>
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #include "fdt_host.h"
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #define ARRAY_SIZE(x)		(sizeof(x) / sizeof((x)[0]))
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #define IH_ARCH_DEFAULT		IH_ARCH_INVALID
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun /* Information about a file that needs to be placed into the FIT */
32*4882a593Smuzhiyun struct content_info {
33*4882a593Smuzhiyun 	struct content_info *next;
34*4882a593Smuzhiyun 	int type;		/* File type (IH_TYPE_...) */
35*4882a593Smuzhiyun 	const char *fname;
36*4882a593Smuzhiyun };
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun /*
39*4882a593Smuzhiyun  * This structure defines all such variables those are initialized by
40*4882a593Smuzhiyun  * mkimage and dumpimage main core and need to be referred by image
41*4882a593Smuzhiyun  * type specific functions
42*4882a593Smuzhiyun  */
43*4882a593Smuzhiyun struct image_tool_params {
44*4882a593Smuzhiyun 	int dflag;
45*4882a593Smuzhiyun 	int eflag;
46*4882a593Smuzhiyun 	int fflag;
47*4882a593Smuzhiyun 	int iflag;
48*4882a593Smuzhiyun 	int lflag;
49*4882a593Smuzhiyun 	int pflag;
50*4882a593Smuzhiyun 	int vflag;
51*4882a593Smuzhiyun 	int xflag;
52*4882a593Smuzhiyun 	int skipcpy;
53*4882a593Smuzhiyun 	int os;
54*4882a593Smuzhiyun 	int arch;
55*4882a593Smuzhiyun 	int type;
56*4882a593Smuzhiyun 	int comp;
57*4882a593Smuzhiyun 	char *dtc;
58*4882a593Smuzhiyun 	unsigned int addr;
59*4882a593Smuzhiyun 	unsigned int ep;
60*4882a593Smuzhiyun 	char *imagename;
61*4882a593Smuzhiyun 	char *imagename2;
62*4882a593Smuzhiyun 	char *datafile;
63*4882a593Smuzhiyun 	char *imagefile;
64*4882a593Smuzhiyun 	char *cmdname;
65*4882a593Smuzhiyun 	const char *outfile;	/* Output filename */
66*4882a593Smuzhiyun 	const char *keydir;	/* Directory holding private keys */
67*4882a593Smuzhiyun 	const char *keydest;	/* Destination .dtb for public key */
68*4882a593Smuzhiyun 	const char *comment;	/* Comment to add to signature node */
69*4882a593Smuzhiyun 	int require_keys;	/* 1 to mark signing keys as 'required' */
70*4882a593Smuzhiyun 	int file_size;		/* Total size of output file */
71*4882a593Smuzhiyun 	int orig_file_size;	/* Original size for file before padding */
72*4882a593Smuzhiyun 	bool auto_its;		/* Automatically create the .its file */
73*4882a593Smuzhiyun 	int fit_image_type;	/* Image type to put into the FIT */
74*4882a593Smuzhiyun 	char *fit_ramdisk;	/* Ramdisk file to include */
75*4882a593Smuzhiyun 	struct content_info *content_head;	/* List of files to include */
76*4882a593Smuzhiyun 	struct content_info *content_tail;
77*4882a593Smuzhiyun 	bool external_data;	/* Store data outside the FIT */
78*4882a593Smuzhiyun 	bool quiet;		/* Don't output text in normal operation */
79*4882a593Smuzhiyun 	unsigned int external_offset;	/* Add padding to external data */
80*4882a593Smuzhiyun 	const char *engine_id;	/* Engine to use for signing */
81*4882a593Smuzhiyun 	char *extraparams;	/* Extra parameters for img creation (-X) */
82*4882a593Smuzhiyun };
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun /*
85*4882a593Smuzhiyun  * image type specific variables and callback functions
86*4882a593Smuzhiyun  */
87*4882a593Smuzhiyun struct image_type_params {
88*4882a593Smuzhiyun 	/* name is an identification tag string for added support */
89*4882a593Smuzhiyun 	char *name;
90*4882a593Smuzhiyun 	/*
91*4882a593Smuzhiyun 	 * header size is local to the specific image type to be supported,
92*4882a593Smuzhiyun 	 * mkimage core treats this as number of bytes
93*4882a593Smuzhiyun 	 */
94*4882a593Smuzhiyun 	uint32_t header_size;
95*4882a593Smuzhiyun 	/* Image type header pointer */
96*4882a593Smuzhiyun 	void *hdr;
97*4882a593Smuzhiyun 	/*
98*4882a593Smuzhiyun 	 * There are several arguments that are passed on the command line
99*4882a593Smuzhiyun 	 * and are registered as flags in image_tool_params structure.
100*4882a593Smuzhiyun 	 * This callback function can be used to check the passed arguments
101*4882a593Smuzhiyun 	 * are in-lined with the image type to be supported
102*4882a593Smuzhiyun 	 *
103*4882a593Smuzhiyun 	 * Returns 1 if parameter check is successful
104*4882a593Smuzhiyun 	 */
105*4882a593Smuzhiyun 	int (*check_params) (struct image_tool_params *);
106*4882a593Smuzhiyun 	/*
107*4882a593Smuzhiyun 	 * This function is used by list command (i.e. mkimage -l <filename>)
108*4882a593Smuzhiyun 	 * image type verification code must be put here
109*4882a593Smuzhiyun 	 *
110*4882a593Smuzhiyun 	 * Returns 0 if image header verification is successful
111*4882a593Smuzhiyun 	 * otherwise, returns respective negative error codes
112*4882a593Smuzhiyun 	 */
113*4882a593Smuzhiyun 	int (*verify_header) (unsigned char *, int, struct image_tool_params *);
114*4882a593Smuzhiyun 	/* Prints image information abstracting from image header */
115*4882a593Smuzhiyun 	void (*print_header) (const void *);
116*4882a593Smuzhiyun 	/*
117*4882a593Smuzhiyun 	 * The header or image contents need to be set as per image type to
118*4882a593Smuzhiyun 	 * be generated using this callback function.
119*4882a593Smuzhiyun 	 * further output file post processing (for ex. checksum calculation,
120*4882a593Smuzhiyun 	 * padding bytes etc..) can also be done in this callback function.
121*4882a593Smuzhiyun 	 */
122*4882a593Smuzhiyun 	void (*set_header) (void *, struct stat *, int,
123*4882a593Smuzhiyun 					struct image_tool_params *);
124*4882a593Smuzhiyun 	/*
125*4882a593Smuzhiyun 	 * This function is used by the command to retrieve a component
126*4882a593Smuzhiyun 	 * (sub-image) from the image (i.e. dumpimage -i <image> -p <position>
127*4882a593Smuzhiyun 	 * <sub-image-name>).
128*4882a593Smuzhiyun 	 * Thus the code to extract a file from an image must be put here.
129*4882a593Smuzhiyun 	 *
130*4882a593Smuzhiyun 	 * Returns 0 if the file was successfully retrieved from the image,
131*4882a593Smuzhiyun 	 * or a negative value on error.
132*4882a593Smuzhiyun 	 */
133*4882a593Smuzhiyun 	int (*extract_subimage)(void *, struct image_tool_params *);
134*4882a593Smuzhiyun 	/*
135*4882a593Smuzhiyun 	 * Some image generation support for ex (default image type) supports
136*4882a593Smuzhiyun 	 * more than one type_ids, this callback function is used to check
137*4882a593Smuzhiyun 	 * whether input (-T <image_type>) is supported by registered image
138*4882a593Smuzhiyun 	 * generation/list low level code
139*4882a593Smuzhiyun 	 */
140*4882a593Smuzhiyun 	int (*check_image_type) (uint8_t);
141*4882a593Smuzhiyun 	/* This callback function will be executed if fflag is defined */
142*4882a593Smuzhiyun 	int (*fflag_handle) (struct image_tool_params *);
143*4882a593Smuzhiyun 	/*
144*4882a593Smuzhiyun 	 * This callback function will be executed for variable size record
145*4882a593Smuzhiyun 	 * It is expected to build this header in memory and return its length
146*4882a593Smuzhiyun 	 * and a pointer to it by using image_type_params.header_size and
147*4882a593Smuzhiyun 	 * image_type_params.hdr. The return value shall indicate if an
148*4882a593Smuzhiyun 	 * additional padding should be used when copying the data image
149*4882a593Smuzhiyun 	 * by returning the padding length.
150*4882a593Smuzhiyun 	 */
151*4882a593Smuzhiyun 	int (*vrec_header) (struct image_tool_params *,
152*4882a593Smuzhiyun 		struct image_type_params *);
153*4882a593Smuzhiyun };
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun /**
156*4882a593Smuzhiyun  * imagetool_get_type() - find the image type params for a given image type
157*4882a593Smuzhiyun  *
158*4882a593Smuzhiyun  * It scans all registers image type supports
159*4882a593Smuzhiyun  * checks the input type for each supported image type
160*4882a593Smuzhiyun  *
161*4882a593Smuzhiyun  * if successful,
162*4882a593Smuzhiyun  *     returns respective image_type_params pointer if success
163*4882a593Smuzhiyun  * if input type_id is not supported by any of image_type_support
164*4882a593Smuzhiyun  *     returns NULL
165*4882a593Smuzhiyun  */
166*4882a593Smuzhiyun struct image_type_params *imagetool_get_type(int type);
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun /*
169*4882a593Smuzhiyun  * imagetool_verify_print_header() - verifies the image header
170*4882a593Smuzhiyun  *
171*4882a593Smuzhiyun  * Scan registered image types and verify the image_header for each
172*4882a593Smuzhiyun  * supported image type. If verification is successful, this prints
173*4882a593Smuzhiyun  * the respective header.
174*4882a593Smuzhiyun  *
175*4882a593Smuzhiyun  * @return 0 on success, negative if input image format does not match with
176*4882a593Smuzhiyun  * any of supported image types
177*4882a593Smuzhiyun  */
178*4882a593Smuzhiyun int imagetool_verify_print_header(
179*4882a593Smuzhiyun 	void *ptr,
180*4882a593Smuzhiyun 	struct stat *sbuf,
181*4882a593Smuzhiyun 	struct image_type_params *tparams,
182*4882a593Smuzhiyun 	struct image_tool_params *params);
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun /**
185*4882a593Smuzhiyun  * imagetool_save_subimage - store data into a file
186*4882a593Smuzhiyun  * @file_name: name of the destination file
187*4882a593Smuzhiyun  * @file_data: data to be written
188*4882a593Smuzhiyun  * @file_len: the amount of data to store
189*4882a593Smuzhiyun  *
190*4882a593Smuzhiyun  * imagetool_save_subimage() store file_len bytes of data pointed by file_data
191*4882a593Smuzhiyun  * into the file name by file_name.
192*4882a593Smuzhiyun  *
193*4882a593Smuzhiyun  * returns:
194*4882a593Smuzhiyun  *     zero in case of success or a negative value if fail.
195*4882a593Smuzhiyun  */
196*4882a593Smuzhiyun int imagetool_save_subimage(
197*4882a593Smuzhiyun 	const char *file_name,
198*4882a593Smuzhiyun 	ulong file_data,
199*4882a593Smuzhiyun 	ulong file_len);
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun /**
202*4882a593Smuzhiyun  * imagetool_get_filesize() - Utility function to obtain the size of a file
203*4882a593Smuzhiyun  *
204*4882a593Smuzhiyun  * This function prints a message if an error occurs, showing the error that
205*4882a593Smuzhiyun  * was obtained.
206*4882a593Smuzhiyun  *
207*4882a593Smuzhiyun  * @params:	mkimage parameters
208*4882a593Smuzhiyun  * @fname:	filename to check
209*4882a593Smuzhiyun  * @return size of file, or -ve value on error
210*4882a593Smuzhiyun  */
211*4882a593Smuzhiyun int imagetool_get_filesize(struct image_tool_params *params, const char *fname);
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun /**
214*4882a593Smuzhiyun  * imagetool_get_source_date() - Get timestamp for build output.
215*4882a593Smuzhiyun  *
216*4882a593Smuzhiyun  * Gets a timestamp for embedding it in a build output. If set
217*4882a593Smuzhiyun  * SOURCE_DATE_EPOCH is used. Else the given fallback value is returned. Prints
218*4882a593Smuzhiyun  * an error message if SOURCE_DATE_EPOCH contains an invalid value and returns
219*4882a593Smuzhiyun  * 0.
220*4882a593Smuzhiyun  *
221*4882a593Smuzhiyun  * @params:	mkimage parameters
222*4882a593Smuzhiyun  * @fallback:	timestamp to use if SOURCE_DATE_EPOCH isn't set
223*4882a593Smuzhiyun  * @return timestamp based on SOURCE_DATE_EPOCH
224*4882a593Smuzhiyun  */
225*4882a593Smuzhiyun time_t imagetool_get_source_date(
226*4882a593Smuzhiyun 	struct image_tool_params *params,
227*4882a593Smuzhiyun 	time_t fallback);
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun /*
230*4882a593Smuzhiyun  * There is a c file associated with supported image type low level code
231*4882a593Smuzhiyun  * for ex. default_image.c, fit_image.c
232*4882a593Smuzhiyun  */
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun void pbl_load_uboot(int fd, struct image_tool_params *mparams);
236*4882a593Smuzhiyun int rockchip_copy_image(int fd, struct image_tool_params *mparams);
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun #define ___cat(a, b) a ## b
239*4882a593Smuzhiyun #define __cat(a, b) ___cat(a, b)
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun /* we need some special handling for this host tool running eventually on
242*4882a593Smuzhiyun  * Darwin. The Mach-O section handling is a bit different than ELF section
243*4882a593Smuzhiyun  * handling. The differnces in detail are:
244*4882a593Smuzhiyun  *  a) we have segments which have sections
245*4882a593Smuzhiyun  *  b) we need a API call to get the respective section symbols */
246*4882a593Smuzhiyun #if defined(__MACH__)
247*4882a593Smuzhiyun #include <mach-o/getsect.h>
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun #define INIT_SECTION(name)  do {					\
250*4882a593Smuzhiyun 		unsigned long name ## _len;				\
251*4882a593Smuzhiyun 		char *__cat(pstart_, name) = getsectdata("__TEXT",	\
252*4882a593Smuzhiyun 			#name, &__cat(name, _len));			\
253*4882a593Smuzhiyun 		char *__cat(pstop_, name) = __cat(pstart_, name) +	\
254*4882a593Smuzhiyun 			__cat(name, _len);				\
255*4882a593Smuzhiyun 		__cat(__start_, name) = (void *)__cat(pstart_, name);	\
256*4882a593Smuzhiyun 		__cat(__stop_, name) = (void *)__cat(pstop_, name);	\
257*4882a593Smuzhiyun 	} while (0)
258*4882a593Smuzhiyun #define SECTION(name)   __attribute__((section("__TEXT, " #name)))
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun struct image_type_params **__start_image_type, **__stop_image_type;
261*4882a593Smuzhiyun #else
262*4882a593Smuzhiyun #define INIT_SECTION(name) /* no-op for ELF */
263*4882a593Smuzhiyun #define SECTION(name)   __attribute__((section(#name)))
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun /* We construct a table of pointers in an ELF section (pointers generally
266*4882a593Smuzhiyun  * go unpadded by gcc).  ld creates boundary syms for us. */
267*4882a593Smuzhiyun extern struct image_type_params *__start_image_type[], *__stop_image_type[];
268*4882a593Smuzhiyun #endif /* __MACH__ */
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun #if !defined(__used)
271*4882a593Smuzhiyun # if __GNUC__ == 3 && __GNUC_MINOR__ < 3
272*4882a593Smuzhiyun #  define __used			__attribute__((__unused__))
273*4882a593Smuzhiyun # else
274*4882a593Smuzhiyun #  define __used			__attribute__((__used__))
275*4882a593Smuzhiyun # endif
276*4882a593Smuzhiyun #endif
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun #define U_BOOT_IMAGE_TYPE( \
279*4882a593Smuzhiyun 		_id, \
280*4882a593Smuzhiyun 		_name, \
281*4882a593Smuzhiyun 		_header_size, \
282*4882a593Smuzhiyun 		_header, \
283*4882a593Smuzhiyun 		_check_params, \
284*4882a593Smuzhiyun 		_verify_header, \
285*4882a593Smuzhiyun 		_print_header, \
286*4882a593Smuzhiyun 		_set_header, \
287*4882a593Smuzhiyun 		_extract_subimage, \
288*4882a593Smuzhiyun 		_check_image_type, \
289*4882a593Smuzhiyun 		_fflag_handle, \
290*4882a593Smuzhiyun 		_vrec_header \
291*4882a593Smuzhiyun 	) \
292*4882a593Smuzhiyun 	static struct image_type_params __cat(image_type_, _id) = \
293*4882a593Smuzhiyun 	{ \
294*4882a593Smuzhiyun 		.name = _name, \
295*4882a593Smuzhiyun 		.header_size = _header_size, \
296*4882a593Smuzhiyun 		.hdr = _header, \
297*4882a593Smuzhiyun 		.check_params = _check_params, \
298*4882a593Smuzhiyun 		.verify_header = _verify_header, \
299*4882a593Smuzhiyun 		.print_header = _print_header, \
300*4882a593Smuzhiyun 		.set_header = _set_header, \
301*4882a593Smuzhiyun 		.extract_subimage = _extract_subimage, \
302*4882a593Smuzhiyun 		.check_image_type = _check_image_type, \
303*4882a593Smuzhiyun 		.fflag_handle = _fflag_handle, \
304*4882a593Smuzhiyun 		.vrec_header = _vrec_header \
305*4882a593Smuzhiyun 	}; \
306*4882a593Smuzhiyun 	static struct image_type_params *SECTION(image_type) __used \
307*4882a593Smuzhiyun 		__cat(image_type_ptr_, _id) = &__cat(image_type_, _id)
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun #endif /* _IMAGETOOL_H_ */
310