summaryrefslogtreecommitdiff
path: root/rbutil/mkimxboot
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil/mkimxboot')
-rw-r--r--rbutil/mkimxboot/main.c16
-rw-r--r--rbutil/mkimxboot/mkimxboot.c103
-rw-r--r--rbutil/mkimxboot/mkimxboot.h2
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
499enum 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
85void dump_imx_dev_info(const char *prefix); 85void dump_imx_dev_info(const char *prefix);
86enum imx_error_t mkimxboot(const char *infile, const char *bootfile, 86enum 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);
88enum 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}