diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2013-01-26 18:24:06 +0000 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2013-01-26 18:24:50 +0000 |
commit | f6e4456cc4337e30483bc52c9dac6e2d38c78897 (patch) | |
tree | 7ed153f7b09ae131ae530885656cb724e8400503 | |
parent | b6cad07f335db0f52e949b9ead0ea7f82202c854 (diff) | |
download | rockbox-f6e4456cc4337e30483bc52c9dac6e2d38c78897.tar.gz rockbox-f6e4456cc4337e30483bc52c9dac6e2d38c78897.zip |
mkimxboot: add an option to extract the of without processing
Change-Id: Ie370f152f4efff4428ee023a9211b82a77fd1df4
-rw-r--r-- | rbutil/mkimxboot/main.c | 16 | ||||
-rw-r--r-- | rbutil/mkimxboot/mkimxboot.c | 103 | ||||
-rw-r--r-- | rbutil/mkimxboot/mkimxboot.h | 2 |
3 files changed, 119 insertions, 2 deletions
diff --git a/rbutil/mkimxboot/main.c b/rbutil/mkimxboot/main.c index 68387c25c0..ed88d3e1ff 100644 --- a/rbutil/mkimxboot/main.c +++ b/rbutil/mkimxboot/main.c | |||
@@ -53,6 +53,7 @@ static void usage(void) | |||
53 | printf(" -t <type>\tSet type (dualboot, singleboot, recovery)\n"); | 53 | printf(" -t <type>\tSet type (dualboot, singleboot, recovery)\n"); |
54 | printf(" -v <v>\tSet variant\n"); | 54 | printf(" -v <v>\tSet variant\n"); |
55 | printf(" -x\t\tDump device informations\n"); | 55 | printf(" -x\t\tDump device informations\n"); |
56 | printf(" -w\tExtract the original firmware\n"); | ||
56 | printf("Supported variants: (default is standard)\n"); | 57 | printf("Supported variants: (default is standard)\n"); |
57 | printf(" "); | 58 | printf(" "); |
58 | for(size_t i = 0; i < NR_VARIANTS; i++) | 59 | for(size_t i = 0; i < NR_VARIANTS; i++) |
@@ -74,6 +75,7 @@ int main(int argc, char *argv[]) | |||
74 | enum imx_firmware_variant_t variant = VARIANT_DEFAULT; | 75 | enum imx_firmware_variant_t variant = VARIANT_DEFAULT; |
75 | enum imx_output_type_t type = IMX_DUALBOOT; | 76 | enum imx_output_type_t type = IMX_DUALBOOT; |
76 | bool debug = false; | 77 | bool debug = false; |
78 | bool extract_of = false; | ||
77 | 79 | ||
78 | if(argc == 1) | 80 | if(argc == 1) |
79 | usage(); | 81 | usage(); |
@@ -93,7 +95,7 @@ int main(int argc, char *argv[]) | |||
93 | {0, 0, 0, 0} | 95 | {0, 0, 0, 0} |
94 | }; | 96 | }; |
95 | 97 | ||
96 | int c = getopt_long(argc, argv, "?di:o:b:t:v:x", long_options, NULL); | 98 | int c = getopt_long(argc, argv, "?di:o:b:t:v:xw", long_options, NULL); |
97 | if(c == -1) | 99 | if(c == -1) |
98 | break; | 100 | break; |
99 | switch(c) | 101 | switch(c) |
@@ -150,6 +152,9 @@ int main(int argc, char *argv[]) | |||
150 | for(int i = 0; i < sizeof(imx_variants) / sizeof(imx_variants[0]); i++) | 152 | for(int i = 0; i < sizeof(imx_variants) / sizeof(imx_variants[0]); i++) |
151 | printf(" %s -> variant=%d\n", imx_variants[i].name, imx_variants[i].variant); | 153 | printf(" %s -> variant=%d\n", imx_variants[i].name, imx_variants[i].variant); |
152 | break; | 154 | break; |
155 | case 'w': | ||
156 | extract_of = true; | ||
157 | break; | ||
153 | default: | 158 | default: |
154 | abort(); | 159 | abort(); |
155 | } | 160 | } |
@@ -165,7 +170,7 @@ int main(int argc, char *argv[]) | |||
165 | printf("You must specify an output file\n"); | 170 | printf("You must specify an output file\n"); |
166 | return 1; | 171 | return 1; |
167 | } | 172 | } |
168 | if(!bootfile) | 173 | if(!bootfile && !extract_of) |
169 | { | 174 | { |
170 | printf("You must specify an boot file\n"); | 175 | printf("You must specify an boot file\n"); |
171 | return 1; | 176 | return 1; |
@@ -176,6 +181,13 @@ int main(int argc, char *argv[]) | |||
176 | return 1; | 181 | return 1; |
177 | } | 182 | } |
178 | 183 | ||
184 | if(extract_of) | ||
185 | { | ||
186 | enum imx_error_t err = extract_firmware(infile, variant, outfile); | ||
187 | printf("Result: %d\n", err); | ||
188 | return 0; | ||
189 | } | ||
190 | |||
179 | struct imx_option_t opt; | 191 | struct imx_option_t opt; |
180 | memset(&opt, 0, sizeof(opt)); | 192 | memset(&opt, 0, sizeof(opt)); |
181 | opt.debug = debug; | 193 | opt.debug = debug; |
diff --git a/rbutil/mkimxboot/mkimxboot.c b/rbutil/mkimxboot/mkimxboot.c index b79361dd63..9e43bbd61c 100644 --- a/rbutil/mkimxboot/mkimxboot.c +++ b/rbutil/mkimxboot/mkimxboot.c | |||
@@ -495,3 +495,106 @@ enum imx_error_t mkimxboot(const char *infile, const char *bootfile, | |||
495 | sb_free(sb_file); | 495 | sb_free(sb_file); |
496 | return ret; | 496 | return ret; |
497 | } | 497 | } |
498 | |||
499 | enum imx_error_t extract_firmware(const char *infile, | ||
500 | enum imx_firmware_variant_t fw_variant, const char *outfile) | ||
501 | { | ||
502 | /* Dump tables */ | ||
503 | if(fw_variant > VARIANT_COUNT) { | ||
504 | return IMX_ERROR; | ||
505 | } | ||
506 | dump_imx_dev_info("[INFO] "); | ||
507 | /* compute MD5 sum of the file */ | ||
508 | uint8_t file_md5sum[16]; | ||
509 | FILE *f = fopen(infile, "rb"); | ||
510 | if(f == NULL) | ||
511 | { | ||
512 | printf("[ERR] Cannot open input file\n"); | ||
513 | return IMX_OPEN_ERROR; | ||
514 | } | ||
515 | fseek(f, 0, SEEK_END); | ||
516 | size_t sz = ftell(f); | ||
517 | fseek(f, 0, SEEK_SET); | ||
518 | void *buf = xmalloc(sz); | ||
519 | if(fread(buf, sz, 1, f) != 1) | ||
520 | { | ||
521 | fclose(f); | ||
522 | free(buf); | ||
523 | printf("[ERR] Cannot read file\n"); | ||
524 | return IMX_READ_ERROR; | ||
525 | } | ||
526 | md5_context ctx; | ||
527 | md5_starts(&ctx); | ||
528 | md5_update(&ctx, buf, sz); | ||
529 | md5_finish(&ctx, file_md5sum); | ||
530 | fclose(f); | ||
531 | |||
532 | printf("[INFO] MD5 sum of the file: "); | ||
533 | print_hex(file_md5sum, 16, true); | ||
534 | /* find model */ | ||
535 | enum imx_model_t model; | ||
536 | int md5_idx; | ||
537 | do | ||
538 | { | ||
539 | int i = 0; | ||
540 | while(i < NR_IMX_SUMS) | ||
541 | { | ||
542 | uint8_t md5[20]; | ||
543 | if(strlen(imx_sums[i].md5sum) != 32) | ||
544 | { | ||
545 | printf("[INFO] Invalid MD5 sum in imx_sums\n"); | ||
546 | return IMX_ERROR; | ||
547 | } | ||
548 | for(int j = 0; j < 16; j++) | ||
549 | { | ||
550 | byte a, b; | ||
551 | if(convxdigit(imx_sums[i].md5sum[2 * j], &a) || convxdigit(imx_sums[i].md5sum[2 * j + 1], &b)) | ||
552 | { | ||
553 | printf("[ERR][INTERNAL] Bad checksum format: %s\n", imx_sums[i].md5sum); | ||
554 | free(buf); | ||
555 | return IMX_ERROR; | ||
556 | } | ||
557 | md5[j] = (a << 4) | b; | ||
558 | } | ||
559 | if(memcmp(file_md5sum, md5, 16) == 0) | ||
560 | break; | ||
561 | i++; | ||
562 | } | ||
563 | if(i == NR_IMX_SUMS) | ||
564 | { | ||
565 | printf("[ERR] MD5 sum doesn't match any known file\n"); | ||
566 | return IMX_NO_MATCH; | ||
567 | } | ||
568 | model = imx_sums[i].model; | ||
569 | md5_idx = i; | ||
570 | }while(0); | ||
571 | printf("[INFO] File is for model %d (%s, version %s)\n", model, | ||
572 | imx_models[model].model_name, imx_sums[md5_idx].version); | ||
573 | |||
574 | if(imx_sums[md5_idx].fw_variants[fw_variant].size == 0) | ||
575 | { | ||
576 | printf("[ERR] Input file does not contain variant '%s'\n", imx_fw_variant[fw_variant]); | ||
577 | free(buf); | ||
578 | return IMX_VARIANT_MISMATCH; | ||
579 | } | ||
580 | |||
581 | f = fopen(outfile, "wb"); | ||
582 | if(f == NULL) | ||
583 | { | ||
584 | printf("[ERR] Cannot open input file\n"); | ||
585 | free(buf); | ||
586 | return IMX_OPEN_ERROR; | ||
587 | } | ||
588 | enum imx_error_t ret = IMX_SUCCESS; | ||
589 | |||
590 | if(fwrite(buf + imx_sums[md5_idx].fw_variants[fw_variant].offset, | ||
591 | imx_sums[md5_idx].fw_variants[fw_variant].size, 1, f) != 1) | ||
592 | { | ||
593 | printf("[ERR] Cannot write file\n"); | ||
594 | ret = IMX_ERROR; | ||
595 | } | ||
596 | fclose(f); | ||
597 | free(buf); | ||
598 | |||
599 | return ret; | ||
600 | } | ||
diff --git a/rbutil/mkimxboot/mkimxboot.h b/rbutil/mkimxboot/mkimxboot.h index 5be87b31e0..1c3711023c 100644 --- a/rbutil/mkimxboot/mkimxboot.h +++ b/rbutil/mkimxboot/mkimxboot.h | |||
@@ -85,6 +85,8 @@ struct imx_option_t | |||
85 | void dump_imx_dev_info(const char *prefix); | 85 | void dump_imx_dev_info(const char *prefix); |
86 | enum imx_error_t mkimxboot(const char *infile, const char *bootfile, | 86 | enum imx_error_t mkimxboot(const char *infile, const char *bootfile, |
87 | const char *outfile, struct imx_option_t opt); | 87 | const char *outfile, struct imx_option_t opt); |
88 | enum imx_error_t extract_firmware(const char *infile, | ||
89 | enum imx_firmware_variant_t fw_variant, const char *outfile); | ||
88 | 90 | ||
89 | #ifdef __cplusplus | 91 | #ifdef __cplusplus |
90 | } | 92 | } |