Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
*.dis
*.lst
.*
*.rm
*.met
*.uns
*.ro
*.debug

Makefile
Makefile.in
Expand Down
4 changes: 4 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,8 @@ AC_CONFIG_FILES([
src/library/include/Makefile
src/library/include/platform/Makefile
src/lib/Makefile
src/modules/Makefile
src/modules/template/Makefile
src/platform/Makefile
src/platform/baytrail/Makefile
src/platform/baytrail/include/Makefile
Expand All @@ -385,6 +387,8 @@ AC_CONFIG_FILES([
src/platform/cannonlake/include/platform/Makefile
src/platform/cannonlake/include/xtensa/Makefile
src/platform/cannonlake/include/xtensa/config/Makefile
src/test/Makefile
src/test/linker/Makefile
])
AC_OUTPUT

Expand Down
72 changes: 64 additions & 8 deletions rimage/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,42 @@ static void elf_module_size(struct image *image, struct module *module,
}
}

static void elf_module_size_reloc(struct image *image, struct module *module,
Elf32_Shdr *section, int index)
{
switch (section->sh_type) {
case SHT_PROGBITS:
/* text or data */
if (section->sh_flags & SHF_EXECINSTR) {
/* text */
module->text_start = 0;
module->text_end += section->sh_size;

fprintf(stdout, "\tTEXT\t");
} else {
/* initialized data, also calc the writable sections */
module->data_start = 0;
module->data_end += section->sh_size;

fprintf(stdout, "\tDATA\t");
}
break;
case SHT_NOBITS:
/* bss */
if (index == module->bss_index) {
/* updated the .bss segment */
module->bss_start = section->sh_addr;
module->bss_end = section->sh_addr + section->sh_size;
fprintf(stdout, "\tBSS\t");
} else {
fprintf(stdout, "\tHEAP\t");
}
break;
default:
break;
}
}

static void elf_module_limits(struct image *image, struct module *module)
{
Elf32_Shdr *section;
Expand All @@ -302,22 +338,29 @@ static void elf_module_limits(struct image *image, struct module *module)

section = &module->section[i];

/* only check valid sections */
if (!(section->sh_flags & valid))
continue;
/* module bss can sometimes be missed */
if (i != module->bss_index) {

if (section->sh_size == 0)
continue;
/* only check valid sections */
if (!(section->sh_flags & valid))
continue;

if (elf_is_rom(image, section))
continue;
if (section->sh_size == 0)
continue;

if (elf_is_rom(image, section))
continue;
}

fprintf(stdout, "\t%d\t0x%8.8x\t0x%8.8x\t%d", i,
section->sh_addr, section->sh_addr + section->sh_size,
section->sh_size);

/* text or data section */
elf_module_size(image, module, section, i);
if (image->reloc)
elf_module_size_reloc(image, module, section, i);
else
elf_module_size(image, module, section, i);

/* section name */
fprintf(stdout, "%s\n", module->strings + section->sh_name);
Expand Down Expand Up @@ -388,6 +431,10 @@ int elf_validate_modules(struct image *image)
uint32_t valid = (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR);
int i, j, ret;

/* relocatable modules have no physical addresses until runtime */
if (image->reloc)
return 0;

/* for each module */
for (i = 0; i < image->num_modules; i++) {
module = &image->module[i];
Expand Down Expand Up @@ -484,6 +531,15 @@ int elf_parse_module(struct image *image, int module_index, const char *name)
}
module->elf_file = name;

/* get file size */
ret = fseek(module->fd, 0, SEEK_END);
if (ret < 0)
goto hdr_err;
module->file_size = ftell(module->fd);
ret = fseek(module->fd, 0, SEEK_SET);
if (ret < 0)
goto hdr_err;

/* read in elf header */
ret = elf_read_hdr(image, module);
if (ret < 0)
Expand Down
97 changes: 96 additions & 1 deletion rimage/file_simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,98 @@ static int simple_write_module(struct image *image, struct module *module)
return 0;
}

static int write_block_reloc(struct image *image, struct module *module)
{
struct snd_sof_blk_hdr block;
size_t count;
void *buffer;
int ret;

block.size = module->file_size;
block.type = SOF_BLK_DATA;
block.offset = 0;

/* write header */
count = fwrite(&block, sizeof(block), 1, image->out_fd);
if (count != 1)
return -errno;

/* alloc data data */
buffer = calloc(1, module->file_size);
if (buffer == NULL)
return -ENOMEM;

/* read in section data */
ret = fseek(module->fd, 0, SEEK_SET);
if (ret < 0) {
fprintf(stderr, "error: can't seek to section %d\n", ret);
goto out;
}
count = fread(buffer, 1, module->file_size, module->fd);
if (count != module->file_size) {
fprintf(stderr, "error: can't read section %d\n", -errno);
ret = -errno;
goto out;
}

/* write out section data */
count = fwrite(buffer, 1, module->file_size, image->out_fd);
if (count != module->file_size) {
fprintf(stderr, "error: can't write section %d\n", -errno);
ret = -errno;
goto out;
}

fprintf(stdout, "\t%d\t0x%8.8x\t0x%8.8x\t0x%8.8lx\t%s\n", block_idx++,
0, module->file_size, ftell(image->out_fd),
block.type == SOF_BLK_TEXT ? "TEXT" : "DATA");

out:
free(buffer);
return ret;
}

static int simple_write_module_reloc(struct image *image, struct module *module)
{
struct snd_sof_mod_hdr hdr;
size_t count;
int i, err;

hdr.num_blocks = 1;
hdr.size = module->text_size + module->data_size;
hdr.type = SOF_FW_BASE; // module

count = fwrite(&hdr, sizeof(hdr), 1, image->out_fd);
if (count != 1) {
fprintf(stderr, "error: failed to write section header %d\n",
-errno);
return -errno;
}

fprintf(stdout, "\n\tTotals\tStart\t\tEnd\t\tSize");

fprintf(stdout, "\n\tTEXT\t0x%8.8x\t0x%8.8x\t0x%x\n",
module->text_start, module->text_end,
module->text_end - module->text_start);
fprintf(stdout, "\tDATA\t0x%8.8x\t0x%8.8x\t0x%x\n",
module->data_start, module->data_end,
module->data_end - module->data_start);
fprintf(stdout, "\tBSS\t0x%8.8x\t0x%8.8x\t0x%x\n\n ",
module->bss_start, module->bss_end,
module->bss_end - module->bss_start);

fprintf(stdout, "\tNo\tAddress\t\tSize\t\tFile\t\tType\n");

err = write_block_reloc(image, module);
if (err < 0) {
fprintf(stderr, "error: failed to write section #%d\n", i);
return err;
}

fprintf(stdout, "\n");
return 0;
}

/* used by others */
static int simple_write_firmware(struct image *image)
{
Expand Down Expand Up @@ -235,7 +327,10 @@ static int simple_write_firmware(struct image *image)

fprintf(stdout, "writing module %d %s\n", i, module->elf_file);

ret = simple_write_module(image, module);
if (image->reloc)
ret = simple_write_module_reloc(image, module);
else
ret = simple_write_module(image, module);
if (ret < 0) {
fprintf(stderr, "error: failed to write module %d\n",
i);
Expand Down
99 changes: 97 additions & 2 deletions rimage/manifest.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,6 @@ static int man_module_create(struct image *image, struct module *module,

fprintf(stdout, "\tNo\tAddress\t\tSize\t\tFile\tType\n");

/* validate segments */
if (man_module_validate(man_module) < 0)
return -EINVAL;

Expand Down Expand Up @@ -445,6 +444,98 @@ static int man_module_create(struct image *image, struct module *module,
return 0;
}

static int man_module_create_reloc(struct image *image, struct module *module,
struct sof_man_module *man_module)
{
/* create module and segments */
int err;
unsigned int pages;
void *buffer = image->fw_image + module->foffset;
size_t count;

image->image_end = 0;

err = man_get_module_manifest(image, module, man_module);
if (err < 0)
return err;

/* stack size ??? convert sizes to PAGES */
man_module->instance_bss_size = 1;

/* max number of instances of this module ?? */
man_module->instance_max_count = 1;

fprintf(stdout, "\n\tTotals\tStart\t\tEnd\t\tSize");

fprintf(stdout, "\n\tTEXT\t0x%8.8x\t0x%8.8x\t0x%x\n",
module->text_start, module->text_end,
module->text_end - module->text_start);
fprintf(stdout, "\tDATA\t0x%8.8x\t0x%8.8x\t0x%x\n",
module->data_start, module->data_end,
module->data_end - module->data_start);
fprintf(stdout, "\tBSS\t0x%8.8x\t0x%8.8x\t0x%x\n\n ",
module->bss_start, module->bss_end,
module->bss_end - module->bss_start);

/* main module */
/* text section is first */
man_module->segment[SOF_MAN_SEGMENT_TEXT].file_offset =
module->foffset;
man_module->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr = 0;
man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length = 0;

/* data section */
man_module->segment[SOF_MAN_SEGMENT_RODATA].v_base_addr = 0;
man_module->segment[SOF_MAN_SEGMENT_RODATA].file_offset =
module->foffset;
pages = module->data_file_size / MAN_PAGE_SIZE;
if (module->data_file_size % MAN_PAGE_SIZE)
pages += 1;

man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length = pages;

/* bss is last */
man_module->segment[SOF_MAN_SEGMENT_BSS].file_offset = 0;
man_module->segment[SOF_MAN_SEGMENT_BSS].v_base_addr = 0;
man_module->segment[SOF_MAN_SEGMENT_BSS].flags.r.length = 0;

fprintf(stdout, "\tNo\tAddress\t\tSize\t\tFile\tType\n");

/* seek to beginning of file */
err = fseek(module->fd, 0, SEEK_SET);
if (err < 0) {
fprintf(stderr, "error: can't seek to section %d\n", err);
return err;
}

count = fread(buffer, 1, module->file_size, module->fd);
if (count != module->file_size) {
fprintf(stderr, "error: can't read section %d\n", -errno);
return -errno;
}

fprintf(stdout, "\t%d\t0x%8.8x\t0x%8.8x\t0x%x\t%s\n", 0,
0, module->file_size, 0, "DATA");


fprintf(stdout, "\n");
image->image_end = module->foffset + module->file_size;

/* round module end up to nearest page */
if (image->image_end % MAN_PAGE_SIZE) {
image->image_end = (image->image_end / MAN_PAGE_SIZE) + 1;
image->image_end *= MAN_PAGE_SIZE;
}

fprintf(stdout, " Total pages text %d data %d bss %d module file limit: 0x%x\n\n",
man_module->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length,
man_module->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length,
man_module->segment[SOF_MAN_SEGMENT_BSS].flags.r.length,
image->image_end);
return 0;
}


static int man_write_unsigned_mod(struct image *image)
{
int count;
Expand Down Expand Up @@ -555,7 +646,11 @@ static int man_write_fw(struct image *image)
module->foffset = image->image_end;
}

ret = man_module_create(image, module, man_module);
if (image->reloc)
ret = man_module_create_reloc(image, module,
man_module);
else
ret = man_module_create(image, module, man_module);
if (ret < 0)
goto err;
}
Expand Down
9 changes: 7 additions & 2 deletions rimage/rimage.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ static const struct adsp *machine[] = {

static void usage(char *name)
{
fprintf(stdout, "%s:\t -m machine -o outfile -k [key] ELF files\n", name);
fprintf(stdout, "%s:\t -m machine -o outfile -k [key] ELF files\n",
name);
fprintf(stdout, "\t -v enable verbose output\n");
fprintf(stdout, "\t -r enable relocatable ELF files\n");
exit(0);
}

Expand All @@ -48,7 +50,7 @@ int main(int argc, char *argv[])

memset(&image, 0, sizeof(image));

while ((opt = getopt(argc, argv, "ho:m:vba:sk:l:")) != -1) {
while ((opt = getopt(argc, argv, "ho:m:vba:sk:l:r")) != -1) {
switch (opt) {
case 'o':
image.out_file = optarg;
Expand All @@ -68,6 +70,9 @@ int main(int argc, char *argv[])
case 'k':
image.key_name = optarg;
break;
case 'r':
image.reloc = 1;
break;
case 'h':
usage(argv[0]);
break;
Expand Down
Loading