diff options
Diffstat (limited to 'rbutil/mkimxboot/mkimxboot.c')
-rw-r--r-- | rbutil/mkimxboot/mkimxboot.c | 134 |
1 files changed, 104 insertions, 30 deletions
diff --git a/rbutil/mkimxboot/mkimxboot.c b/rbutil/mkimxboot/mkimxboot.c index 6f90924c9a..8806167078 100644 --- a/rbutil/mkimxboot/mkimxboot.c +++ b/rbutil/mkimxboot/mkimxboot.c | |||
@@ -26,20 +26,22 @@ | |||
26 | #include "dualboot.h" | 26 | #include "dualboot.h" |
27 | #include "md5.h" | 27 | #include "md5.h" |
28 | 28 | ||
29 | /* Supported models */ | 29 | struct imx_fw_variant_desc_t |
30 | enum imx_model_t | ||
31 | { | 30 | { |
32 | MODEL_UNKNOWN = -1, | 31 | /* Offset within file */ |
33 | MODEL_FUZEPLUS = 0, | 32 | size_t offset; |
34 | /* new models go here */ | 33 | /* Total size of the firmware */ |
35 | 34 | size_t size; | |
36 | NUM_MODELS | ||
37 | }; | 35 | }; |
38 | 36 | ||
39 | struct imx_md5sum_t | 37 | struct imx_md5sum_t |
40 | { | 38 | { |
41 | int model; | 39 | /* Device model */ |
40 | enum imx_model_t model; | ||
41 | /* md5sum of the file */ | ||
42 | char *md5sum; | 42 | char *md5sum; |
43 | /* Variant descriptions */ | ||
44 | struct imx_fw_variant_desc_t fw_variants[VARIANT_COUNT]; | ||
43 | }; | 45 | }; |
44 | 46 | ||
45 | struct imx_model_desc_t | 47 | struct imx_model_desc_t |
@@ -66,9 +68,38 @@ struct imx_model_desc_t | |||
66 | uint32_t bootloader_addr; | 68 | uint32_t bootloader_addr; |
67 | }; | 69 | }; |
68 | 70 | ||
71 | static const char *imx_fw_variant[] = | ||
72 | { | ||
73 | [VARIANT_DEFAULT] = "default", | ||
74 | [VARIANT_ZENXFI2_RECOVERY] = "ZEN X-Fi2 Recovery", | ||
75 | [VARIANT_ZENXFI2_NAND] = "ZEN X-Fi2 NAND", | ||
76 | [VARIANT_ZENXFI2_SD] = "ZEN X-Fi2 eMMC/SD", | ||
77 | }; | ||
78 | |||
69 | static const struct imx_md5sum_t imx_sums[] = | 79 | static const struct imx_md5sum_t imx_sums[] = |
70 | { | 80 | { |
71 | { MODEL_FUZEPLUS, "c3e27620a877dc6b200b97dcb3e0ecc7" }, /* Version 2.38.6 */ | 81 | { |
82 | /* Version 2.38.6 */ | ||
83 | MODEL_FUZEPLUS, "c3e27620a877dc6b200b97dcb3e0ecc7", | ||
84 | { [VARIANT_DEFAULT] = { 0, 34652624 } } | ||
85 | }, | ||
86 | { | ||
87 | /* Version 1.23.01e */ | ||
88 | MODEL_ZENXFI2, "e37e2c24abdff8e624d0a29f79157850", | ||
89 | }, | ||
90 | { | ||
91 | /* Version 1.23.01e */ | ||
92 | MODEL_ZENXFI2, "2beff2168212d332f13cfc36ca46989d", | ||
93 | { [VARIANT_ZENXFI2_RECOVERY] = { 0x93010, 684192}, | ||
94 | [VARIANT_ZENXFI2_NAND] = { 0x13a0b0, 42410704 }, | ||
95 | [VARIANT_ZENXFI2_SD] = { 0x29ac380, 42304208 } | ||
96 | } | ||
97 | }, | ||
98 | { | ||
99 | /* Version 1.00.22e */ | ||
100 | MODEL_ZENXFI3, "658a24eeef5f7186ca731085d8822a87", | ||
101 | { [VARIANT_DEFAULT] = {0, 18110576} } | ||
102 | }, | ||
72 | }; | 103 | }; |
73 | 104 | ||
74 | static struct crypto_key_t zero_key = | 105 | static struct crypto_key_t zero_key = |
@@ -79,8 +110,12 @@ static struct crypto_key_t zero_key = | |||
79 | 110 | ||
80 | static const struct imx_model_desc_t imx_models[] = | 111 | static const struct imx_model_desc_t imx_models[] = |
81 | { | 112 | { |
82 | [MODEL_FUZEPLUS] = { "Fuze+", dualboot_fuzeplus, sizeof(dualboot_fuzeplus), "fuz+", 72, | 113 | [MODEL_FUZEPLUS] = { "Fuze+", dualboot_fuzeplus, sizeof(dualboot_fuzeplus), "fuz+", 72, |
83 | 1, &zero_key, 0, 0x40000000 }, | 114 | 1, &zero_key, 0, 0x40000000 }, |
115 | [MODEL_ZENXFI2] = {"Zen X-Fi2", dualboot_zenxfi2, sizeof(dualboot_zenxfi2), "zxf2", 82, | ||
116 | 1, &zero_key, 0, 0x40000000 }, | ||
117 | [MODEL_ZENXFI3] = {"Zen X-Fi3", dualboot_zenxfi3, sizeof(dualboot_zenxfi3), "zxf3", 83, | ||
118 | 1, &zero_key, 0, 0x40000000 }, | ||
84 | }; | 119 | }; |
85 | 120 | ||
86 | #define NR_IMX_SUMS (sizeof(imx_sums) / sizeof(imx_sums[0])) | 121 | #define NR_IMX_SUMS (sizeof(imx_sums) / sizeof(imx_sums[0])) |
@@ -212,7 +247,8 @@ static enum imx_error_t patch_std_zero_host_play(int jump_before, int model, | |||
212 | } | 247 | } |
213 | } | 248 | } |
214 | 249 | ||
215 | static enum imx_error_t patch_firmware(int model, enum imx_output_type_t type, | 250 | static enum imx_error_t patch_firmware(enum imx_model_t model, |
251 | enum imx_firmware_variant_t variant, enum imx_output_type_t type, | ||
216 | struct sb_file_t *sb_file, void *boot, size_t boot_sz) | 252 | struct sb_file_t *sb_file, void *boot, size_t boot_sz) |
217 | { | 253 | { |
218 | switch(model) | 254 | switch(model) |
@@ -221,6 +257,23 @@ static enum imx_error_t patch_firmware(int model, enum imx_output_type_t type, | |||
221 | /* The Fuze+ uses the standard ____, host, play sections, patch after third | 257 | /* The Fuze+ uses the standard ____, host, play sections, patch after third |
222 | * call in ____ section */ | 258 | * call in ____ section */ |
223 | return patch_std_zero_host_play(3, model, type, sb_file, boot, boot_sz); | 259 | return patch_std_zero_host_play(3, model, type, sb_file, boot, boot_sz); |
260 | case MODEL_ZENXFI3: | ||
261 | /* The ZEN X-Fi3 uses the standard ____, hSst, pSay sections, patch after third | ||
262 | * call in ____ section. Although sections names use the S variant, they are standard. */ | ||
263 | return patch_std_zero_host_play(3, model, type, sb_file, boot, boot_sz); | ||
264 | case MODEL_ZENXFI2: | ||
265 | /* The ZEN X-Fi2 has two types of firmware: recovery and normal. | ||
266 | * Normal uses the standard ___, host, play sections and recovery only ____ */ | ||
267 | switch(variant) | ||
268 | { | ||
269 | case VARIANT_ZENXFI2_RECOVERY: | ||
270 | case VARIANT_ZENXFI2_NAND: | ||
271 | case VARIANT_ZENXFI2_SD: | ||
272 | return patch_std_zero_host_play(1, model, type, sb_file, boot, boot_sz); | ||
273 | default: | ||
274 | return IMX_DONT_KNOW_HOW_TO_PATCH; | ||
275 | } | ||
276 | break; | ||
224 | default: | 277 | default: |
225 | return IMX_DONT_KNOW_HOW_TO_PATCH; | 278 | return IMX_DONT_KNOW_HOW_TO_PATCH; |
226 | } | 279 | } |
@@ -247,26 +300,38 @@ static uint32_t get_uint32be(unsigned char *p) | |||
247 | return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; | 300 | return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; |
248 | } | 301 | } |
249 | 302 | ||
303 | void dump_imx_dev_info(const char *prefix) | ||
304 | { | ||
305 | printf("%smkimxboot models:\n", prefix); | ||
306 | for(int i = 0; i < NR_IMX_MODELS; i++) | ||
307 | { | ||
308 | printf("%s %s: idx=%d rb_model=%s rb_num=%d\n", prefix, | ||
309 | imx_models[i].model_name, i, imx_models[i].rb_model_name, | ||
310 | imx_models[i].rb_model_num); | ||
311 | } | ||
312 | printf("%smkimxboot variants:\n", prefix); | ||
313 | for(int i = 0; i < VARIANT_COUNT; i++) | ||
314 | { | ||
315 | printf("%s %d: %s\n", prefix, i, imx_fw_variant[i]); | ||
316 | } | ||
317 | printf("%smkimxboot mapping:\n", prefix); | ||
318 | for(int i = 0; i < NR_IMX_SUMS; i++) | ||
319 | { | ||
320 | printf("%s md5sum=%s -> idx=%d\n", prefix, imx_sums[i].md5sum, | ||
321 | imx_sums[i].model); | ||
322 | for(int j = 0; j < VARIANT_COUNT; j++) | ||
323 | if(imx_sums[i].fw_variants[j].size) | ||
324 | printf("%s variant=%d -> offset=%#x size=%#x\n", prefix, | ||
325 | j, (unsigned)imx_sums[i].fw_variants[j].offset, | ||
326 | (unsigned)imx_sums[i].fw_variants[j].size); | ||
327 | } | ||
328 | } | ||
329 | |||
250 | enum imx_error_t mkimxboot(const char *infile, const char *bootfile, | 330 | enum imx_error_t mkimxboot(const char *infile, const char *bootfile, |
251 | const char *outfile, struct imx_option_t opt) | 331 | const char *outfile, struct imx_option_t opt) |
252 | { | 332 | { |
253 | /* Dump tables */ | 333 | /* Dump tables */ |
254 | do | 334 | dump_imx_dev_info("[INFO] "); |
255 | { | ||
256 | printf("[INFO] mkimxboot models:\n"); | ||
257 | for(int i = 0; i < NR_IMX_MODELS; i++) | ||
258 | { | ||
259 | printf("[INFO] %s: idx=%d rb_model=%s rb_num=%d\n", | ||
260 | imx_models[i].model_name, i, imx_models[i].rb_model_name, | ||
261 | imx_models[i].rb_model_num); | ||
262 | } | ||
263 | printf("[INFO] mkimxboot mapping:\n"); | ||
264 | for(int i = 0; i < NR_IMX_SUMS; i++) | ||
265 | { | ||
266 | printf("[INFO] md5sum=%s -> idx=%d\n", imx_sums[i].md5sum, | ||
267 | imx_sums[i].model); | ||
268 | } | ||
269 | }while(0); | ||
270 | /* compute MD5 sum of the file */ | 335 | /* compute MD5 sum of the file */ |
271 | uint8_t file_md5sum[16]; | 336 | uint8_t file_md5sum[16]; |
272 | do | 337 | do |
@@ -298,7 +363,8 @@ enum imx_error_t mkimxboot(const char *infile, const char *bootfile, | |||
298 | printf("[INFO] MD5 sum of the file: "); | 363 | printf("[INFO] MD5 sum of the file: "); |
299 | print_hex(file_md5sum, 16, true); | 364 | print_hex(file_md5sum, 16, true); |
300 | /* find model */ | 365 | /* find model */ |
301 | int model; | 366 | enum imx_model_t model; |
367 | int md5_idx; | ||
302 | do | 368 | do |
303 | { | 369 | { |
304 | int i = 0; | 370 | int i = 0; |
@@ -327,6 +393,7 @@ enum imx_error_t mkimxboot(const char *infile, const char *bootfile, | |||
327 | return IMX_NO_MATCH; | 393 | return IMX_NO_MATCH; |
328 | } | 394 | } |
329 | model = imx_sums[i].model; | 395 | model = imx_sums[i].model; |
396 | md5_idx = i; | ||
330 | }while(0); | 397 | }while(0); |
331 | printf("[INFO] File is for model %d (%s)\n", model, imx_models[model].model_name); | 398 | printf("[INFO] File is for model %d (%s)\n", model, imx_models[model].model_name); |
332 | /* load rockbox file */ | 399 | /* load rockbox file */ |
@@ -385,11 +452,18 @@ enum imx_error_t mkimxboot(const char *infile, const char *bootfile, | |||
385 | struct sb_file_t *sb_file; | 452 | struct sb_file_t *sb_file; |
386 | do | 453 | do |
387 | { | 454 | { |
455 | if(imx_sums[md5_idx].fw_variants[opt.fw_variant].size == 0) | ||
456 | { | ||
457 | printf("[ERR] Input file does not contain variant '%s'\n", imx_fw_variant[opt.fw_variant]); | ||
458 | free(boot); | ||
459 | return IMX_VARIANT_MISMATCH; | ||
460 | } | ||
388 | enum sb_error_t err; | 461 | enum sb_error_t err; |
389 | g_debug = opt.debug; | 462 | g_debug = opt.debug; |
390 | clear_keys(); | 463 | clear_keys(); |
391 | add_keys(imx_models[model].keys, imx_models[model].nr_keys); | 464 | add_keys(imx_models[model].keys, imx_models[model].nr_keys); |
392 | sb_file = sb_read_file(infile, false, NULL, &imx_printf, &err); | 465 | sb_file = sb_read_file_ex(infile, imx_sums[md5_idx].fw_variants[opt.fw_variant].offset, |
466 | imx_sums[md5_idx].fw_variants[opt.fw_variant].size, false, NULL, &imx_printf, &err); | ||
393 | if(sb_file == NULL) | 467 | if(sb_file == NULL) |
394 | { | 468 | { |
395 | clear_keys(); | 469 | clear_keys(); |
@@ -398,7 +472,7 @@ enum imx_error_t mkimxboot(const char *infile, const char *bootfile, | |||
398 | } | 472 | } |
399 | }while(0); | 473 | }while(0); |
400 | /* produce file */ | 474 | /* produce file */ |
401 | enum imx_error_t ret = patch_firmware(model, opt.output, sb_file, boot + 8, boot_size - 8); | 475 | enum imx_error_t ret = patch_firmware(model, opt.fw_variant, opt.output, sb_file, boot + 8, boot_size - 8); |
402 | if(ret == IMX_SUCCESS) | 476 | if(ret == IMX_SUCCESS) |
403 | ret = sb_write_file(sb_file, outfile); | 477 | ret = sb_write_file(sb_file, outfile); |
404 | 478 | ||