-
Notifications
You must be signed in to change notification settings - Fork 6.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LLEXT full ARM relocation support (adding executable) #70171
Closed
Closed
Changes from 1 commit
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
1d76a0b
llext: Full ARM relocation support and MPU support
selescop 92b5533
llext: Add file loader and heap stat shell command
selescop ad4cc40
llext: Add zephyr_llext cmake macro for llext compilation
selescop 38b2d8a
llext: Add llext file loader sample
selescop 0513e09
llext: tests: Update tests
selescop File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Copyright (c) 2024 Schneider Electric | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
cmake_minimum_required(VERSION 3.20.0) | ||
|
||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) | ||
|
||
project(fs_loader) | ||
|
||
target_sources(app PRIVATE src/main.c src/log_extension.c src/export.c) | ||
|
||
# declare extension | ||
zephyr_llext(hello_world) | ||
zephyr_llext_sources(hello_world.llext/hello_world.c) | ||
|
||
zephyr_llext(hello_world_pic PIC) | ||
zephyr_llext_sources(hello_world.llext/hello_world.c) | ||
|
||
set(FAT_IMG ${CMAKE_CURRENT_BINARY_DIR}/llext_vfat.img) | ||
|
||
# generate image | ||
add_custom_target(vfat.img ALL | ||
COMMAND ${CMAKE_CURRENT_LIST_DIR}/makeimg.sh ${FAT_IMG} ${CMAKE_CURRENT_BINARY_DIR}/hello_world.llext ${CMAKE_CURRENT_BINARY_DIR}/hello_world_pic.llext | ||
WORKING_DIRECTORY ${ZEPHYR_BASE} | ||
SOURCES ${CMAKE_CURRENT_LIST_DIR}/makeimg.sh | ||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/hello_world.llext ${CMAKE_CURRENT_BINARY_DIR}/hello_world_pic.llext | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# | ||
# Copyright (c) 2024 Schneider Electric | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# | ||
|
||
config APP_WIPE_STORAGE | ||
bool "Option to clear the flash area before mounting" | ||
help | ||
Use this to force an existing file system to be created. | ||
|
||
config CONFIG_LLEXT_PIC | ||
bool "Build LL extension with PIC enabled" | ||
help | ||
Use this to force building LL extension in Position Independant Code. | ||
|
||
source "Kconfig.zephyr" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
.. zephyr:code-sample:: llext-fs-loader | ||
:name: Linkable loadable extensions filesystem module | ||
:relevant-api: llext | ||
|
||
Manage loadable extensions using fielsystem. | ||
|
||
Overview | ||
******** | ||
|
||
This example provides filesystem access to the :ref:`llext` system and provides the | ||
ability to manage loadable code extensions in the filesystem. | ||
|
||
Requirements | ||
************ | ||
|
||
A board with a supported llext architecture and filesystem. | ||
|
||
Building | ||
******** | ||
|
||
.. zephyr-app-commands:: | ||
:zephyr-app: samples/subsys/llext/fs_loader | ||
:board: nucleo_l496zg | ||
:goals: build | ||
:compact: | ||
|
||
Running | ||
******* | ||
|
||
Once the board has booted, you will be presented with a shell console. | ||
All the llext system related commands are available as sub-commands of llext | ||
which can be seen with llext help | ||
|
||
.. code-block:: console | ||
|
||
uart:~$ llext help | ||
llext - Loadable extension commands | ||
Subcommands: | ||
list :List loaded extensions and their size in memory | ||
load_hex :Load an elf file encoded in hex directly from the shell input. | ||
Syntax: | ||
<ext_name> <ext_hex_string> | ||
load_fs :Load an elf file encoded in elf directly from a filesystem. | ||
Syntax: | ||
<ext_name> <filepath> | ||
unload :Unload an extension by name. Syntax: | ||
<ext_name> | ||
list_symbols :List extension symbols. Syntax: | ||
<ext_name> | ||
call_fn :Call extension function with prototype void fn(void). Syntax: | ||
<ext_name> <function_name> | ||
|
||
A hello world llext extension can be found in hello_world.llext folder. | ||
|
||
This is built in parallel of zephyr and must be copied in filesystem. | ||
|
||
|
||
|
||
.. code-block:: console | ||
|
||
uart:~$ llext load_fs hello_world /NAND:/hello_world.llext | ||
|
||
This extension can then be seen in the list of loaded extensions (`list`), its symbols printed | ||
(`list_symbols`), and the hello_world function which the extension exports can be called and | ||
run (`call_fn`). | ||
|
||
.. code-block:: console | ||
|
||
uart:~$ llext call_fn hello_world start | ||
hello world from new thread | ||
thread id is .... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
VERSION_MAJOR = 0 | ||
VERSION_MINOR = 1 | ||
PATCHLEVEL = 0 | ||
VERSION_TWEAK = 0 | ||
EXTRAVERSION = fs_llext |
50 changes: 50 additions & 0 deletions
50
samples/subsys/llext/fs_loader/boards/nucleo_l496zg.overlay
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright (c) 2024 Schneider Electric | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
&usbotg_fs { | ||
pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; | ||
pinctrl-names = "default"; | ||
status = "okay"; | ||
}; | ||
/* hsi48 must be enabled for usb */ | ||
&clk_hsi48 { | ||
status = "okay"; | ||
}; | ||
|
||
&flash0 { | ||
partitions { | ||
compatible = "fixed-partitions"; | ||
#address-cells = <1>; | ||
#size-cells = <1>; | ||
|
||
code_partition: partition@0 { | ||
label = "code"; | ||
reg = <0x0000000 DT_SIZE_K(1024-128)>; | ||
read-only; | ||
}; | ||
|
||
/* | ||
* The final 128 KiB is reserved for the application. | ||
* Storage partition will be used by FCB/LittleFS/NVS | ||
* if enabled. | ||
*/ | ||
storage_partition: partition@E0000 { | ||
label = "storage"; | ||
reg = <0x00E0000 DT_SIZE_K(128)>; | ||
}; | ||
}; | ||
}; | ||
|
||
/ { | ||
msc_disk0 { | ||
status="okay"; | ||
compatible = "zephyr,flash-disk"; | ||
partition = <&storage_partition>; | ||
disk-name = "NAND"; | ||
/* cache-size == page erase size */ | ||
cache-size = <2048>; | ||
}; | ||
}; |
41 changes: 41 additions & 0 deletions
41
samples/subsys/llext/fs_loader/boards/stm32f4_disco.overlay
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Copyright (c) 2024 Schneider Electric | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
&flash0 { | ||
partitions { | ||
compatible = "fixed-partitions"; | ||
#address-cells = <1>; | ||
#size-cells = <1>; | ||
|
||
code_partition: partition@0 { | ||
label = "code"; | ||
reg = <0x0000000 DT_SIZE_K(1024-128)>; | ||
read-only; | ||
}; | ||
|
||
/* | ||
* The final 128 KiB is reserved for the application. | ||
* Storage partition will be used by FCB/LittleFS/NVS | ||
* if enabled. | ||
*/ | ||
storage_partition: partition@E0000 { | ||
label = "storage"; | ||
reg = <0x00E0000 DT_SIZE_K(128)>; | ||
read-only; | ||
}; | ||
}; | ||
}; | ||
|
||
/ { | ||
msc_disk0 { | ||
status="okay"; | ||
compatible = "zephyr,flash-disk"; | ||
partition = <&storage_partition>; | ||
disk-name = "NAND"; | ||
/* cache-size == page erase size */ | ||
cache-size = <2048>; | ||
}; | ||
}; |
70 changes: 70 additions & 0 deletions
70
samples/subsys/llext/fs_loader/hello_world.llext/hello_world.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/** | ||
* Copyright (c) 2024 Schneider Electric | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
#include <zephyr/kernel.h> | ||
#include <string.h> | ||
#include <zephyr/llext/symbol.h> | ||
|
||
|
||
#include <zephyr/logging/log.h> | ||
/* In all files comprising the module but one */ | ||
LOG_MODULE_DECLARE(extension, LOG_LEVEL_INF); | ||
|
||
|
||
/* semaphore to end extension thread */ | ||
struct k_sem sem_end_thread; | ||
|
||
|
||
static void extension_thread(void *p1, void *p2, void *p3) | ||
{ | ||
LOG_INF("llext thread: start"); | ||
|
||
while (true) { | ||
int ret = k_sem_take(&sem_end_thread, K_MSEC(1000)); | ||
if (ret != 0) { | ||
/* timeout */ | ||
k_tid_t thread_id = k_sched_current_thread_query(); | ||
printk("Hello World from extension thread %p\n", thread_id); | ||
} else { | ||
/* quit thread */ | ||
break; | ||
} | ||
} | ||
|
||
LOG_INF("llext thread: end"); | ||
} | ||
|
||
#define STACK_SIZE 2048 | ||
#define PRIORITY 5 | ||
|
||
K_THREAD_STACK_DEFINE(hello_world_stack, STACK_SIZE); | ||
struct k_thread new_thread; | ||
|
||
void start(void) | ||
{ | ||
LOG_INF("Starting extension..."); | ||
|
||
k_sem_init(&sem_end_thread, 0, 10); | ||
|
||
k_tid_t tid = k_thread_create(&new_thread, hello_world_stack, STACK_SIZE, | ||
extension_thread, NULL, NULL, NULL, PRIORITY, | ||
K_ESSENTIAL, K_MSEC(0)); | ||
#ifdef CONFIG_THREAD_NAME | ||
strncpy(new_thread.name, "extension", CONFIG_THREAD_MAX_NAME_LEN - 1); | ||
/* Ensure NULL termination, truncate if longer */ | ||
new_thread.name[CONFIG_THREAD_MAX_NAME_LEN - 1] = '\0'; | ||
|
||
#endif | ||
|
||
LOG_INF("Extension Started tid=%p", tid); | ||
} | ||
|
||
void stop(void) | ||
{ | ||
k_sem_give(&sem_end_thread); | ||
} | ||
|
||
LL_EXTENSION_SYMBOL(start); | ||
LL_EXTENSION_SYMBOL(stop); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#!/bin/sh | ||
|
||
# | ||
# Copyright (c) 2024 Schneider Electric. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# | ||
|
||
# Create a FAT12 disk image to flash in memory | ||
# This tool requires the following to be available on the host system: | ||
# | ||
# - dosfstools | ||
# - mtools | ||
set -e | ||
|
||
PROGNAME=$(basename "$0") | ||
OUTPUT=$1 | ||
LOGICAL_SECTOR_SIZE=512 | ||
DISK_SIZE_KB=128 | ||
|
||
usage() { | ||
printf "Usage:\n\t%s output.img input1 [input2] [...]" "$PROGNAME" | ||
} | ||
|
||
die() { | ||
>&2 printf "%s ERROR: " "$PROGNAME" | ||
# We want die() to be usable exactly like printf | ||
# shellcheck disable=SC2059 | ||
>&2 printf "%s\n" "$@" | ||
exit 1 | ||
} | ||
|
||
if [ $# -lt 2 ]; then | ||
usage | ||
die "Not enough arguments." | ||
fi | ||
|
||
shift | ||
INPUTS="$*" | ||
|
||
printf "Creating empty '%s' image..." "$(basename "$OUTPUT")" | ||
dd if=/dev/zero of="$OUTPUT" bs=1k count=${DISK_SIZE_KB} status=none || die "dd to $OUTPUT" | ||
printf "done\nCreating FAT partition image..." | ||
mkfs.fat -F12 -S"$LOGICAL_SECTOR_SIZE" "$OUTPUT" >/dev/null || die "mkfs.vfat failed" | ||
printf "done\nCopying input files..." | ||
mcopy -i "$OUTPUT" "$INPUTS" "::/" || die "mcopy $OUTPUT $INPUTS" | ||
printf "done\n" |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
afaict this can also be done in Python. Perhaps take a look at
pyfatfs
.Could we have a Python implementation instead, and thereby be one step closer to supporting llext in windows and MacOS ?