diff --git a/tests/subsys/llext/simple/boards/qemu_cortex_a9.conf b/tests/subsys/llext/simple/boards/qemu_cortex_a9.conf new file mode 100644 index 00000000000..85f52f80513 --- /dev/null +++ b/tests/subsys/llext/simple/boards/qemu_cortex_a9.conf @@ -0,0 +1,6 @@ +CONFIG_FILE_SYSTEM=y +CONFIG_FILE_SYSTEM_LITTLEFS=y +CONFIG_FS_LITTLEFS_FMP_DEV=y +CONFIG_FLASH_MAP=y +CONFIG_FLASH=y +CONFIG_FLASH_SIMULATOR=y diff --git a/tests/subsys/llext/simple/boards/qemu_cortex_a9.overlay b/tests/subsys/llext/simple/boards/qemu_cortex_a9.overlay new file mode 100644 index 00000000000..3ec42970a9e --- /dev/null +++ b/tests/subsys/llext/simple/boards/qemu_cortex_a9.overlay @@ -0,0 +1,28 @@ +/ { + sim_flash_controller: sim_flash_controller { + compatible = "zephyr,sim-flash"; + + #address-cells = <1>; + #size-cells = <1>; + erase-value = <0x00>; + + flash_sim0: flash_sim@0 { + compatible = "soc-nv-flash"; + reg = <0x00000000 0x2000>; + + erase-block-size = <1024>; + write-block-size = <4>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage_partition"; + reg = <0x00000000 0x2000>; + }; + }; + }; + }; +}; diff --git a/tests/subsys/llext/simple/boards/qemu_cortex_r5.conf b/tests/subsys/llext/simple/boards/qemu_cortex_r5.conf new file mode 100644 index 00000000000..85f52f80513 --- /dev/null +++ b/tests/subsys/llext/simple/boards/qemu_cortex_r5.conf @@ -0,0 +1,6 @@ +CONFIG_FILE_SYSTEM=y +CONFIG_FILE_SYSTEM_LITTLEFS=y +CONFIG_FS_LITTLEFS_FMP_DEV=y +CONFIG_FLASH_MAP=y +CONFIG_FLASH=y +CONFIG_FLASH_SIMULATOR=y diff --git a/tests/subsys/llext/simple/boards/qemu_cortex_r5.overlay b/tests/subsys/llext/simple/boards/qemu_cortex_r5.overlay new file mode 100644 index 00000000000..3ec42970a9e --- /dev/null +++ b/tests/subsys/llext/simple/boards/qemu_cortex_r5.overlay @@ -0,0 +1,28 @@ +/ { + sim_flash_controller: sim_flash_controller { + compatible = "zephyr,sim-flash"; + + #address-cells = <1>; + #size-cells = <1>; + erase-value = <0x00>; + + flash_sim0: flash_sim@0 { + compatible = "soc-nv-flash"; + reg = <0x00000000 0x2000>; + + erase-block-size = <1024>; + write-block-size = <4>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage_partition"; + reg = <0x00000000 0x2000>; + }; + }; + }; + }; +}; diff --git a/tests/subsys/llext/simple/src/test_llext_simple.c b/tests/subsys/llext/simple/src/test_llext_simple.c index 4646c9b5519..5be1e60076b 100644 --- a/tests/subsys/llext/simple/src/test_llext_simple.c +++ b/tests/subsys/llext/simple/src/test_llext_simple.c @@ -6,10 +6,16 @@ #include #include +#include +#if defined(CONFIG_FILE_SYSTEM_LITTLEFS) +#include +#endif #include #include #include +#include #include +#include #include #include "syscalls_ext.h" #include "threads_kernel_objects_ext.h" @@ -323,6 +329,57 @@ ZTEST(llext, test_find_section) } #endif +#if defined(CONFIG_FILE_SYSTEM) +#define LLEXT_FILE "hello_world.llext" + +FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(storage); +static struct fs_mount_t mp = { + .type = FS_LITTLEFS, + .fs_data = &storage, + .storage_dev = (void *)FIXED_PARTITION_ID(storage_partition), + .mnt_point = "/lfs", +}; + +ZTEST(llext, test_fs_loader) +{ + int res; + char path[UINT8_MAX]; + struct fs_file_t fd; + + /* File system should be mounted before the testcase. If not mount it now. */ + if (!(mp.flags & FS_MOUNT_FLAG_AUTOMOUNT)) { + zassert_ok(fs_mount(&mp), "Filesystem should be mounted"); + } + + snprintf(path, sizeof(path), "%s/%s", mp.mnt_point, LLEXT_FILE); + fs_file_t_init(&fd); + + zassert_ok(fs_open(&fd, path, FS_O_CREATE | FS_O_TRUNC | FS_O_WRITE), + "Failed opening file"); + + zassert_equal(fs_write(&fd, hello_world_ext, ARRAY_SIZE(hello_world_ext)), + ARRAY_SIZE(hello_world_ext), + "Full content of the buffer holding ext should be written"); + + zassert_ok(fs_close(&fd), "Failed closing file"); + + struct llext_fs_loader fs_loader = LLEXT_FS_LOADER(path); + struct llext_loader *loader = &fs_loader.loader; + struct llext_load_param ldr_parm = LLEXT_LOAD_PARAM_DEFAULT; + struct llext *ext = NULL; + + res = llext_load(loader, "hello_world", &ext, &ldr_parm); + zassert_ok(res, "load should succeed"); + + void (*test_entry_fn)() = llext_find_sym(&ext->exp_tab, "test_entry"); + + zassert_not_null(test_entry_fn, "test_entry should be an exported symbol"); + + llext_unload(&ext); + fs_unmount(&mp); +} +#endif + /* * Ensure that EXPORT_SYMBOL does indeed provide a symbol and a valid address * to it. diff --git a/tests/subsys/llext/simple/testcase.yaml b/tests/subsys/llext/simple/testcase.yaml index 16a584f641c..6fb9088f0e5 100644 --- a/tests/subsys/llext/simple/testcase.yaml +++ b/tests/subsys/llext/simple/testcase.yaml @@ -45,6 +45,13 @@ tests: extra_configs: - CONFIG_USERSPACE=y - CONFIG_LLEXT_STORAGE_WRITABLE=n + llext.simple.readonly_fs_loader: + arch_allow: arm # Xtensa needs writable storage + filter: not CONFIG_MPU and not CONFIG_MMU and not CONFIG_SOC_SERIES_S32ZE + extra_configs: + - arch:arm:CONFIG_ARM_MPU=n + - arch:arm:CONFIG_ARM_AARCH32_MMU=n + - CONFIG_LLEXT_STORAGE_WRITABLE=n llext.simple.writable: arch_allow: arm xtensa integration_platforms: