diff options
Diffstat (limited to 'rbutil/mkimxboot/mkimxboot.c')
-rw-r--r-- | rbutil/mkimxboot/mkimxboot.c | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/rbutil/mkimxboot/mkimxboot.c b/rbutil/mkimxboot/mkimxboot.c index 7a9d05fe69..d420afce5d 100644 --- a/rbutil/mkimxboot/mkimxboot.c +++ b/rbutil/mkimxboot/mkimxboot.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <stdio.h> | 21 | #include <stdio.h> |
22 | #include <stdlib.h> | 22 | #include <stdlib.h> |
23 | #include <stdarg.h> | 23 | #include <stdarg.h> |
24 | #include <string.h> | ||
25 | #include <ctype.h> | ||
24 | #include "mkimxboot.h" | 26 | #include "mkimxboot.h" |
25 | #include "sb.h" | 27 | #include "sb.h" |
26 | #include "dualboot.h" | 28 | #include "dualboot.h" |
@@ -279,10 +281,62 @@ static enum imx_error_t patch_std_zero_host_play(int jump_before, int model, | |||
279 | } | 281 | } |
280 | } | 282 | } |
281 | 283 | ||
284 | static enum imx_error_t parse_subversion(const char *s, const char *end, uint16_t *ver) | ||
285 | { | ||
286 | int len = (end == NULL) ? strlen(s) : end - s; | ||
287 | if(len > 4) | ||
288 | { | ||
289 | printf("[ERR] Bad subversion override '%s' (too long)\n", s); | ||
290 | return IMX_ERROR; | ||
291 | } | ||
292 | *ver = 0; | ||
293 | for(int i = 0; i < len; i++) | ||
294 | { | ||
295 | if(!isdigit(s[i])) | ||
296 | { | ||
297 | printf("[ERR] Bad subversion override '%s' (not a digit)\n", s); | ||
298 | return IMX_ERROR; | ||
299 | } | ||
300 | *ver = *ver << 4 | (s[i] - '0'); | ||
301 | } | ||
302 | return IMX_SUCCESS; | ||
303 | } | ||
304 | |||
305 | static enum imx_error_t parse_version(const char *s, struct sb_version_t *ver) | ||
306 | { | ||
307 | const char *dot1 = strchr(s, '.'); | ||
308 | if(dot1 == NULL) | ||
309 | { | ||
310 | printf("[ERR] Bad version override '%s' (missing dot)\n", s); | ||
311 | return IMX_ERROR; | ||
312 | } | ||
313 | const char *dot2 = strchr(dot1 + 1, '.'); | ||
314 | if(dot2 == NULL) | ||
315 | { | ||
316 | printf("[ERR] Bad version override '%s' (missing second dot)\n", s); | ||
317 | return IMX_ERROR; | ||
318 | } | ||
319 | enum imx_error_t ret = parse_subversion(s, dot1, &ver->major); | ||
320 | if(ret != IMX_SUCCESS) return ret; | ||
321 | ret = parse_subversion(dot1 + 1, dot2, &ver->minor); | ||
322 | if(ret != IMX_SUCCESS) return ret; | ||
323 | ret = parse_subversion(dot2 + 1, NULL, &ver->revision); | ||
324 | if(ret != IMX_SUCCESS) return ret; | ||
325 | return IMX_SUCCESS; | ||
326 | } | ||
327 | |||
282 | static enum imx_error_t patch_firmware(enum imx_model_t model, | 328 | static enum imx_error_t patch_firmware(enum imx_model_t model, |
283 | enum imx_firmware_variant_t variant, enum imx_output_type_t type, | 329 | enum imx_firmware_variant_t variant, enum imx_output_type_t type, |
284 | struct sb_file_t *sb_file, void *boot, size_t boot_sz) | 330 | struct sb_file_t *sb_file, void *boot, size_t boot_sz, |
331 | const char *force_version) | ||
285 | { | 332 | { |
333 | if(force_version) | ||
334 | { | ||
335 | enum imx_error_t err = parse_version(force_version, &sb_file->product_ver); | ||
336 | if(err != IMX_SUCCESS) return err; | ||
337 | err = parse_version(force_version, &sb_file->component_ver); | ||
338 | if(err != IMX_SUCCESS) return err; | ||
339 | } | ||
286 | switch(model) | 340 | switch(model) |
287 | { | 341 | { |
288 | case MODEL_FUZEPLUS: | 342 | case MODEL_FUZEPLUS: |
@@ -511,7 +565,8 @@ enum imx_error_t mkimxboot(const char *infile, const char *bootfile, | |||
511 | } | 565 | } |
512 | }while(0); | 566 | }while(0); |
513 | /* produce file */ | 567 | /* produce file */ |
514 | enum imx_error_t ret = patch_firmware(model, opt.fw_variant, opt.output, sb_file, boot + 8, boot_size - 8); | 568 | enum imx_error_t ret = patch_firmware(model, opt.fw_variant, opt.output, |
569 | sb_file, boot + 8, boot_size - 8, opt.force_version); | ||
515 | if(ret == IMX_SUCCESS) | 570 | if(ret == IMX_SUCCESS) |
516 | ret = sb_write_file(sb_file, outfile); | 571 | ret = sb_write_file(sb_file, outfile); |
517 | 572 | ||