README.rst
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.
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