diff options
Diffstat (limited to 'utils/sbtools')
-rw-r--r-- | utils/sbtools/elftosb.c | 115 | ||||
-rw-r--r-- | utils/sbtools/sb.h | 1 | ||||
-rw-r--r-- | utils/sbtools/sbtoelf.c | 25 |
3 files changed, 126 insertions, 15 deletions
diff --git a/utils/sbtools/elftosb.c b/utils/sbtools/elftosb.c index 601321d9c0..78d2e80bf9 100644 --- a/utils/sbtools/elftosb.c +++ b/utils/sbtools/elftosb.c | |||
@@ -221,6 +221,8 @@ struct cmd_section_t | |||
221 | 221 | ||
222 | struct cmd_file_t | 222 | struct cmd_file_t |
223 | { | 223 | { |
224 | struct sb_version_t product_ver; | ||
225 | struct sb_version_t component_ver; | ||
224 | struct cmd_source_t *source_list; | 226 | struct cmd_source_t *source_list; |
225 | struct cmd_section_t *section_list; | 227 | struct cmd_section_t *section_list; |
226 | }; | 228 | }; |
@@ -449,6 +451,50 @@ static struct cmd_source_t *find_source_by_id(struct cmd_file_t *cmd_file, const | |||
449 | return NULL; | 451 | return NULL; |
450 | } | 452 | } |
451 | 453 | ||
454 | static void generate_default_version(struct sb_version_t *ver) | ||
455 | { | ||
456 | ver->major = 0x999; | ||
457 | ver->minor = 0x999; | ||
458 | ver->revision = 0x999; | ||
459 | } | ||
460 | |||
461 | static uint16_t parse_sb_subversion(char *str) | ||
462 | { | ||
463 | int len = strlen(str); | ||
464 | uint16_t n = 0; | ||
465 | if(len == 0 || len > 4) | ||
466 | bug("invalid command file: invalid version string"); | ||
467 | for(int i = 0; i < len; i++) | ||
468 | { | ||
469 | if(!isdigit(str[i])) | ||
470 | bug("invalid command file: invalid version string"); | ||
471 | n = n << 4 | (str[i] - '0'); | ||
472 | } | ||
473 | return n; | ||
474 | } | ||
475 | |||
476 | static void parse_sb_version(struct sb_version_t *ver, char *str) | ||
477 | { | ||
478 | int len = strlen(str); | ||
479 | int cnt = 0; | ||
480 | int pos[2]; | ||
481 | |||
482 | for(int i = 0; i < len; i++) | ||
483 | { | ||
484 | if(str[i] != '.') | ||
485 | continue; | ||
486 | if(cnt == 2) | ||
487 | bug("invalid command file: invalid version string"); | ||
488 | pos[cnt++] = i + 1; | ||
489 | str[i] = 0; | ||
490 | } | ||
491 | if(cnt != 2) | ||
492 | bug("invalid command file: invalid version string"); | ||
493 | ver->major = parse_sb_subversion(str); | ||
494 | ver->minor = parse_sb_subversion(str + pos[0]); | ||
495 | ver->revision = parse_sb_subversion(str + pos[1]); | ||
496 | } | ||
497 | |||
452 | static struct cmd_file_t *read_command_file(const char *file) | 498 | static struct cmd_file_t *read_command_file(const char *file) |
453 | { | 499 | { |
454 | int size; | 500 | int size; |
@@ -469,12 +515,52 @@ static struct cmd_file_t *read_command_file(const char *file) | |||
469 | struct cmd_file_t *cmd_file = xmalloc(sizeof(struct cmd_file_t)); | 515 | struct cmd_file_t *cmd_file = xmalloc(sizeof(struct cmd_file_t)); |
470 | memset(cmd_file, 0, sizeof(struct cmd_file_t)); | 516 | memset(cmd_file, 0, sizeof(struct cmd_file_t)); |
471 | 517 | ||
518 | generate_default_version(&cmd_file->product_ver); | ||
519 | generate_default_version(&cmd_file->component_ver); | ||
520 | |||
472 | struct lexem_t lexem; | 521 | struct lexem_t lexem; |
473 | char *p = buf; | 522 | char *p = buf; |
474 | char *end = buf + size; | 523 | char *end = buf + size; |
475 | #define next() next_lexem(&p, end, &lexem) | 524 | #define next() next_lexem(&p, end, &lexem) |
476 | /* sources */ | 525 | /* init lexer */ |
477 | next(); | 526 | next(); |
527 | /* options ? */ | ||
528 | if(lexem.type == LEX_IDENTIFIER && !strcmp(lexem.str, "options")) | ||
529 | { | ||
530 | next(); | ||
531 | if(lexem.type != LEX_LBRACE) | ||
532 | bug("invalid command file: '{' expected after 'options'\n"); | ||
533 | |||
534 | while(true) | ||
535 | { | ||
536 | next(); | ||
537 | if(lexem.type == LEX_RBRACE) | ||
538 | break; | ||
539 | if(lexem.type != LEX_IDENTIFIER) | ||
540 | bug("invalid command file: identifier expected in options\n"); | ||
541 | char *opt = lexem.str; | ||
542 | next(); | ||
543 | if(lexem.type != LEX_EQUAL) | ||
544 | bug("invalid command file: '=' expected after identifier\n"); | ||
545 | next(); | ||
546 | if(!strcmp(opt, "productVersion") || !strcmp(opt, "componentVersion")) | ||
547 | { | ||
548 | if(lexem.type != LEX_STRING) | ||
549 | bug("invalid command file: string expected after '='\n"); | ||
550 | if(!strcmp(opt, "productVersion")) | ||
551 | parse_sb_version(&cmd_file->product_ver, lexem.str); | ||
552 | else | ||
553 | parse_sb_version(&cmd_file->component_ver, lexem.str); | ||
554 | } | ||
555 | else | ||
556 | bug("invalid command file: unknown option '%s'\n", opt); | ||
557 | next(); | ||
558 | if(lexem.type != LEX_SEMICOLON) | ||
559 | bug("invalid command file: ';' expected after string\n"); | ||
560 | } | ||
561 | next(); | ||
562 | } | ||
563 | /* sources */ | ||
478 | if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "sources") != 0) | 564 | if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "sources") != 0) |
479 | bug("invalid command file: 'sources' expected\n"); | 565 | bug("invalid command file: 'sources' expected\n"); |
480 | next(); | 566 | next(); |
@@ -686,6 +772,8 @@ struct sb_file_t | |||
686 | { | 772 | { |
687 | int nr_sections; | 773 | int nr_sections; |
688 | struct sb_section_t *sections; | 774 | struct sb_section_t *sections; |
775 | struct sb_version_t product_ver; | ||
776 | struct sb_version_t component_ver; | ||
689 | /* for production use */ | 777 | /* for production use */ |
690 | uint32_t image_size; /* in blocks */ | 778 | uint32_t image_size; /* in blocks */ |
691 | }; | 779 | }; |
@@ -759,6 +847,9 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file) | |||
759 | { | 847 | { |
760 | struct sb_file_t *sb = xmalloc(sizeof(struct sb_file_t)); | 848 | struct sb_file_t *sb = xmalloc(sizeof(struct sb_file_t)); |
761 | memset(sb, 0, sizeof(struct sb_file_t)); | 849 | memset(sb, 0, sizeof(struct sb_file_t)); |
850 | |||
851 | sb->product_ver = cmd_file->product_ver; | ||
852 | sb->component_ver = cmd_file->component_ver; | ||
762 | 853 | ||
763 | if(g_debug) | 854 | if(g_debug) |
764 | printf("Applying command file...\n"); | 855 | printf("Applying command file...\n"); |
@@ -972,14 +1063,16 @@ static uint64_t generate_timestamp() | |||
972 | return (uint64_t)t * 1000000L; | 1063 | return (uint64_t)t * 1000000L; |
973 | } | 1064 | } |
974 | 1065 | ||
975 | void generate_version(struct sb_version_t *ver) | 1066 | static uint16_t swap16(uint16_t t) |
976 | { | 1067 | { |
977 | ver->major = 0x999; | 1068 | return (t << 8) | (t >> 8); |
978 | ver->pad0 = 0; | 1069 | } |
979 | ver->minor = 0x999; | 1070 | |
980 | ver->pad1 = 0; | 1071 | static void fix_version(struct sb_version_t *ver) |
981 | ver->revision = 0x999; | 1072 | { |
982 | ver->pad2 = 0; | 1073 | ver->major = swap16(ver->major); |
1074 | ver->minor = swap16(ver->minor); | ||
1075 | ver->revision = swap16(ver->revision); | ||
983 | } | 1076 | } |
984 | 1077 | ||
985 | static void produce_sb_header(struct sb_file_t *sb, struct sb_header_t *sb_hdr) | 1078 | static void produce_sb_header(struct sb_file_t *sb, struct sb_header_t *sb_hdr) |
@@ -1006,8 +1099,10 @@ static void produce_sb_header(struct sb_file_t *sb, struct sb_header_t *sb_hdr) | |||
1006 | generate_random_data(sb_hdr->rand_pad0, sizeof(sb_hdr->rand_pad0)); | 1099 | generate_random_data(sb_hdr->rand_pad0, sizeof(sb_hdr->rand_pad0)); |
1007 | generate_random_data(sb_hdr->rand_pad1, sizeof(sb_hdr->rand_pad1)); | 1100 | generate_random_data(sb_hdr->rand_pad1, sizeof(sb_hdr->rand_pad1)); |
1008 | sb_hdr->timestamp = generate_timestamp(); | 1101 | sb_hdr->timestamp = generate_timestamp(); |
1009 | generate_version(&sb_hdr->product_ver); | 1102 | sb_hdr->product_ver = sb->product_ver; |
1010 | generate_version(&sb_hdr->component_ver); | 1103 | fix_version(&sb_hdr->product_ver); |
1104 | sb_hdr->component_ver = sb->component_ver; | ||
1105 | fix_version(&sb_hdr->component_ver); | ||
1011 | sb_hdr->drive_tag = 0; | 1106 | sb_hdr->drive_tag = 0; |
1012 | 1107 | ||
1013 | sha_1_init(&sha_1_params); | 1108 | sha_1_init(&sha_1_params); |
diff --git a/utils/sbtools/sb.h b/utils/sbtools/sb.h index 9ffdba9191..a1482691ce 100644 --- a/utils/sbtools/sb.h +++ b/utils/sbtools/sb.h | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #define BLOCK_SIZE 16 | 24 | #define BLOCK_SIZE 16 |
25 | 25 | ||
26 | /* All fields are in big-endian BCD */ | ||
26 | struct sb_version_t | 27 | struct sb_version_t |
27 | { | 28 | { |
28 | uint16_t major; | 29 | uint16_t major; |
diff --git a/utils/sbtools/sbtoelf.c b/utils/sbtools/sbtoelf.c index f421f83848..d729357a56 100644 --- a/utils/sbtools/sbtoelf.c +++ b/utils/sbtools/sbtoelf.c | |||
@@ -339,7 +339,7 @@ static void extract_section(int data_sec, char name[5], byte *buf, int size, con | |||
339 | elf_release(&elf); | 339 | elf_release(&elf); |
340 | } | 340 | } |
341 | 341 | ||
342 | void fill_section_name(char name[5], uint32_t identifier) | 342 | static void fill_section_name(char name[5], uint32_t identifier) |
343 | { | 343 | { |
344 | name[0] = (identifier >> 24) & 0xff; | 344 | name[0] = (identifier >> 24) & 0xff; |
345 | name[1] = (identifier >> 16) & 0xff; | 345 | name[1] = (identifier >> 16) & 0xff; |
@@ -351,6 +351,18 @@ void fill_section_name(char name[5], uint32_t identifier) | |||
351 | name[4] = 0; | 351 | name[4] = 0; |
352 | } | 352 | } |
353 | 353 | ||
354 | static uint16_t swap16(uint16_t t) | ||
355 | { | ||
356 | return (t << 8) | (t >> 8); | ||
357 | } | ||
358 | |||
359 | static void fix_version(struct sb_version_t *ver) | ||
360 | { | ||
361 | ver->major = swap16(ver->major); | ||
362 | ver->minor = swap16(ver->minor); | ||
363 | ver->revision = swap16(ver->revision); | ||
364 | } | ||
365 | |||
354 | static void extract(unsigned long filesize) | 366 | static void extract(unsigned long filesize) |
355 | { | 367 | { |
356 | struct sha_1_params_t sha_1_params; | 368 | struct sha_1_params_t sha_1_params; |
@@ -433,16 +445,19 @@ static void extract(unsigned long filesize) | |||
433 | color(YELLOW); | 445 | color(YELLOW); |
434 | printf("%s", asctime(time)); | 446 | printf("%s", asctime(time)); |
435 | 447 | ||
448 | struct sb_version_t product_ver = sb_header->product_ver; | ||
449 | fix_version(&product_ver); | ||
450 | struct sb_version_t component_ver = sb_header->component_ver; | ||
451 | fix_version(&component_ver); | ||
452 | |||
436 | color(GREEN); | 453 | color(GREEN); |
437 | printf(" Product version = "); | 454 | printf(" Product version = "); |
438 | color(YELLOW); | 455 | color(YELLOW); |
439 | printf("%X.%X.%X\n", sb_header->product_ver.major, | 456 | printf("%X.%X.%X\n", product_ver.major, product_ver.minor, product_ver.revision); |
440 | sb_header->product_ver.minor, sb_header->product_ver.revision); | ||
441 | color(GREEN); | 457 | color(GREEN); |
442 | printf(" Component version = "); | 458 | printf(" Component version = "); |
443 | color(YELLOW); | 459 | color(YELLOW); |
444 | printf("%X.%X.%X\n", sb_header->component_ver.major, | 460 | printf("%X.%X.%X\n", component_ver.major, component_ver.minor, component_ver.revision); |
445 | sb_header->component_ver.minor, sb_header->component_ver.revision); | ||
446 | 461 | ||
447 | color(GREEN); | 462 | color(GREEN); |
448 | printf(" Drive tag = "); | 463 | printf(" Drive tag = "); |