1.. zephyr:code-sample:: llext-shell-loader
2   :name: Linkable loadable extensions shell module
3   :relevant-api: llext
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.
17
18Building
19********
20
21.. zephyr-app-commands::
22   :zephyr-app: samples/subsys/llext/shell_loader
23   :board: robokit1
24   :goals: build
25   :compact:
26
27.. note:: You may need to disable memory protection for the sample to work (e.g. CONFIG_ARM_MPU=n).
28
29Running
30*******
31
32Once the board has booted, you will be presented with a shell prompt.
33All the llext system related commands are available as sub-commands of llext
34which can be seen with llext help
35
36.. code-block:: console
37
38  uart:~$ llext help
39  llext - Loadable extension commands
40  Subcommands:
41    list          :List loaded extensions and their size in memory
42    load_hex      :Load an elf file encoded in hex directly from the shell input.
43                   Syntax:
44                   <ext_name> <ext_hex_string>
45    unload        :Unload an extension by name. Syntax:
46                   <ext_name>
47    list_symbols  :List extension symbols. Syntax:
48                   <ext_name>
49    call_fn       :Call extension function with prototype void fn(void). Syntax:
50                   <ext_name> <function_name>
51
52A hello world C file can be found in tests/subsys/llext/hello_world/hello_world.c
53
54This can be built into a relocatable elf usable on arm v7 platforms. It can be
55inspected with some binutils to see symbols, sections, and relocations.
56Then using additional tools converted to a hex string usable by the llext
57load_hex shell command.
58
59On a host machine with the zephyr sdk setup and the arm toolchain in PATH
60
61.. code-block:: console
62
63  $ arm-zephyr-eabi-gcc -mlong-calls -mthumb -c -o hello_world.elf tests/subsys/llext/hello_world/hello_world.c
64  $ arm-zephyr-eabi-objdump -r -d -x hello_world.elf
65
66	hello_world.elf:     file format elf32-littlearm
67	hello_world.elf
68	architecture: armv4t, flags 0x00000011:
69	HAS_RELOC, HAS_SYMS
70	start address 0x00000000
71	private flags = 0x5000000: [Version5 EABI]
72
73	Sections:
74	Idx Name          Size      VMA       LMA       File off  Algn
75	  0 .text         00000038  00000000  00000000  00000034  2**2
76	                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
77	  1 .data         00000000  00000000  00000000  0000006c  2**0
78	                  CONTENTS, ALLOC, LOAD, DATA
79	  2 .bss          00000000  00000000  00000000  0000006c  2**0
80	                  ALLOC
81	  3 .rodata       00000025  00000000  00000000  0000006c  2**2
82	                  CONTENTS, ALLOC, LOAD, READONLY, DATA
83	  4 .comment      00000021  00000000  00000000  00000091  2**0
84	                  CONTENTS, READONLY
85	  5 .ARM.attributes 0000002a  00000000  00000000  000000b2  2**0
86	                  CONTENTS, READONLY
87	SYMBOL TABLE:
88	00000000 l    df *ABS*	00000000 hello_world.c
89	00000000 l    d  .text	00000000 .text
90	00000000 l    d  .data	00000000 .data
91	00000000 l    d  .bss	00000000 .bss
92	00000000 l    d  .rodata	00000000 .rodata
93	00000000 l     O .rodata	00000004 number
94	00000000 l    d  .comment	00000000 .comment
95	00000000 l    d  .ARM.attributes	00000000 .ARM.attributes
96	00000000 g     F .text	00000034 hello_world
97	00000000         *UND*	00000000 printk
98
99
100
101	Disassembly of section .text:
102
103	00000000 <hello_world>:
104	   0:	b580      	push	{r7, lr}
105	   2:	af00      	add	r7, sp, #0
106	   4:	4b08      	ldr	r3, [pc, #32]	; (28 <hello_world+0x28>)
107	   6:	0018      	movs	r0, r3
108	   8:	4b08      	ldr	r3, [pc, #32]	; (2c <hello_world+0x2c>)
109	   a:	f000 f813 	bl	34 <hello_world+0x34>
110	   e:	222a      	movs	r2, #42	; 0x2a
111	  10:	4b07      	ldr	r3, [pc, #28]	; (30 <hello_world+0x30>)
112	  12:	0011      	movs	r1, r2
113	  14:	0018      	movs	r0, r3
114	  16:	4b05      	ldr	r3, [pc, #20]	; (2c <hello_world+0x2c>)
115	  18:	f000 f80c 	bl	34 <hello_world+0x34>
116	  1c:	46c0      	nop			; (mov r8, r8)
117	  1e:	46bd      	mov	sp, r7
118	  20:	bc80      	pop	{r7}
119	  22:	bc01      	pop	{r0}
120	  24:	4700      	bx	r0
121	  26:	46c0      	nop			; (mov r8, r8)
122	  28:	00000004 	.word	0x00000004
123				28: R_ARM_ABS32	.rodata
124	  2c:	00000000 	.word	0x00000000
125				2c: R_ARM_ABS32	printk
126	  30:	00000014 	.word	0x00000014
127				30: R_ARM_ABS32	.rodata
128	  34:	4718      	bx	r3
129	  36:	46c0      	nop			; (mov r8, r8)
130
131  $ xxd -p hello_world.elf | tr -d '\n'
132
133The resulting hex string can be used to load the extension.
134
135.. code-block:: console
136
137  uart:~$ llext load_hex hello_world 7f454c4601010100000000000000000001002800010000000000000000000000680200000000000534000000000028000b000a0080b500af084b1800084b00f013f82a22074b11001800054b00f00cf8c046bd4680bc01bc0047c0460400000000000000140000001847c0462a00000068656c6c6f20776f726c640a0000000041206e756d62657220697320256c750a00004743433a20285a65706879722053444b20302e31362e31292031322e322e30004129000000616561626900011f000000053454000602080109011204140115011703180119011a011e06000000000000000000000000000000000100000000000000000000000400f1ff000000000000000000000000030001000000000000000000000000000300030000000000000000000000000003000400000000000000000000000000030005000f00000000000000000000000000050012000000000000000400000001000500190000000000000000000000000001000f0000002800000000000000000001001900000034000000000000000000010000000000000000000000000003000600000000000000000000000000030007001c000000010000003400000012000100280000000000000000000000100000000068656c6c6f5f776f726c642e63002464006e756d6265720024740068656c6c6f5f776f726c64007072696e746b000028000000020500002c000000020e00003000000002050000002e73796d746162002e737472746162002e7368737472746162002e72656c2e74657874002e64617461002e627373002e726f64617461002e636f6d6d656e74002e41524d2e6174747269627574657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f0000000100000006000000000000003400000038000000000000000000000004000000000000001b000000090000004000000000000000fc0100001800000008000000010000000400000008000000250000000100000003000000000000006c00000000000000000000000000000001000000000000002b0000000800000003000000000000006c0000000000000000000000000000000100000000000000300000000100000002000000000000006c00000025000000000000000000000004000000000000003800000001000000300000000000000091000000210000000000000000000000010000000100000041000000030000700000000000000000b20000002a0000000000000000000000010000000000000001000000020000000000000000000000dc000000f0000000090000000d000000040000001000000009000000030000000000000000000000cc0100002f0000000000000000000000010000000000000011000000030000000000000000000000140200005100000000000000000000000100000000000000
138
139This extension can then be seen in the list of loaded extensions (`list`), its symbols printed
140(`list_symbols`), and the hello_world function which the extension exports can be called and
141run (`call_fn`).
142
143.. code-block:: console
144
145  uart:~$ llext call_fn hello_world hello_world
146  hello world
147  A number is 42
148
149In this sample there are 3 absolute (R_ARM_ABS32) relocations, 2 of which are meant to hold addresses into the .rodata sections where the strings are located. A third is an address of where the printk function (symbol) can be found. At load time llext replaces the values in the .text section with real memory addresses so that printk works as expected with the strings included in the hello world sample.
150