Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 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 Riebeling | 2d2fa5c | 2011-12-04 13:54:07 +0000 | [diff] [blame] | 25 | #include <string.h> |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 26 | #include "mkimxboot.h" |
| 27 | |
Amaury Pouly | e09c1e3 | 2012-05-19 13:55:33 +0200 | [diff] [blame] | 28 | struct imx_variant_t |
| 29 | { |
| 30 | const char *name; |
| 31 | enum imx_firmware_variant_t variant; |
| 32 | }; |
| 33 | |
Thomas Jarosch | 2a3e162 | 2015-01-11 21:40:51 +0100 | [diff] [blame] | 34 | static struct imx_variant_t imx_variants[] = |
Amaury Pouly | e09c1e3 | 2012-05-19 13:55:33 +0200 | [diff] [blame] | 35 | { |
| 36 | { "default", VARIANT_DEFAULT }, |
| 37 | { "zenxfi2-recovery", VARIANT_ZENXFI2_RECOVERY }, |
| 38 | { "zenxfi2-nand", VARIANT_ZENXFI2_NAND }, |
| 39 | { "zenxfi2-sd", VARIANT_ZENXFI2_SD }, |
Amaury Pouly | f2dfc84 | 2013-01-26 18:37:12 +0000 | [diff] [blame] | 40 | { "zenxfistyle-recovery", VARIANT_ZENXFISTYLE_RECOVERY }, |
Amaury Pouly | 55babd5 | 2013-06-18 15:02:01 +0200 | [diff] [blame] | 41 | { "zenstyle-recovery", VARIANT_ZENSTYLE_RECOVERY }, |
Amaury Pouly | e09c1e3 | 2012-05-19 13:55:33 +0200 | [diff] [blame] | 42 | }; |
| 43 | |
| 44 | #define NR_VARIANTS sizeof(imx_variants) / sizeof(imx_variants[0]) |
| 45 | |
Amaury Pouly | 782d9c0 | 2014-05-29 21:45:51 +0200 | [diff] [blame] | 46 | struct model_t |
| 47 | { |
| 48 | const char *name; |
| 49 | enum imx_model_t model; |
| 50 | }; |
| 51 | |
| 52 | struct 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 Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 66 | static void usage(void) |
| 67 | { |
Amaury Pouly | 44c32f8 | 2013-03-10 15:10:38 +0100 | [diff] [blame] | 68 | printf("Usage: mkimxboot [options | file]...\n"); |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 69 | printf("Options:\n"); |
Amaury Pouly | 6483e23 | 2013-06-15 22:11:04 +0200 | [diff] [blame] | 70 | 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 Pouly | ff946f1 | 2017-01-01 21:31:47 +0100 | [diff] [blame] | 75 | printf(" -t <type> Set type (dualboot, singleboot, recovery, origfw, charge)\n"); |
Amaury Pouly | 6483e23 | 2013-06-15 22:11:04 +0200 | [diff] [blame] | 76 | printf(" -v <v> Set variant\n"); |
| 77 | printf(" -x Dump device informations\n"); |
Amaury Pouly | 6483e23 | 2013-06-15 22:11:04 +0200 | [diff] [blame] | 78 | printf(" -p <ver> Force product and component version\n"); |
Amaury Pouly | 782d9c0 | 2014-05-29 21:45:51 +0200 | [diff] [blame] | 79 | 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 Pouly | e09c1e3 | 2012-05-19 13:55:33 +0200 | [diff] [blame] | 81 | 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 Pouly | 782d9c0 | 2014-05-29 21:45:51 +0200 | [diff] [blame] | 90 | 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 Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 98 | printf("By default a dualboot image is built\n"); |
Amaury Pouly | d561017 | 2013-06-16 01:33:16 +0200 | [diff] [blame] | 99 | 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 Pouly | 782d9c0 | 2014-05-29 21:45:51 +0200 | [diff] [blame] | 104 | 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 Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 107 | exit(1); |
| 108 | } |
| 109 | |
Amaury Pouly | ff946f1 | 2017-01-01 21:31:47 +0100 | [diff] [blame] | 110 | static int print_md5(const char *file, const char *type) |
Amaury Pouly | 782d9c0 | 2014-05-29 21:45:51 +0200 | [diff] [blame] | 111 | { |
| 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 Pouly | ff946f1 | 2017-01-01 21:31:47 +0100 | [diff] [blame] | 117 | err = compute_soft_md5sum(file, md5sum); |
Amaury Pouly | 782d9c0 | 2014-05-29 21:45:51 +0200 | [diff] [blame] | 118 | 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 Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 135 | int main(int argc, char *argv[]) |
| 136 | { |
| 137 | char *infile = NULL; |
| 138 | char *outfile = NULL; |
| 139 | char *bootfile = NULL; |
Amaury Pouly | e09c1e3 | 2012-05-19 13:55:33 +0200 | [diff] [blame] | 140 | enum imx_firmware_variant_t variant = VARIANT_DEFAULT; |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 141 | enum imx_output_type_t type = IMX_DUALBOOT; |
Amaury Pouly | 782d9c0 | 2014-05-29 21:45:51 +0200 | [diff] [blame] | 142 | enum imx_model_t model = MODEL_UNKNOWN; |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 143 | bool debug = false; |
Amaury Pouly | 782d9c0 | 2014-05-29 21:45:51 +0200 | [diff] [blame] | 144 | const char *md5type = NULL; |
Amaury Pouly | 42a725f | 2013-01-29 11:50:46 +0000 | [diff] [blame] | 145 | const char *force_version = NULL; |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 146 | |
| 147 | if(argc == 1) |
| 148 | usage(); |
Dominik Riebeling | 2d2fa5c | 2011-12-04 13:54:07 +0000 | [diff] [blame] | 149 | |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 150 | while(1) |
| 151 | { |
| 152 | static struct option long_options[] = |
| 153 | { |
Amaury Pouly | ff946f1 | 2017-01-01 21:31:47 +0100 | [diff] [blame] | 154 | {"help", no_argument, 0, 'h'}, |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 155 | {"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 Pouly | e09c1e3 | 2012-05-19 13:55:33 +0200 | [diff] [blame] | 160 | {"variant", required_argument, 0, 'v'}, |
| 161 | {"dev-info", no_argument, 0, 'x'}, |
Amaury Pouly | 782d9c0 | 2014-05-29 21:45:51 +0200 | [diff] [blame] | 162 | {"model", required_argument, 0, 'm'}, |
| 163 | {"md5", required_argument, 0, '5'}, |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 164 | {0, 0, 0, 0} |
| 165 | }; |
| 166 | |
Amaury Pouly | ff946f1 | 2017-01-01 21:31:47 +0100 | [diff] [blame] | 167 | int c = getopt_long(argc, argv, "hdi:o:b:t:v:xp:m:5:", long_options, NULL); |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 168 | if(c == -1) |
| 169 | break; |
| 170 | switch(c) |
| 171 | { |
| 172 | case 'd': |
| 173 | debug = true; |
| 174 | break; |
Amaury Pouly | ff946f1 | 2017-01-01 21:31:47 +0100 | [diff] [blame] | 175 | case 'h': |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 176 | usage(); |
| 177 | break; |
| 178 | case 'o': |
| 179 | outfile = optarg; |
| 180 | break; |
| 181 | case 'i': |
| 182 | infile = optarg; |
| 183 | break; |
| 184 | case 'b': |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 185 | bootfile = optarg; |
| 186 | break; |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 187 | 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 Pouly | 6022d31 | 2014-01-21 19:01:34 +0100 | [diff] [blame] | 194 | else if(strcmp(optarg, "charge") == 0) |
| 195 | type = IMX_CHARGE; |
Amaury Pouly | ff946f1 | 2017-01-01 21:31:47 +0100 | [diff] [blame] | 196 | else if(strcmp(optarg, "origfw") == 0) |
| 197 | type = IMX_ORIG_FW; |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 198 | else |
| 199 | { |
| 200 | printf("Invalid boot type '%s'\n", optarg); |
| 201 | return 1; |
| 202 | } |
| 203 | break; |
Amaury Pouly | e09c1e3 | 2012-05-19 13:55:33 +0200 | [diff] [blame] | 204 | 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 Pouly | 7c7fa36 | 2013-06-15 22:19:52 +0200 | [diff] [blame] | 216 | |
Amaury Pouly | e09c1e3 | 2012-05-19 13:55:33 +0200 | [diff] [blame] | 217 | 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 Pouly | 42a725f | 2013-01-29 11:50:46 +0000 | [diff] [blame] | 226 | case 'p': |
| 227 | force_version = optarg; |
| 228 | break; |
Amaury Pouly | 782d9c0 | 2014-05-29 21:45:51 +0200 | [diff] [blame] | 229 | 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 Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 247 | default: |
| 248 | abort(); |
| 249 | } |
| 250 | } |
| 251 | |
| 252 | if(!infile) |
| 253 | { |
| 254 | printf("You must specify an input file\n"); |
| 255 | return 1; |
| 256 | } |
Amaury Pouly | 782d9c0 | 2014-05-29 21:45:51 +0200 | [diff] [blame] | 257 | |
| 258 | if(md5type) |
| 259 | return print_md5(infile, md5type); |
| 260 | |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 261 | if(!outfile) |
| 262 | { |
| 263 | printf("You must specify an output file\n"); |
| 264 | return 1; |
| 265 | } |
Amaury Pouly | ff946f1 | 2017-01-01 21:31:47 +0100 | [diff] [blame] | 266 | |
| 267 | if(!bootfile && type != IMX_ORIG_FW) |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 268 | { |
| 269 | printf("You must specify an boot file\n"); |
| 270 | return 1; |
| 271 | } |
Amaury Pouly | ff946f1 | 2017-01-01 21:31:47 +0100 | [diff] [blame] | 272 | |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 273 | if(optind != argc) |
| 274 | { |
| 275 | printf("Extra arguments on command line\n"); |
| 276 | return 1; |
| 277 | } |
| 278 | |
| 279 | struct imx_option_t opt; |
Amaury Pouly | e09c1e3 | 2012-05-19 13:55:33 +0200 | [diff] [blame] | 280 | memset(&opt, 0, sizeof(opt)); |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 281 | opt.debug = debug; |
| 282 | opt.output = type; |
Amaury Pouly | e09c1e3 | 2012-05-19 13:55:33 +0200 | [diff] [blame] | 283 | opt.fw_variant = variant; |
Amaury Pouly | 42a725f | 2013-01-29 11:50:46 +0000 | [diff] [blame] | 284 | opt.force_version = force_version; |
Amaury Pouly | b772782 | 2014-08-31 20:40:58 +0200 | [diff] [blame] | 285 | opt.model = model; |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 286 | enum imx_error_t err = mkimxboot(infile, bootfile, outfile, opt); |
Amaury Pouly | ee2eb13 | 2017-11-05 18:27:18 +0100 | [diff] [blame] | 287 | printf("Result: %d (%s)\n", err, imx_error_to_string(err)); |
Amaury Pouly | 303c486 | 2011-11-06 19:44:03 +0000 | [diff] [blame] | 288 | return 0; |
| 289 | } |