Skip to content

Commit

Permalink
llext: add support for executable sections in IMR / DRAM
Browse files Browse the repository at this point in the history
Make the link helper collect any non-default executable sections and
link them at 0 to be relocated at run-time to IMR / DRAM addresses.
Also tell Zephyr to treat any such sections as detached.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
  • Loading branch information
lyakh committed Sep 27, 2024
1 parent 64cb133 commit 1fa751a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 7 deletions.
36 changes: 29 additions & 7 deletions scripts/llext_link_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,12 @@ def main():

command = [args.command]

executable = []
writable = []
readonly = []

text_found = False

elf = ELFFile(open(args.file, 'rb'))

# Create an object file with sections grouped by their properties,
Expand All @@ -102,13 +105,14 @@ def main():
# In general additional executable sections are possible, e.g.
# .init. In the future support for arbitrary such sections can be
# added, similar to writable and read-only data below.
if s_name != '.text':
print(f"Warning! Non-standard executable section {s_name}")

text_addr = max_alignment(text_addr, 0x1000, s_alignment)
text_size = s_size

command.append(f'-Wl,-Ttext=0x{text_addr:x}')
if s_name == '.text':
text_found = True
text_addr = max_alignment(text_addr, 0x1000, s_alignment)
text_size = s_size
command.append(f'-Wl,-Ttext=0x{text_addr:x}')
else:
# Any additional executable sections are intended for IMR
executable.append(section)

continue

Expand All @@ -122,6 +126,24 @@ def main():
# .rodata or other read-only sections
readonly.append(section)

if not text_found:
raise RuntimeError('No .text section found in the object file')

# IMR sections don't need to be linked with SRAM addresses
imr_addr = 0

for section in executable:
s_alignment = section.header['sh_addralign']
s_name = section.name

imr_addr = align_up(imr_addr, s_alignment)

command.append(f'-Wl,--section-start={s_name}=0x{imr_addr:x}')

imr_addr += section.header['sh_size']

# So far there doesn't seem to be any reason to align additional
# executable sections after .text
start_addr = align_up(text_addr + text_size, 0x1000)

for section in readonly:
Expand Down
8 changes: 8 additions & 0 deletions src/library_manager/llext_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,13 @@ static int llext_manager_unload_module(uint32_t module_id, const struct sof_man_
return err;
}

#define LLEXT_SECTION_MIN_ADDR 0x10000

static bool llext_manager_section_detached(const elf_shdr_t *shdr)
{
return shdr->sh_addr < LLEXT_SECTION_MIN_ADDR;
}

static int llext_manager_link(struct sof_man_fw_desc *desc, struct sof_man_module *mod,
uint32_t module_id, struct module_data *md, const void **buildinfo,
const struct sof_man_module_manifest **mod_manifest)
Expand All @@ -232,6 +239,7 @@ static int llext_manager_link(struct sof_man_fw_desc *desc, struct sof_man_modul
struct llext_load_param ldr_parm = {
.relocate_local = !ctx->segment[LIB_MANAGER_TEXT].size,
.pre_located = true,
.section_detached = llext_manager_section_detached,
};
int ret = llext_load(&ebl.loader, mod->name, &md->llext, &ldr_parm);

Expand Down

0 comments on commit 1fa751a

Please sign in to comment.