1.. zephyr:code-sample:: llext-shell-loader
2   :name: Linkable loadable extensions shell module
3   :relevant-api: llext_apis
4
5   Manage loadable extensions using shell commands.
6
7Overview
8********
9
10This example provides shell access to the :ref:`llext` system and provides the
11ability to manage loadable code extensions in the shell.
12
13Requirements
14************
15
16A board with a supported LLEXT architecture and shell capable console. The
17following example uses an ARMv7 CPU, but the same instructions can be adapted
18to any LLEXT-supported target.
19
20Building
21********
22
23The following command will build the main shell application:
24
25.. zephyr-app-commands::
26   :zephyr-app: samples/subsys/llext/shell_loader
27   :board: robokit1
28   :goals: build
29   :compact:
30
31.. note::
32
33   You may need to disable memory protection for the sample to work (e.g.
34   ``CONFIG_ARM_MPU=n``). See the full list of similar flags in
35   :zephyr_file:`tests/subsys/llext/no_mem_protection.conf`.
36
37This sample also includes the source for a very basic extension,
38:zephyr_file:`samples/subsys/llext/shell_loader/hello_world.c`, which can be
39used to test the LLEXT features.
40
41It can be compiled to :file:`build/hello_world.llext` using the Zephyr build
42system like this:
43
44.. code-block:: console
45
46   $ ninja -C build -vvv hello_world_ext
47
48On a host machine with the Zephyr SDK and the ``arm-zephyr-eabi`` toolchain in
49``PATH``, you can also obtain the same result directly with ``gcc``:
50
51.. code-block:: console
52
53   $ arm-zephyr-eabi-gcc -mlong-calls -mthumb -c -o build/hello_world.llext samples/subsys/llext/shell/hello_world.c
54
55.. note::
56
57   LLEXT by default only imports symbols that have been explicitly exported by
58   the extension via the :c:macro:`EXPORT_SYMBOL` macro. Compiling with this
59   macro requires using the full Zephyr build system, or at least the
60   :ref:`LLEXT EDK <llext_build_edk>`.
61
62   To avoid this complexity, this sample configures Zephyr to use all global
63   symbols defined in the extension ELF file via the Kconfig option
64   :kconfig:option:`CONFIG_LLEXT_IMPORT_ALL_GLOBALS`. This is not recommended
65   for large extensions as the memory usage increases significantly.
66
67The compiled extension can be inspected with the usual binutils utilities to
68see symbols, sections, and relocations. Then, using additional tools, converted
69to a hex string usable by the ``llext load_hex`` shell command:
70
71.. code-block:: console
72
73  $ arm-zephyr-eabi-objdump -r -d -x build/hello_world.llext
74
75	hello_world.elf:     file format elf32-littlearm
76	hello_world.elf
77	architecture: armv4t, flags 0x00000011:
78	HAS_RELOC, HAS_SYMS
79	start address 0x00000000
80	private flags = 0x5000000: [Version5 EABI]
81
82	Sections:
83	Idx Name          Size      VMA       LMA       File off  Algn
84	  0 .text         00000038  00000000  00000000  00000034  2**2
85	                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
86	  1 .data         00000000  00000000  00000000  0000006c  2**0
87	                  CONTENTS, ALLOC, LOAD, DATA
88	  2 .bss          00000000  00000000  00000000  0000006c  2**0
89	                  ALLOC
90	  3 .rodata       00000025  00000000  00000000  0000006c  2**2
91	                  CONTENTS, ALLOC, LOAD, READONLY, DATA
92	  4 .comment      00000021  00000000  00000000  00000091  2**0
93	                  CONTENTS, READONLY
94	  5 .ARM.attributes 0000002a  00000000  00000000  000000b2  2**0
95	                  CONTENTS, READONLY
96	SYMBOL TABLE:
97	00000000 l    df *ABS*	00000000 hello_world.c
98	00000000 l    d  .text	00000000 .text
99	00000000 l    d  .data	00000000 .data
100	00000000 l    d  .bss	00000000 .bss
101	00000000 l    d  .rodata	00000000 .rodata
102	00000000 l     O .rodata	00000004 number
103	00000000 l    d  .comment	00000000 .comment
104	00000000 l    d  .ARM.attributes	00000000 .ARM.attributes
105	00000000 g     F .text	00000034 hello_world
106	00000000         *UND*	00000000 printk
107
108
109
110	Disassembly of section .text:
111
112	00000000 <hello_world>:
113	   0:	b580      	push	{r7, lr}
114	   2:	af00      	add	r7, sp, #0
115	   4:	4b08      	ldr	r3, [pc, #32]	; (28 <hello_world+0x28>)
116	   6:	0018      	movs	r0, r3
117	   8:	4b08      	ldr	r3, [pc, #32]	; (2c <hello_world+0x2c>)
118	   a:	f000 f813 	bl	34 <hello_world+0x34>
119	   e:	222a      	movs	r2, #42	; 0x2a
120	  10:	4b07      	ldr	r3, [pc, #28]	; (30 <hello_world+0x30>)
121	  12:	0011      	movs	r1, r2
122	  14:	0018      	movs	r0, r3
123	  16:	4b05      	ldr	r3, [pc, #20]	; (2c <hello_world+0x2c>)
124	  18:	f000 f80c 	bl	34 <hello_world+0x34>
125	  1c:	46c0      	nop			; (mov r8, r8)
126	  1e:	46bd      	mov	sp, r7
127	  20:	bc80      	pop	{r7}
128	  22:	bc01      	pop	{r0}
129	  24:	4700      	bx	r0
130	  26:	46c0      	nop			; (mov r8, r8)
131	  28:	00000004 	.word	0x00000004
132				28: R_ARM_ABS32	.rodata
133	  2c:	00000000 	.word	0x00000000
134				2c: R_ARM_ABS32	printk
135	  30:	00000014 	.word	0x00000014
136				30: R_ARM_ABS32	.rodata
137	  34:	4718      	bx	r3
138	  36:	46c0      	nop			; (mov r8, r8)
139
140  $ xxd -p build/hello_world.llext | tr -d '\n'
141  7f454c4601010100000000000000000001002800010000000000000000000000680200000000000534000000000028000b000a0080b500af084b1800084b00f013f82a22074b11001800054b00f00cf8c046bd4680bc01bc0047c0460400000000000000140000001847c0462a00000068656c6c6f20776f726c640a0000000041206e756d62657220697320256c750a00004743433a20285a65706879722053444b20302e31362e31292031322e322e30004129000000616561626900011f000000053454000602080109011204140115011703180119011a011e06000000000000000000000000000000000100000000000000000000000400f1ff000000000000000000000000030001000000000000000000000000000300030000000000000000000000000003000400000000000000000000000000030005000f00000000000000000000000000050012000000000000000400000001000500190000000000000000000000000001000f0000002800000000000000000001001900000034000000000000000000010000000000000000000000000003000600000000000000000000000000030007001c000000010000003400000012000100280000000000000000000000100000000068656c6c6f5f776f726c642e63002464006e756d6265720024740068656c6c6f5f776f726c64007072696e746b000028000000020500002c000000020e00003000000002050000002e73796d746162002e737472746162002e7368737472746162002e72656c2e74657874002e64617461002e627373002e726f64617461002e636f6d6d656e74002e41524d2e6174747269627574657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f0000000100000006000000000000003400000038000000000000000000000004000000000000001b000000090000004000000000000000fc0100001800000008000000010000000400000008000000250000000100000003000000000000006c00000000000000000000000000000001000000000000002b0000000800000003000000000000006c0000000000000000000000000000000100000000000000300000000100000002000000000000006c00000025000000000000000000000004000000000000003800000001000000300000000000000091000000210000000000000000000000010000000100000041000000030000700000000000000000b20000002a0000000000000000000000010000000000000001000000020000000000000000000000dc000000f0000000090000000d000000040000001000000009000000030000000000000000000000cc0100002f0000000000000000000000010000000000000011000000030000000000000000000000140200005100000000000000000000000100000000000000
142
143In this sample there are 3 absolute (``R_ARM_ABS32``) relocations, 2 of which
144are meant to hold addresses into the ``.rodata`` sections where the strings are
145located. A third is an address of where the ``printk`` function (symbol) can be
146found. At load time LLEXT replaces the values in the ``.text`` section with
147real memory addresses so that ``printk`` works as expected with the strings
148included in the hello world sample.
149
150Running
151*******
152
153Once the board has booted, you will be presented with a shell prompt.
154All the LLEXT system related commands are available as sub-commands of
155``llext``, and can be seen with ``llext help``:
156
157.. code-block:: console
158
159  uart:~$ llext help
160  llext - Loadable extension commands
161  Subcommands:
162    list          :List loaded extensions and their size in memory
163    load_hex      :Load an elf file encoded in hex directly from the shell input.
164                   Syntax:
165                   <ext_name> <ext_hex_string>
166    unload        :Unload an extension by name. Syntax:
167                   <ext_name>
168    list_symbols  :List extension symbols. Syntax:
169                   <ext_name>
170    call_fn       :Call extension function with prototype void fn(void). Syntax:
171                   <ext_name> <function_name>
172
173The hex string generated above can be used to load the extension:
174
175.. code-block:: console
176
177  uart:~$ llext load_hex hello_world 7f454c4601010100000000000000000001002800010000000000000000000000680200000000000534000000000028000b000a0080b500af084b1800084b00f013f82a22074b11001800054b00f00cf8c046bd4680bc01bc0047c0460400000000000000140000001847c0462a00000068656c6c6f20776f726c640a0000000041206e756d62657220697320256c750a00004743433a20285a65706879722053444b20302e31362e31292031322e322e30004129000000616561626900011f000000053454000602080109011204140115011703180119011a011e06000000000000000000000000000000000100000000000000000000000400f1ff000000000000000000000000030001000000000000000000000000000300030000000000000000000000000003000400000000000000000000000000030005000f00000000000000000000000000050012000000000000000400000001000500190000000000000000000000000001000f0000002800000000000000000001001900000034000000000000000000010000000000000000000000000003000600000000000000000000000000030007001c000000010000003400000012000100280000000000000000000000100000000068656c6c6f5f776f726c642e63002464006e756d6265720024740068656c6c6f5f776f726c64007072696e746b000028000000020500002c000000020e00003000000002050000002e73796d746162002e737472746162002e7368737472746162002e72656c2e74657874002e64617461002e627373002e726f64617461002e636f6d6d656e74002e41524d2e6174747269627574657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f0000000100000006000000000000003400000038000000000000000000000004000000000000001b000000090000004000000000000000fc0100001800000008000000010000000400000008000000250000000100000003000000000000006c00000000000000000000000000000001000000000000002b0000000800000003000000000000006c0000000000000000000000000000000100000000000000300000000100000002000000000000006c00000025000000000000000000000004000000000000003800000001000000300000000000000091000000210000000000000000000000010000000100000041000000030000700000000000000000b20000002a0000000000000000000000010000000000000001000000020000000000000000000000dc000000f0000000090000000d000000040000001000000009000000030000000000000000000000cc0100002f0000000000000000000000010000000000000011000000030000000000000000000000140200005100000000000000000000000100000000000000
178
179This extension can then be seen in the list of loaded extensions (``list``), its symbols printed
180(``list_symbols``), and the hello_world function which the extension exports can be called and
181run (``call_fn``).
182
183.. code-block:: console
184
185  uart:~$ llext call_fn hello_world hello_world
186  hello world
187