Skip to content

Commit 08fe313

Browse files
committed
llext: automatically calculate module addresses
Currently LLEXT module starting addresses are hard-coded in their respective CMakeLists.txt files. This is very wasteful, since it's unknown in what order modules are loaded, inflexible and not easily extendible to other platforms. Switch to calculating addresses automatically based on a single per-platform Kconfig value. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
1 parent b4a8c5c commit 08fe313

10 files changed

Lines changed: 98 additions & 9 deletions

File tree

app/overlays/lnl/module_overlay.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
CONFIG_LIBRARY_BASE_ADDRESS=0xa0688000
12
CONFIG_SAMPLE_SMART_AMP=m
23
CONFIG_COMP_MIXIN_MIXOUT=m
34
CONFIG_COMP_IIR=m

app/overlays/mtl/module_overlay.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
CONFIG_LIBRARY_BASE_ADDRESS=0xa0688000
12
CONFIG_SAMPLE_SMART_AMP=m
23
CONFIG_COMP_MIXIN_MIXOUT=m
34
CONFIG_COMP_IIR=m

scripts/llext_link_helper.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ def parse_args():
2828
help='Object file name')
2929
parser.add_argument("-t", "--text-addr", required=True, type=str,
3030
help='.text section address')
31+
parser.add_argument("-s", "--size-file", required=True, type=str,
32+
help='File with stored accumulated size')
3133

3234
args = parser.parse_args()
3335

@@ -43,11 +45,20 @@ def max_alignment(addr, align1, align2):
4345
return upper - (upper % align1)
4446

4547
def main():
48+
global args
49+
4650
parse_args()
4751

48-
elf = ELFFile(open(args.file, 'rb'))
52+
# Get the size of the previous module, if this isn't the first one.
53+
# It is used to automatically calculate starting address of the current
54+
# module.
55+
try:
56+
with open(args.size_file, 'r') as f_size:
57+
size = int(f_size.read().strip(), base = 0)
58+
except OSError:
59+
size = 0
4960

50-
text_addr = int(args.text_addr, 0)
61+
text_addr = int(args.text_addr, 0) + size
5162
text_size = 0
5263

5364
# File names differ when building shared or relocatable objects
@@ -65,6 +76,8 @@ def main():
6576
writable = []
6677
readonly = []
6778

79+
elf = ELFFile(open(args.file, 'rb'))
80+
6881
# Create an object file with sections grouped by their properties,
6982
# similar to how program segments are created: all executable sections,
7083
# then all read-only data sections, and eventually all writable data

scripts/llext_offset_calc.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env python3
2+
# SPDX-License-Identifier: BSD-3-Clause
3+
4+
# Add rounded new file size to accumulated module size cache
5+
6+
import argparse
7+
import pathlib
8+
import os
9+
10+
args = None
11+
12+
def parse_args():
13+
global args
14+
15+
parser = argparse.ArgumentParser(description='Add a file size to a sum in a file')
16+
17+
parser.add_argument("-i", "--input", required=True, type=str,
18+
help='Object file name')
19+
parser.add_argument("-s", "--size-file", required=True, type=str,
20+
help='File to store accumulated size')
21+
22+
args = parser.parse_args()
23+
24+
def main():
25+
global args
26+
27+
parse_args()
28+
29+
f_output = pathlib.Path(args.size_file)
30+
31+
try:
32+
with open(f_output, 'r') as f_size:
33+
size = int(f_size.read().strip(), base = 0)
34+
except OSError:
35+
size = 0
36+
37+
# Failure will raise an exception
38+
f_size = open(f_output, "w")
39+
40+
# align to a page border
41+
size += os.path.getsize(args.input) + 0xfff
42+
size &= ~0xfff
43+
44+
f_size.write(f'0x{size:x}\n')
45+
46+
if __name__ == "__main__":
47+
main()

src/audio/eq_iir/llext/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,4 @@ sof_llext_build("eq_iir"
66
SOURCES ../eq_iir.c
77
../eq_iir_ipc4.c
88
../eq_iir_generic.c
9-
TEXT_ADDR 0xa06ea000
109
)

