blob: 5b8cceb04407c1f87e80f9e7961fcfd058c7a6d0 [file] [log] [blame]
Amaury Pouly303c4862011-11-06 19:44:03 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <getopt.h>
23#include <stdlib.h>
24#include <stdio.h>
Dominik Riebeling2d2fa5c2011-12-04 13:54:07 +000025#include <string.h>
Amaury Pouly303c4862011-11-06 19:44:03 +000026#include "mkimxboot.h"
27
Amaury Poulye09c1e32012-05-19 13:55:33 +020028struct imx_variant_t
29{
30 const char *name;
31 enum imx_firmware_variant_t variant;
32};
33
Thomas Jarosch2a3e1622015-01-11 21:40:51 +010034static struct imx_variant_t imx_variants[] =
Amaury Poulye09c1e32012-05-19 13:55:33 +020035{
36 { "default", VARIANT_DEFAULT },
37 { "zenxfi2-recovery", VARIANT_ZENXFI2_RECOVERY },
38 { "zenxfi2-nand", VARIANT_ZENXFI2_NAND },
39 { "zenxfi2-sd", VARIANT_ZENXFI2_SD },
Amaury Poulyf2dfc842013-01-26 18:37:12 +000040 { "zenxfistyle-recovery", VARIANT_ZENXFISTYLE_RECOVERY },
Amaury Pouly55babd52013-06-18 15:02:01 +020041 { "zenstyle-recovery", VARIANT_ZENSTYLE_RECOVERY },
Amaury Poulye09c1e32012-05-19 13:55:33 +020042};
43
44#define NR_VARIANTS sizeof(imx_variants) / sizeof(imx_variants[0])
45
Amaury Pouly782d9c02014-05-29 21:45:51 +020046struct model_t
47{
48 const char *name;
49 enum imx_model_t model;
50};
51
52struct model_t imx_models[] =
53{
54 { "unknown", MODEL_UNKNOWN },
55 { "fuzeplus", MODEL_FUZEPLUS },
56 { "zenxfi2", MODEL_ZENXFI2 },
57 { "zenxfi3", MODEL_ZENXFI3 },
58 { "zenxfistyle", MODEL_ZENXFISTYLE },
59 { "zenstyle", MODEL_ZENSTYLE },
60 { "nwze370", MODEL_NWZE370 },
61 { "nwze360", MODEL_NWZE360 },
62};
63
64#define NR_MODELS sizeof(imx_models) / sizeof(imx_models[0])
65
Amaury Pouly303c4862011-11-06 19:44:03 +000066static void usage(void)
67{
Amaury Pouly44c32f82013-03-10 15:10:38 +010068 printf("Usage: mkimxboot [options | file]...\n");
Amaury Pouly303c4862011-11-06 19:44:03 +000069 printf("Options:\n");
Amaury Pouly6483e232013-06-15 22:11:04 +020070 printf(" -?/--help Display this message\n");
71 printf(" -o <file> Set output file\n");
72 printf(" -i <file> Set input file\n");
73 printf(" -b <file> Set boot file\n");
74 printf(" -d/--debug Enable debug output\n");
Amaury Poulyff946f12017-01-01 21:31:47 +010075 printf(" -t <type> Set type (dualboot, singleboot, recovery, origfw, charge)\n");
Amaury Pouly6483e232013-06-15 22:11:04 +020076 printf(" -v <v> Set variant\n");
77 printf(" -x Dump device informations\n");
Amaury Pouly6483e232013-06-15 22:11:04 +020078 printf(" -p <ver> Force product and component version\n");
Amaury Pouly782d9c02014-05-29 21:45:51 +020079 printf(" -5 <type> Compute <type> MD5 sum of the input file\n");
80 printf(" -m <model> Specify model (useful for soft MD5 sum)\n");
Amaury Poulye09c1e32012-05-19 13:55:33 +020081 printf("Supported variants: (default is standard)\n");
82 printf(" ");
83 for(size_t i = 0; i < NR_VARIANTS; i++)
84 {
85 if(i != 0)
86 printf(", ");
87 printf("%s", imx_variants[i].name);
88 }
89 printf("\n");
Amaury Pouly782d9c02014-05-29 21:45:51 +020090 printf("Supported models: (default is unknown)\n");
91 for(size_t i = 0; i < NR_MODELS; i++)
92 {
93 if(i != 0)
94 printf(", ");
95 printf("%s", imx_models[i].name);
96 }
97 printf("\n");
Amaury Pouly303c4862011-11-06 19:44:03 +000098 printf("By default a dualboot image is built\n");
Amaury Poulyd5610172013-06-16 01:33:16 +020099 printf("This tools supports the following format for the boot file:\n");
100 printf("- rockbox scramble format\n");
101 printf("- elf format\n");
102 printf("Additional checks will be performed on rockbox scramble format to\n");
103 printf("ensure soundness of operation.\n");
Amaury Pouly782d9c02014-05-29 21:45:51 +0200104 printf("There are two types of MD5 sums: 'full' or 'soft'.\n");
105 printf("- full MD5 sum applies to the whole file\n");
106 printf("- soft MD5 sum for SB files accounts for relevant parts only\n");
Amaury Pouly303c4862011-11-06 19:44:03 +0000107 exit(1);
108}
109
Amaury Poulyff946f12017-01-01 21:31:47 +0100110static int print_md5(const char *file, const char *type)
Amaury Pouly782d9c02014-05-29 21:45:51 +0200111{
112 uint8_t md5sum[16];
113 enum imx_error_t err;
114 if(strcmp(type, "full") == 0)
115 err = compute_md5sum(file, md5sum);
116 else if(strcmp(type, "soft") == 0)
Amaury Poulyff946f12017-01-01 21:31:47 +0100117 err = compute_soft_md5sum(file, md5sum);
Amaury Pouly782d9c02014-05-29 21:45:51 +0200118 else
119 {
120 printf("Invalid md5sum type '%s'\n", type);
121 return 1;
122 }
123 if(err != IMX_SUCCESS)
124 {
125 printf("There was an error when computing the MD5 sum: %d\n", err);
126 return 2;
127 }
128 printf("%s MD5 sum: ", type);
129 for(int i = 0; i < 16; i++)
130 printf("%02x", md5sum[i]);
131 printf("\n");
132 return 0;
133}
134
Amaury Pouly303c4862011-11-06 19:44:03 +0000135int main(int argc, char *argv[])
136{
137 char *infile = NULL;
138 char *outfile = NULL;
139 char *bootfile = NULL;
Amaury Poulye09c1e32012-05-19 13:55:33 +0200140 enum imx_firmware_variant_t variant = VARIANT_DEFAULT;
Amaury Pouly303c4862011-11-06 19:44:03 +0000141 enum imx_output_type_t type = IMX_DUALBOOT;
Amaury Pouly782d9c02014-05-29 21:45:51 +0200142 enum imx_model_t model = MODEL_UNKNOWN;
Amaury Pouly303c4862011-11-06 19:44:03 +0000143 bool debug = false;
Amaury Pouly782d9c02014-05-29 21:45:51 +0200144 const char *md5type = NULL;
Amaury Pouly42a725f2013-01-29 11:50:46 +0000145 const char *force_version = NULL;
Amaury Pouly303c4862011-11-06 19:44:03 +0000146
147 if(argc == 1)
148 usage();
Dominik Riebeling2d2fa5c2011-12-04 13:54:07 +0000149
Amaury Pouly303c4862011-11-06 19:44:03 +0000150 while(1)
151 {
152 static struct option long_options[] =
153 {
Amaury Poulyff946f12017-01-01 21:31:47 +0100154 {"help", no_argument, 0, 'h'},
Amaury Pouly303c4862011-11-06 19:44:03 +0000155 {"in-file", no_argument, 0, 'i'},
156 {"out-file", required_argument, 0, 'o'},
157 {"boot-file", required_argument, 0, 'b'},
158 {"debug", no_argument, 0, 'd'},
159 {"type", required_argument, 0, 't'},
Amaury Poulye09c1e32012-05-19 13:55:33 +0200160 {"variant", required_argument, 0, 'v'},
161 {"dev-info", no_argument, 0, 'x'},
Amaury Pouly782d9c02014-05-29 21:45:51 +0200162 {"model", required_argument, 0, 'm'},
163 {"md5", required_argument, 0, '5'},
Amaury Pouly303c4862011-11-06 19:44:03 +0000164 {0, 0, 0, 0}
165 };
166
Amaury Poulyff946f12017-01-01 21:31:47 +0100167 int c = getopt_long(argc, argv, "hdi:o:b:t:v:xp:m:5:", long_options, NULL);
Amaury Pouly303c4862011-11-06 19:44:03 +0000168 if(c == -1)
169 break;
170 switch(c)
171 {
172 case 'd':
173 debug = true;
174 break;
Amaury Poulyff946f12017-01-01 21:31:47 +0100175 case 'h':
Amaury Pouly303c4862011-11-06 19:44:03 +0000176 usage();
177 break;
178 case 'o':
179 outfile = optarg;
180 break;
181 case 'i':
182 infile = optarg;
183 break;
184 case 'b':
Amaury Pouly303c4862011-11-06 19:44:03 +0000185 bootfile = optarg;
186 break;
Amaury Pouly303c4862011-11-06 19:44:03 +0000187 case 't':
188 if(strcmp(optarg, "dualboot") == 0)
189 type = IMX_DUALBOOT;
190 else if(strcmp(optarg, "singleboot") == 0)
191 type = IMX_SINGLEBOOT;
192 else if(strcmp(optarg, "recovery") == 0)
193 type = IMX_RECOVERY;
Amaury Pouly6022d312014-01-21 19:01:34 +0100194 else if(strcmp(optarg, "charge") == 0)
195 type = IMX_CHARGE;
Amaury Poulyff946f12017-01-01 21:31:47 +0100196 else if(strcmp(optarg, "origfw") == 0)
197 type = IMX_ORIG_FW;
Amaury Pouly303c4862011-11-06 19:44:03 +0000198 else
199 {
200 printf("Invalid boot type '%s'\n", optarg);
201 return 1;
202 }
203 break;
Amaury Poulye09c1e32012-05-19 13:55:33 +0200204 case 'v':
205 {
206 for(size_t i = 0; i < NR_VARIANTS; i++)
207 {
208 if(strcmp(optarg, imx_variants[i].name) == 0)
209 {
210 variant = imx_variants[i].variant;
211 goto Lok;
212 }
213 }
214 printf("Invalid variant '%s'\n", optarg);
215 return 1;
Amaury Pouly7c7fa362013-06-15 22:19:52 +0200216
Amaury Poulye09c1e32012-05-19 13:55:33 +0200217 Lok:
218 break;
219 }
220 case 'x':
221 dump_imx_dev_info("");
222 printf("variant mapping:\n");
223 for(int i = 0; i < sizeof(imx_variants) / sizeof(imx_variants[0]); i++)
224 printf(" %s -> variant=%d\n", imx_variants[i].name, imx_variants[i].variant);
225 break;
Amaury Pouly42a725f2013-01-29 11:50:46 +0000226 case 'p':
227 force_version = optarg;
228 break;
Amaury Pouly782d9c02014-05-29 21:45:51 +0200229 case '5':
230 md5type = optarg;
231 break;
232 case 'm':
233 if(model != MODEL_UNKNOWN)
234 {
235 printf("You cannot specify two models\n");
236 return 1;
237 }
238 for(int i = 0; i < NR_MODELS; i++)
239 if(strcmp(optarg, imx_models[i].name) == 0)
240 {
241 model = imx_models[i].model;
242 break;
243 }
244 if(model == MODEL_UNKNOWN)
245 printf("Unknown model '%s'\n", optarg);
246 break;
Amaury Pouly303c4862011-11-06 19:44:03 +0000247 default:
248 abort();
249 }
250 }
251
252 if(!infile)
253 {
254 printf("You must specify an input file\n");
255 return 1;
256 }
Amaury Pouly782d9c02014-05-29 21:45:51 +0200257
258 if(md5type)
259 return print_md5(infile, md5type);
260
Amaury Pouly303c4862011-11-06 19:44:03 +0000261 if(!outfile)
262 {
263 printf("You must specify an output file\n");
264 return 1;
265 }
Amaury Poulyff946f12017-01-01 21:31:47 +0100266
267 if(!bootfile && type != IMX_ORIG_FW)
Amaury Pouly303c4862011-11-06 19:44:03 +0000268 {
269 printf("You must specify an boot file\n");
270 return 1;
271 }
Amaury Poulyff946f12017-01-01 21:31:47 +0100272
Amaury Pouly303c4862011-11-06 19:44:03 +0000273 if(optind != argc)
274 {
275 printf("Extra arguments on command line\n");
276 return 1;
277 }
278
279 struct imx_option_t opt;
Amaury Poulye09c1e32012-05-19 13:55:33 +0200280 memset(&opt, 0, sizeof(opt));
Amaury Pouly303c4862011-11-06 19:44:03 +0000281 opt.debug = debug;
282 opt.output = type;
Amaury Poulye09c1e32012-05-19 13:55:33 +0200283 opt.fw_variant = variant;
Amaury Pouly42a725f2013-01-29 11:50:46 +0000284 opt.force_version = force_version;
Amaury Poulyb7727822014-08-31 20:40:58 +0200285 opt.model = model;
Amaury Pouly303c4862011-11-06 19:44:03 +0000286 enum imx_error_t err = mkimxboot(infile, bootfile, outfile, opt);
Amaury Poulyee2eb132017-11-05 18:27:18 +0100287 printf("Result: %d (%s)\n", err, imx_error_to_string(err));
Amaury Pouly303c4862011-11-06 19:44:03 +0000288 return 0;
289}