summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/sbtools/sb.c12
-rw-r--r--utils/sbtools/sb.h1
-rw-r--r--utils/sbtools/sbtoelf.c82
3 files changed, 80 insertions, 15 deletions
diff --git a/utils/sbtools/sb.c b/utils/sbtools/sb.c
index 99f9536..d620c00 100644
--- a/utils/sbtools/sb.c
+++ b/utils/sbtools/sb.c
@@ -571,7 +571,7 @@ static struct sb_section_t *read_section(bool data_sec, uint32_t id, byte *buf,
#undef printf
}
-static void fill_section_name(char name[5], uint32_t identifier)
+void sb_fill_section_name(char name[5], uint32_t identifier)
{
name[0] = (identifier >> 24) & 0xff;
name[1] = (identifier >> 16) & 0xff;
@@ -773,7 +773,7 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
struct crypto_key_t k;
char *env = getenv("SB_REAL_KEY");
if(!parse_key(&env, &k) || *env)
- bug("Invalid SB_REAL_KEY");
+ bug("Invalid SB_REAL_KEY\n");
memcpy(real_key, k.u.key, 16);
}
@@ -801,7 +801,7 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
struct sb_section_header_t *sec_hdr = (struct sb_section_header_t *)&buf[ofs];
char name[5];
- fill_section_name(name, sec_hdr->identifier);
+ sb_fill_section_name(name, sec_hdr->identifier);
int pos = sec_hdr->offset * BLOCK_SIZE;
int size = sec_hdr->size * BLOCK_SIZE;
int data_sec = !(sec_hdr->flags & SECTION_BOOTABLE);
@@ -889,7 +889,7 @@ struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
offset += sizeof(struct sb_instruction_tag_t);
char name[5];
- fill_section_name(name, tag->identifier);
+ sb_fill_section_name(name, tag->identifier);
int pos = offset;
int size = tag->len * BLOCK_SIZE;
int data_sec = !(tag->flags & SECTION_BOOTABLE);
@@ -1004,7 +1004,7 @@ void sb_dump(struct sb_file_t *file, void *u, sb_color_printf cprintf)
printf(TREE, "+-");
printf(HEADER, "First Boot Section ID: ");
char name[5];
- fill_section_name(name, file->first_boot_sec_id);
+ sb_fill_section_name(name, file->first_boot_sec_id);
printf(TEXT, "%08x (%s)\n", file->first_boot_sec_id, name);
if(file->real_key)
@@ -1035,7 +1035,7 @@ void sb_dump(struct sb_file_t *file, void *u, sb_color_printf cprintf)
printf(HEADER, "Section\n");
printf(TREE,"| +-");
printf(HEADER, "Identifier: ");
- fill_section_name(name, sec->identifier);
+ sb_fill_section_name(name, sec->identifier);
printf(TEXT, "%08x (%s)\n", sec->identifier, name);
printf(TREE, "| +-");
printf(HEADER, "Type: ");
diff --git a/utils/sbtools/sb.h b/utils/sbtools/sb.h
index 548b3ef..39bb8ce 100644
--- a/utils/sbtools/sb.h
+++ b/utils/sbtools/sb.h
@@ -213,6 +213,7 @@ typedef void (*sb_color_printf)(void *u, bool err, color_t c, const char *f, ...
struct sb_file_t *sb_read_file(const char *filename, bool raw_mode, void *u,
sb_color_printf printf);
+void sb_fill_section_name(char name[5], uint32_t identifier);
void sb_dump(struct sb_file_t *file, void *u, sb_color_printf printf);
#endif /* __SB_H__ */
diff --git a/utils/sbtools/sbtoelf.c b/utils/sbtools/sbtoelf.c
index 0199ffb..179f912 100644
--- a/utils/sbtools/sbtoelf.c
+++ b/utils/sbtools/sbtoelf.c
@@ -76,12 +76,14 @@ static void elf_write(void *user, uint32_t addr, const void *buf, size_t count)
fwrite(buf, count, 1, f);
}
-static void extract_elf_section(struct elf_params_t *elf, int count, const char *prefix,
- const char *indent)
+static void extract_elf_section(struct elf_params_t *elf, int count, uint32_t id)
{
- char *filename = xmalloc(strlen(prefix) + 32);
- sprintf(filename, "%s.%d.elf", prefix, count);
- printf("%swrite %s\n", indent, filename);
+ char name[5];
+ char *filename = xmalloc(strlen(g_out_prefix) + 32);
+ sb_fill_section_name(name, id);
+ sprintf(filename, "%s%s.%d.elf", g_out_prefix, name, count);
+ if(g_debug)
+ printf("Write boot section %s to %s\n", name, filename);
FILE *fd = fopen(filename, "wb");
free(filename);
@@ -92,12 +94,74 @@ static void extract_elf_section(struct elf_params_t *elf, int count, const char
fclose(fd);
}
+static void extract_sb_section(struct sb_section_t *sec)
+{
+ if(sec->is_data)
+ {
+ char sec_name[5];
+ char *filename = xmalloc(strlen(g_out_prefix) + 32);
+ sb_fill_section_name(sec_name, sec->identifier);
+ sprintf(filename, "%s%s.bin", g_out_prefix, sec_name);
+ FILE *fd = fopen(filename, "wb");
+ if(fd == NULL)
+ bugp("Cannot open %s for writing\n", filename);
+ if(g_debug)
+ printf("Write data section %s to %s\n", sec_name, filename);
+ free(filename);
+
+ for(int j = 0; j < sec->nr_insts; j++)
+ {
+ assert(sec->insts[j].inst == SB_INST_DATA);
+ fwrite(sec->insts[j].data, sec->insts[j].size, 1, fd);
+ }
+ fclose(fd);
+ }
+
+ int elf_count = 0;
+ struct elf_params_t elf;
+ elf_init(&elf);
+
+ for(int i = 0; i < sec->nr_insts; i++)
+ {
+ struct sb_inst_t *inst = &sec->insts[i];
+ switch(inst->inst)
+ {
+ case SB_INST_LOAD:
+ elf_add_load_section(&elf, inst->addr, inst->size, inst->data);
+ break;
+ case SB_INST_FILL:
+ elf_add_fill_section(&elf, inst->addr, inst->size, inst->pattern);
+ break;
+ case SB_INST_CALL:
+ case SB_INST_JUMP:
+ elf_set_start_addr(&elf, inst->addr);
+ extract_elf_section(&elf, elf_count++, sec->identifier);
+ elf_release(&elf);
+ elf_init(&elf);
+ break;
+ default:
+ /* ignore mode and nop */
+ break;
+ }
+ }
+
+ if(!elf_is_empty(&elf))
+ extract_elf_section(&elf, elf_count, sec->identifier);
+ elf_release(&elf);
+}
+
+static void extract_sb_file(struct sb_file_t *file)
+{
+ for(int i = 0; i < file->nr_sections; i++)
+ extract_sb_section(&file->sections[i]);
+}
+
static void usage(void)
{
printf("Usage: sbtoelf [options] sb-file\n");
printf("Options:\n");
printf(" -?/--help\tDisplay this message\n");
- printf(" -o <file>\tSet output prefix\n");
+ printf(" -o <prefix>\tEnable output and set prefix\n");
printf(" -d/--debug\tEnable debug output*\n");
printf(" -k <file>\tAdd key file\n");
printf(" -z\t\tAdd zero key\n");
@@ -196,9 +260,6 @@ int main(int argc, char **argv)
}
}
- if(g_out_prefix == NULL)
- g_out_prefix = "";
-
if(argc - optind != 1)
{
usage();
@@ -208,6 +269,9 @@ int main(int argc, char **argv)
const char *sb_filename = argv[optind];
struct sb_file_t *file = sb_read_file(sb_filename, raw_mode, NULL, sb_printf);
+ color(OFF);
+ if(g_out_prefix)
+ extract_sb_file(file);
if(g_debug)
{
color(GREY);