A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 289 lines 9.0 kB view raw
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> 25#include <string.h> 26#include "mkimxboot.h" 27 28struct imx_variant_t 29{ 30 const char *name; 31 enum imx_firmware_variant_t variant; 32}; 33 34static struct imx_variant_t imx_variants[] = 35{ 36 { "default", VARIANT_DEFAULT }, 37 { "zenxfi2-recovery", VARIANT_ZENXFI2_RECOVERY }, 38 { "zenxfi2-nand", VARIANT_ZENXFI2_NAND }, 39 { "zenxfi2-sd", VARIANT_ZENXFI2_SD }, 40 { "zenxfistyle-recovery", VARIANT_ZENXFISTYLE_RECOVERY }, 41 { "zenstyle-recovery", VARIANT_ZENSTYLE_RECOVERY }, 42}; 43 44#define NR_VARIANTS sizeof(imx_variants) / sizeof(imx_variants[0]) 45 46struct 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 66static void usage(void) 67{ 68 printf("Usage: mkimxboot [options | file]...\n"); 69 printf("Options:\n"); 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"); 75 printf(" -t <type> Set type (dualboot, singleboot, recovery, origfw, charge)\n"); 76 printf(" -v <v> Set variant\n"); 77 printf(" -x Dump device informations\n"); 78 printf(" -p <ver> Force product and component version\n"); 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"); 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"); 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"); 98 printf("By default a dualboot image is built\n"); 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"); 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"); 107 exit(1); 108} 109 110static int print_md5(const char *file, const char *type) 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) 117 err = compute_soft_md5sum(file, md5sum); 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 135int main(int argc, char *argv[]) 136{ 137 char *infile = NULL; 138 char *outfile = NULL; 139 char *bootfile = NULL; 140 enum imx_firmware_variant_t variant = VARIANT_DEFAULT; 141 enum imx_output_type_t type = IMX_DUALBOOT; 142 enum imx_model_t model = MODEL_UNKNOWN; 143 bool debug = false; 144 const char *md5type = NULL; 145 const char *force_version = NULL; 146 147 if(argc == 1) 148 usage(); 149 150 while(1) 151 { 152 static struct option long_options[] = 153 { 154 {"help", no_argument, 0, 'h'}, 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'}, 160 {"variant", required_argument, 0, 'v'}, 161 {"dev-info", no_argument, 0, 'x'}, 162 {"model", required_argument, 0, 'm'}, 163 {"md5", required_argument, 0, '5'}, 164 {0, 0, 0, 0} 165 }; 166 167 int c = getopt_long(argc, argv, "hdi:o:b:t:v:xp:m:5:", long_options, NULL); 168 if(c == -1) 169 break; 170 switch(c) 171 { 172 case 'd': 173 debug = true; 174 break; 175 case 'h': 176 usage(); 177 break; 178 case 'o': 179 outfile = optarg; 180 break; 181 case 'i': 182 infile = optarg; 183 break; 184 case 'b': 185 bootfile = optarg; 186 break; 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; 194 else if(strcmp(optarg, "charge") == 0) 195 type = IMX_CHARGE; 196 else if(strcmp(optarg, "origfw") == 0) 197 type = IMX_ORIG_FW; 198 else 199 { 200 printf("Invalid boot type '%s'\n", optarg); 201 return 1; 202 } 203 break; 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; 216 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; 226 case 'p': 227 force_version = optarg; 228 break; 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; 247 default: 248 abort(); 249 } 250 } 251 252 if(!infile) 253 { 254 printf("You must specify an input file\n"); 255 return 1; 256 } 257 258 if(md5type) 259 return print_md5(infile, md5type); 260 261 if(!outfile) 262 { 263 printf("You must specify an output file\n"); 264 return 1; 265 } 266 267 if(!bootfile && type != IMX_ORIG_FW) 268 { 269 printf("You must specify an boot file\n"); 270 return 1; 271 } 272 273 if(optind != argc) 274 { 275 printf("Extra arguments on command line\n"); 276 return 1; 277 } 278 279 struct imx_option_t opt; 280 memset(&opt, 0, sizeof(opt)); 281 opt.debug = debug; 282 opt.output = type; 283 opt.fw_variant = variant; 284 opt.force_version = force_version; 285 opt.model = model; 286 enum imx_error_t err = mkimxboot(infile, bootfile, outfile, opt); 287 printf("Result: %d (%s)\n", err, imx_error_to_string(err)); 288 return 0; 289}