Skip to content

Commit 38828e5

Browse files
committed
developer-guide: add LLEXT module documentation
Describe LLEXT loadable module support in SOF. Signed-off-by: Guennadi Liakhovetski <[email protected]>
1 parent 97e7339 commit 38828e5

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

developer_guides/firmware/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ Developer guides and information for firmware development.
1212
porting
1313
cmake
1414
async_messaging_best_practices
15+
llext_modules
+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
.. _llext_modules:
2+
3+
LLEXT Modules
4+
#############
5+
6+
|SOF| support for loadable modules, using Zephyr LLEXT API.
7+
8+
Zephyr LLEXT API
9+
****************
10+
11+
Please refer to https://docs.zephyrproject.org/latest/services/llext/index.html
12+
for detailed documentation. In short, the Zephyr Linkable Loadable Extensions
13+
(LLEXT) API implements support for run-time loading and unloading of ELF-format
14+
executable code and data.
15+
16+
SOF use of the LLEXT API
17+
************************
18+
19+
SOF has multiple ways to implement loadable modules. LLEXT is one of them.
20+
With it modules are built as shared or relocatable ELF objects with an addition
21+
of a cryptographic signature, using any user-supplied key, and a manifest. When
22+
loaded and instantiated, Zephyr LLEXT functionality is used to dynamically
23+
resolve module internal as well as SOF and Zephyr external code and data
24+
references. In the future support for inter-module linking will be added.
25+
26+
Accessing the base firmware from LLEXT modules
27+
**********************************************
28+
29+
LLEXT modules can access all code and data from the base firmware exported,
30+
using the ``EXPORT_SYMBOL()`` macro. Therefore writing LLEXT modules isn't very
31+
different from built-in ones.
32+
33+
Implementing LLEXT modules
34+
**************************
35+
36+
At the moment only modules, implementing the Module Adapter API
37+
:ref:`apps-comp-world` are supported.
38+
39+
.. _multiple-adapter-modules:
40+
41+
It is possible to implement multiple Module Adapter modules with a common code
42+
base, i.e. sharing a set of source files and functions. Then a single LLEXT
43+
object would be created, implementing multiple Module Adapter interfaces. In
44+
that case an array of ``struct sof_module_api_build_info`` objects is needed and
45+
the TOML file should contain those multiple module entries too.
46+
src/audio/mixin_mixout/mixin_mixout.c is an example of such a case.
47+
48+
As explained above, LLEXT modules in general look very similar to native SOF
49+
code, with the only restriction of having no access to not-exported symbols.
50+
51+
LLEXT modules should also contain a ``.buildinfo`` section, containing a
52+
``struct sof_module_api_build_info`` object and a ``.module`` section,
53+
containing a ``struct sof_man_module_manifest`` object. The latter should also
54+
contain a pointer to a module entry point function, returning a pointer to the
55+
module's ``struct module_interface`` instance. All these additions can be
56+
performed, using ``SOF_LLEXT_MOD_ENTRY()``, ``SOF_LLEXT_MODULE_MANIFEST()`` and
57+
``SOF_LLEXT_BUILDINFO`` helper macros. See src/audio/eq_iir/eq_iir.c for an
58+
example.
59+
60+
A TOML configuration file is needed for building of LLEXT modules too. It is
61+
generated by the C preprocessor at build time from the same components, as would
62+
be used for a monolithic build. For this preprocessor run a small header file is
63+
added. It mostly just includes ``platform.toml`` and ``${module}.toml``, similar
64+
to src/samples/audio/smart_amp_test_llext/llext.toml.h.
65+
66+
Finally an additional CMakeLists.txt is needed similar to
67+
src/samples/audio/smart_amp_test_llext/CMakeLists.txt. It contains a single call
68+
to ``sof_llext_build()``, which is an SOF helper function, using Zephyr LLEXT
69+
cmake support by calling ``add_llext_target()`` and ``add_llext_command()``.
70+
71+
With that in place, it is also possible to switch between monolithic and modular
72+
builds by specifying the module as "tristate" in its Kconfig and selecting "m"
73+
for modular builds. Note, that it is possible to implement third party Module
74+
Adapter drivers, that would be built exclusively as loadable modules. Such
75+
modules don't have to use "tristate" in their Kconfig entries.
76+
77+
Installation
78+
************
79+
80+
As specified in
81+
:ref:`Firmware look-up paths per Intel platform <intel_firmware_paths>`
82+
the |SOF| Linux kernel driver loads SOF modules by their UUIDs,
83+
specified in the topology. For SOF in-tree modules the process of creation and
84+
installation of modules in a deployment tree is automated by the
85+
xtensa-build-zephyr.py script. It copies modules to the deployment tree as
86+
files with a "llext" extension and creates symbolic links to them named as
87+
``${UUID}.bin``. E.g.
88+
89+
.. code-block:: cfg
90+
91+
B36EE4DA-006F-47F9-A06D-FECBE2D8B6CE.bin -> drc.llext
92+
93+
Note, that as described :ref:`above <multiple-adapter-modules>` multiple UUIDs
94+
can be associated with a single module, in such cases multiple symbolic links
95+
will be created, e.g.
96+
97+
.. code-block:: cfg
98+
99+
39656EB2-3B71-4049-8D3F-F92CD5C43C09.bin -> mixin_mixout.llext
100+
3C56505A-24D7-418F-BDDC-C1F5A3AC2AE0.bin -> mixin_mixout.llext
101+
102+
See :ref:`apps-component-overview` for more information on UUID use by SOF
103+
component and module adapter drivers.
104+
105+
It is also possible to avoid using the script by running ``west build`` to build
106+
an SOF image and any modules, then using the cross-compiler to preprocess TOML
107+
files and finally by running rimage to sign them. This would generate the same
108+
result but figuring out all the command-line arguments would be rather difficult.

getting_started/intel_debug/introduction.rst

+1
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ configuration issue.
119119

120120
Linux SOF will look up firmware files at the following paths:
121121

122+
.. _intel_firmware_paths:
122123
.. list-table:: Firmware look-up paths per Intel platform
123124
:widths: 55 5 50 25
124125
:header-rows: 1

0 commit comments

Comments
 (0)