summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2011-04-17 18:37:30 +0000
committerAmaury Pouly <pamaury@rockbox.org>2011-04-17 18:37:30 +0000
commite3fe3956f6c9c244ccbc57d1ddce7b2202b373f4 (patch)
treed7ce4f48d839157888f6f1ce7084e39473e60117 /utils
parent8bff25945bfceaeace132998aa98f6d1022aa3e9 (diff)
downloadrockbox-e3fe3956f6c9c244ccbc57d1ddce7b2202b373f4.tar.gz
rockbox-e3fe3956f6c9c244ccbc57d1ddce7b2202b373f4.zip
elftosb: more code toward sb production
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29741 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'utils')
-rw-r--r--utils/sbtools/elftosb.c110
1 files changed, 95 insertions, 15 deletions
diff --git a/utils/sbtools/elftosb.c b/utils/sbtools/elftosb.c
index c4887ab47a..275f21724d 100644
--- a/utils/sbtools/elftosb.c
+++ b/utils/sbtools/elftosb.c
@@ -80,6 +80,9 @@ static int convxdigit(char digit, byte *val)
80 80
81typedef byte (*key_array_t)[16]; 81typedef byte (*key_array_t)[16];
82 82
83int g_nr_keys;
84key_array_t g_key_array;
85
83static key_array_t read_keys(const char *key_file, int *num_keys) 86static key_array_t read_keys(const char *key_file, int *num_keys)
84{ 87{
85 int size; 88 int size;
@@ -499,12 +502,16 @@ struct sb_section_t
499 uint32_t identifier; 502 uint32_t identifier;
500 int nr_insts; 503 int nr_insts;
501 struct sb_inst_t *insts; 504 struct sb_inst_t *insts;
505 /* for production use */
506 uint32_t file_offset; /* in blocks */
502}; 507};
503 508
504struct sb_file_t 509struct sb_file_t
505{ 510{
506 int nr_sections; 511 int nr_sections;
507 struct sb_section_t *sections; 512 struct sb_section_t *sections;
513 /* for production use */
514 uint32_t image_size; /* in blocks */
508}; 515};
509 516
510static bool elf_read(void *user, uint32_t addr, void *buf, size_t count) 517static bool elf_read(void *user, uint32_t addr, void *buf, size_t count)
@@ -572,7 +579,7 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
572 579
573 if(cinst->type == CMD_LOAD) 580 if(cinst->type == CMD_LOAD)
574 sec->nr_insts += elf_get_nr_sections(elf); 581 sec->nr_insts += elf_get_nr_sections(elf);
575 else if(cinst->type == CMD_JUMP || cinst->type == CMD_LOAD) 582 else if(cinst->type == CMD_JUMP || cinst->type == CMD_CALL)
576 { 583 {
577 if(!elf_get_start_addr(elf, NULL)) 584 if(!elf_get_start_addr(elf, NULL))
578 bug("cannot jump/call '%s' because it has no starting point !", cinst->identifier); 585 bug("cannot jump/call '%s' because it has no starting point !", cinst->identifier);
@@ -602,9 +609,6 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
602 sec->insts[idx].addr = esec->addr; 609 sec->insts[idx].addr = esec->addr;
603 sec->insts[idx].size = esec->size; 610 sec->insts[idx].size = esec->size;
604 sec->insts[idx++].data = esec->section; 611 sec->insts[idx++].data = esec->section;
605 if(g_debug)
606 printf("LOAD | addr=0x%08x | len=0x%08x | crc=0x%08x\n",
607 esec->addr, esec->size, 0);
608 } 612 }
609 else if(esec->type == EST_FILL) 613 else if(esec->type == EST_FILL)
610 { 614 {
@@ -612,21 +616,14 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
612 sec->insts[idx].addr = esec->addr; 616 sec->insts[idx].addr = esec->addr;
613 sec->insts[idx].size = esec->size; 617 sec->insts[idx].size = esec->size;
614 sec->insts[idx++].pattern = esec->pattern; 618 sec->insts[idx++].pattern = esec->pattern;
615 if(g_debug)
616 printf("FILL | addr=0x%08x | len=0x%08x | pattern=0x%08x\n",
617 esec->addr, esec->size, esec->pattern);
618 } 619 }
619 esec = esec->next; 620 esec = esec->next;
620 } 621 }
621 } 622 }
622 else if(cinst->type == CMD_JUMP || cinst->type == CMD_LOAD) 623 else if(cinst->type == CMD_JUMP || cinst->type == CMD_CALL)
623 { 624 {
624 sec->insts[idx].inst = (cinst->type == CMD_JUMP) ? SB_INST_JUMP : SB_INST_CALL; 625 sec->insts[idx].inst = (cinst->type == CMD_JUMP) ? SB_INST_JUMP : SB_INST_CALL;
625 sec->insts[idx++].addr = elf->start_addr; 626 sec->insts[idx++].addr = elf->start_addr;
626 if(g_debug)
627 printf("%s | addr=0x%08x | arg=0x%08x\n",
628 (cinst->type == CMD_JUMP) ? "JUMP" : "CALL",
629 elf->start_addr, 0);
630 } 627 }
631 628
632 cinst = cinst->next; 629 cinst = cinst->next;
@@ -640,6 +637,82 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
640 * Sb file production 637 * Sb file production
641 */ 638 */
642 639
640static void compute_sb_offsets(struct sb_file_t *sb)
641{
642 sb->image_size = 0;
643 /* sb header */
644 sb->image_size += sizeof(struct sb_header_t) / BLOCK_SIZE;
645 /* sections headers */
646 sb->image_size += sb->nr_sections * sizeof(struct sb_section_header_t) / BLOCK_SIZE;
647 /* key dictionary */
648 sb->image_size += g_nr_keys * sizeof(struct sb_key_dictionary_entry_t) / BLOCK_SIZE;
649 /* sections */
650 for(int i = 0; i < sb->nr_sections; i++)
651 {
652 /* each section has a preliminary TAG command */
653 sb->image_size += sizeof(struct sb_instruction_tag_t) / BLOCK_SIZE;
654
655 struct sb_section_t *sec = &sb->sections[i];
656 sec->file_offset = sb->image_size;
657 for(int j = 0; j < sec->nr_insts; j++)
658 {
659 struct sb_inst_t *inst = &sec->insts[j];
660 if(inst->inst == SB_INST_CALL || inst->inst == SB_INST_JUMP)
661 {
662 if(g_debug)
663 printf("%s | addr=0x%08x | arg=0x%08x\n",
664 inst->inst == SB_INST_CALL ? "CALL" : "JUMP", inst->addr, 0);
665 sb->image_size += sizeof(struct sb_instruction_call_t) / BLOCK_SIZE;
666 }
667 else if(inst->inst == SB_INST_FILL)
668 {
669 if(g_debug)
670 printf("FILL | addr=0x%08x | len=0x%08x | pattern=0x%08x\n",
671 inst->addr, inst->size, inst->pattern);
672 sb->image_size += sizeof(struct sb_instruction_fill_t) / BLOCK_SIZE;
673 }
674 else if(inst->inst == SB_INST_LOAD)
675 {
676 if(g_debug)
677 printf("LOAD | addr=0x%08x | len=0x%08x\n", inst->addr, inst->size);
678 /* load header */
679 sb->image_size += sizeof(struct sb_instruction_load_t) / BLOCK_SIZE;
680 /* data + alignment */
681 sb->image_size += (inst->size + BLOCK_SIZE - 1) / BLOCK_SIZE;
682 }
683 }
684 }
685 /* final signature */
686 sb->image_size += 2;
687}
688
689static void produce_sb_header(struct sb_file_t *sb, struct sb_header_t *sb_hdr)
690{
691 sb_hdr->signature[0] = 'S';
692 sb_hdr->signature[1] = 'T';
693 sb_hdr->signature[2] = 'M';
694 sb_hdr->signature[3] = 'P';
695 sb_hdr->major_ver = IMAGE_MAJOR_VERSION;
696 sb_hdr->minor_ver = IMAGE_MINOR_VERSION;
697 sb_hdr->flags = 0;
698 sb_hdr->image_size = sb->image_size;
699}
700
701static void produce_sb_file(struct sb_file_t *sb, const char *filename)
702{
703 int fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT,
704 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
705 if(fd < 0)
706 bugp("cannot open output file");
707
708 compute_sb_offsets(sb);
709
710 struct sb_header_t sb_hdr;
711 produce_sb_header(sb, &sb_hdr);
712
713 close(fd);
714}
715
643#define ROUND_UP(val, round) ((((val) + (round) - 1) / (round)) * (round)) 716#define ROUND_UP(val, round) ((((val) + (round) - 1) / (round)) * (round))
644 717
645static uint8_t instruction_checksum(struct sb_instruction_header_t *hdr) 718static uint8_t instruction_checksum(struct sb_instruction_header_t *hdr)
@@ -654,12 +727,19 @@ static uint8_t instruction_checksum(struct sb_instruction_header_t *hdr)
654int main(int argc, const char **argv) 727int main(int argc, const char **argv)
655{ 728{
656 if(argc != 4) 729 if(argc != 4)
657 bug("Usage: %s <cmd file> <key file> <out file>\n",*argv); 730 {
731 printf("Usage: %s <cmd file> <key file> <out file>\n",*argv);
732 printf("To enable debug mode, set environement variable SB_DEBUG to YES\n");
733 return 1;
734 }
735
736 if(getenv("SB_DEBUG") != NULL && strcmp(getenv("SB_DEBUG"), "YES") == 0)
737 g_debug = true;
658 738
659 int nr_keys; 739 g_key_array = read_keys(argv[2], &g_nr_keys);
660 key_array_t key_array = read_keys(argv[2], &nr_keys);
661 struct cmd_file_t *cmd_file = read_command_file(argv[1]); 740 struct cmd_file_t *cmd_file = read_command_file(argv[1]);
662 struct sb_file_t *sb_file = apply_cmd_file(cmd_file); 741 struct sb_file_t *sb_file = apply_cmd_file(cmd_file);
742 produce_sb_file(sb_file, argv[3]);
663 743
664 return 0; 744 return 0;
665} 745}