src/audio/mixin_mixout/llext/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,4 @@ sof_llext_build("mixin_mixout"
77
../mixin_mixout_hifi3.c
88
../mixin_mixout_hifi5.c
99
../mixin_mixout_generic.c
10-
TEXT_ADDR 0xa06aa000
1110
)

src/audio/volume/llext/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@ sof_llext_build("volume"
1111
../volume_hifi4_with_peakvol.c
1212
../volume.c
1313
../volume_ipc4.c
14-
TEXT_ADDR 0xa068a000
1514
)

src/library_manager/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,13 @@ config LIBRARY_AUTH_SUPPORT
3333
could be used if enabled.
3434
If unsure say N.
3535

36+
config LIBRARY_BASE_ADDRESS
37+
hex "Base address for memory, dedicated to loadable modules"
38+
default 0
39+
help
40+
When initializing modules SOF will allocate memory for them and map
41+
it to a predefined per-module address. Those addresses are calculated
42+
automatically but the beginning of that area is platform-specific and
43+
should be set by this option.
44+
3645
endmenu

src/samples/audio/smart_amp_test_llext/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@
44
# Hard-coded .text address to be moved to a common place
55
sof_llext_build("smart_amp_test"
66
SOURCES ../smart_amp_test_ipc4.c
7-
TEXT_ADDR 0xa06ca000
87
)

zephyr/CMakeLists.txt

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ function(sof_append_relative_path_definitions target)
3535
endforeach()
3636
endfunction()
3737

38+
define_property(GLOBAL PROPERTY SOF_LLEXT_LAST_TARGET
39+
BRIEF_DOCS "Last LLEXT target"
40+
FULL_DOCS "\
41+
Building LLEXT targets must be serialized. This property contains the \
42+
previously added LLEXT module for the establishment of a dependency chain."
43+
)
44+
3845
# Used by LLEXT modules to create a file with module UUIDs
3946
function(sof_llext_write_uuids module)
4047
file(STRINGS ${CMAKE_CURRENT_LIST_DIR}/../${module}.toml uuids REGEX "^[ \t]*uuid *=")
@@ -51,7 +58,6 @@ endfunction()
5158
# Build an LLEXT module. Provice a module name, a list of sources and an address
5259
# of the .text section as arguments.
5360
function(sof_llext_build module)
54-
set(single_args TEXT_ADDR)
5561
set(multi_args SOURCES)
5662
cmake_parse_arguments(PARSE_ARGV 1 SOF_LLEXT "${options}" "${single_args}" "${multi_args}")
5763

@@ -88,13 +94,29 @@ function(sof_llext_build module)
8894

8995
get_target_property(proc_in_file ${module} lib_output)
9096
get_target_property(proc_out_file ${module} pkg_input)
97+
get_target_property(proc_pkg_file ${module} pkg_output)
98+
set(size_file ${PROJECT_BINARY_DIR}/module_size)
99+
100+
get_property(last_target GLOBAL PROPERTY SOF_LLEXT_LAST_TARGET)
101+
if(NOT "${last_target}" STREQUAL "")
102+
add_dependencies(${module}_llext_proc ${last_target})
103+
endif()
104+
set_property(GLOBAL PROPERTY SOF_LLEXT_LAST_TARGET ${module})
105+
91106
add_llext_command(TARGET ${module}
92107
POST_BUILD
93-
COMMAND ${SOF_BASE}scripts/llext_link_helper.py
94-
--text-addr="${SOF_LLEXT_TEXT_ADDR}" -f ${proc_in_file} ${CMAKE_C_COMPILER} --
108+
COMMAND ${SOF_BASE}scripts/llext_link_helper.py -s ${size_file}
109+
--text-addr=${CONFIG_LIBRARY_BASE_ADDRESS}
110+
-f ${proc_in_file} ${CMAKE_C_COMPILER} --
95111
-o ${proc_out_file} ${EXTRA_LINKER_PARAMS}
96112
$<TARGET_OBJECTS:${module}_llext_lib>
97113
)
114+
115+
add_llext_command(TARGET ${module}
116+
POST_PKG
117+
COMMAND ${SOF_BASE}scripts/llext_offset_calc.py
118+
-i ${proc_pkg_file} -s ${size_file}
119+
)
98120
endfunction()
99121

100122
# Initial SOF module will contain

0 commit comments

Comments
 (0)