Blame view

tools/dumpimage.c 4.78 KB
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
1
2
3
4
5
6
7
8
9
10
11
12
13
  /*
   * Based on mkimage.c.
   *
   * Written by Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
   *
   * SPDX-License-Identifier:	GPL-2.0+
   */
  
  #include "dumpimage.h"
  #include <image.h>
  #include <version.h>
  
  static void usage(void);
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
14
15
16
17
  /* parameters initialized by core will be used by the image type code */
  static struct image_tool_params params = {
  	.type = IH_TYPE_KERNEL,
  };
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
18
  /*
67f946cd1   Guilherme Maciel Ferreira   dumpimage: replac...
19
   * dumpimage_extract_subimage -
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
20
21
22
23
24
25
26
27
28
   *
   * It scans all registered image types,
   * verifies image_header for each supported image type
   * if verification is successful, it extracts the desired file,
   * indexed by pflag, from the image
   *
   * returns negative if input image format does not match with any of
   * supported image types
   */
67f946cd1   Guilherme Maciel Ferreira   dumpimage: replac...
29
  static int dumpimage_extract_subimage(struct image_type_params *tparams,
f41f5b7c0   Guilherme Maciel Ferreira   dumpimage: add 'T...
30
  		void *ptr, struct stat *sbuf)
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
31
32
  {
  	int retval = -1;
f41f5b7c0   Guilherme Maciel Ferreira   dumpimage: add 'T...
33
34
35
36
37
38
39
40
41
42
  
  	if (tparams->verify_header) {
  		retval = tparams->verify_header((unsigned char *)ptr,
  				sbuf->st_size, &params);
  		if (retval != 0)
  			return -1;
  		/*
  		 * Extract the file from the image
  		 * if verify is successful
  		 */
67f946cd1   Guilherme Maciel Ferreira   dumpimage: replac...
43
44
  		if (tparams->extract_subimage) {
  			retval = tparams->extract_subimage(ptr, &params);
f41f5b7c0   Guilherme Maciel Ferreira   dumpimage: add 'T...
45
46
  		} else {
  			fprintf(stderr,
67f946cd1   Guilherme Maciel Ferreira   dumpimage: replac...
47
48
  				"%s: extract_subimage undefined for %s
  ",
f41f5b7c0   Guilherme Maciel Ferreira   dumpimage: add 'T...
49
50
  				params.cmdname, tparams->name);
  			return -2;
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  		}
  	}
  
  	return retval;
  }
  
  int main(int argc, char **argv)
  {
  	int opt;
  	int ifd = -1;
  	struct stat sbuf;
  	char *ptr;
  	int retval = 0;
  	struct image_type_params *tparams = NULL;
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
65
  	params.cmdname = *argv;
f41f5b7c0   Guilherme Maciel Ferreira   dumpimage: add 'T...
66
  	while ((opt = getopt(argc, argv, "li:o:T:p:V")) != -1) {
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
67
68
69
70
71
72
73
74
75
76
77
  		switch (opt) {
  		case 'l':
  			params.lflag = 1;
  			break;
  		case 'i':
  			params.imagefile = optarg;
  			params.iflag = 1;
  			break;
  		case 'o':
  			params.outfile = optarg;
  			break;
f41f5b7c0   Guilherme Maciel Ferreira   dumpimage: add 'T...
78
79
80
81
82
83
  		case 'T':
  			params.type = genimg_get_type_id(optarg);
  			if (params.type < 0) {
  				usage();
  			}
  			break;
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  		case 'p':
  			params.pflag = strtoul(optarg, &ptr, 10);
  			if (*ptr) {
  				fprintf(stderr,
  					"%s: invalid file position %s
  ",
  					params.cmdname, *argv);
  				exit(EXIT_FAILURE);
  			}
  			break;
  		case 'V':
  			printf("dumpimage version %s
  ", PLAIN_VERSION);
  			exit(EXIT_SUCCESS);
  		default:
  			usage();
f41f5b7c0   Guilherme Maciel Ferreira   dumpimage: add 'T...
100
  			break;
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
101
102
103
104
105
106
107
  		}
  	}
  
  	if (optind >= argc)
  		usage();
  
  	/* set tparams as per input type_id */
a93648d19   Guilherme Maciel Ferreira   imagetool: replac...
108
  	tparams = imagetool_get_type(params.type);
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
109
  	if (tparams == NULL) {
f41f5b7c0   Guilherme Maciel Ferreira   dumpimage: add 'T...
110
111
  		fprintf(stderr, "%s: unsupported type: %s
  ",
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  			params.cmdname, genimg_get_type_name(params.type));
  		exit(EXIT_FAILURE);
  	}
  
  	/*
  	 * check the passed arguments parameters meets the requirements
  	 * as per image type to be generated/listed
  	 */
  	if (tparams->check_params) {
  		if (tparams->check_params(&params))
  			usage();
  	}
  
  	if (params.iflag)
  		params.datafile = argv[optind];
  	else
  		params.imagefile = argv[optind];
  	if (!params.outfile)
  		params.outfile = params.datafile;
  
  	ifd = open(params.imagefile, O_RDONLY|O_BINARY);
  	if (ifd < 0) {
  		fprintf(stderr, "%s: Can't open \"%s\": %s
  ",
  			params.cmdname, params.imagefile,
  			strerror(errno));
  		exit(EXIT_FAILURE);
  	}
  
  	if (params.lflag || params.iflag) {
  		if (fstat(ifd, &sbuf) < 0) {
  			fprintf(stderr, "%s: Can't stat \"%s\": %s
  ",
  				params.cmdname, params.imagefile,
  				strerror(errno));
  			exit(EXIT_FAILURE);
  		}
f41f5b7c0   Guilherme Maciel Ferreira   dumpimage: add 'T...
149
  		if ((uint32_t)sbuf.st_size < tparams->header_size) {
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
  			fprintf(stderr,
  				"%s: Bad size: \"%s\" is not valid image
  ",
  				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
  ",
  				params.cmdname, params.imagefile,
  				strerror(errno));
  			exit(EXIT_FAILURE);
  		}
  
  		/*
  		 * Both calls bellow scan through dumpimage registry for all
  		 * supported image types and verify the input image file
  		 * header for match
  		 */
  		if (params.iflag) {
  			/*
  			 * Extract the data files from within the matched
  			 * image type. Returns the error code if not matched
  			 */
67f946cd1   Guilherme Maciel Ferreira   dumpimage: replac...
176
  			retval = dumpimage_extract_subimage(tparams, ptr,
f41f5b7c0   Guilherme Maciel Ferreira   dumpimage: add 'T...
177
  					&sbuf);
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
178
179
180
181
182
  		} else {
  			/*
  			 * Print the image information for matched image type
  			 * Returns the error code if not matched
  			 */
0ca6691c2   Guilherme Maciel Ferreira   imagetool: move c...
183
184
  			retval = imagetool_verify_print_header(ptr, &sbuf,
  					tparams, &params);
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
  		}
  
  		(void)munmap((void *)ptr, sbuf.st_size);
  		(void)close(ifd);
  
  		return retval;
  	}
  
  	(void)close(ifd);
  
  	return EXIT_SUCCESS;
  }
  
  static void usage(void)
  {
  	fprintf(stderr, "Usage: %s -l image
  "
  		"          -l ==> list image header information
  ",
  		params.cmdname);
  	fprintf(stderr,
f41f5b7c0   Guilherme Maciel Ferreira   dumpimage: add 'T...
206
207
208
209
210
211
212
213
  		"       %s -i image -T type [-p position] [-o outfile] data_file
  "
  		"          -i ==> extract from the 'image' a specific 'data_file'
  "
  		"          -T ==> set image type to 'type'
  "
  		"          -p ==> 'position' (starting at 0) of the 'data_file' inside the 'image'
  ",
a804b5ce2   Guilherme Maciel Ferreira   Add dumpimage, a ...
214
215
216
217
218
219
220
221
  		params.cmdname);
  	fprintf(stderr,
  		"       %s -V ==> print version information and exit
  ",
  		params.cmdname);
  
  	exit(EXIT_FAILURE);
  }