llext: Keep constant data in flash.
This patch adds a new Kconfig option that allows read-only data sections without relocations to be mapped directly (remain in flash) instead of being copied to RAM during extension loading. This helps extensions that have large constant data, such as certificates, lookup tables etc.. to save saving significant RAM, especially with MPU is enabled. This feature requires the extension to place rodata sections without relocations in LLEXT_RODATA_NO_RELOC section. Note that we chose to disable this optimization when MMU or USERSPACE is enabled because the NO_RELOC section may not be aligned to the MPU/MMU requirements on some architectures. If we leave it in place, llext will attempt to create an MPU region for it using a misaligned address, and if we allow it to be copied to RAM, it defeats the purpose of this feature. Signed-off-by: Ibrahim Abdalkader <i.abdalkader@gmail.com>
This commit is contained in:
committed by
Fabio Baltieri
parent
234aa30a8f
commit
dca4136f5e
@@ -53,6 +53,9 @@ enum llext_mem {
|
||||
LLEXT_MEM_PREINIT, /**< Array of early setup functions */
|
||||
LLEXT_MEM_INIT, /**< Array of setup functions */
|
||||
LLEXT_MEM_FINI, /**< Array of cleanup functions */
|
||||
#ifdef CONFIG_LLEXT_RODATA_NO_RELOC
|
||||
LLEXT_MEM_RODATA_NO_RELOC, /**< Read-only data without relocations (kept in flash) */
|
||||
#endif
|
||||
|
||||
LLEXT_MEM_COUNT, /**< Number of regions managed by LLEXT */
|
||||
};
|
||||
@@ -62,6 +65,22 @@ enum llext_mem {
|
||||
/* Number of memory partitions used by LLEXT */
|
||||
#define LLEXT_MEM_PARTITIONS (LLEXT_MEM_BSS+1)
|
||||
|
||||
#ifdef CONFIG_LLEXT_RODATA_NO_RELOC
|
||||
/* Section name for read-only data kept in flash */
|
||||
#define LLEXT_SECT_RODATA_NO_RELOC llext.rodata.noreloc
|
||||
|
||||
/* Full section name as string for comparisons */
|
||||
#define LLEXT_SECTION_RODATA_NO_RELOC ("." STRINGIFY(LLEXT_SECT_RODATA_NO_RELOC))
|
||||
|
||||
/**
|
||||
* Use this attribute on read-only data that should remain in flash
|
||||
* instead of being copied to RAM.
|
||||
*/
|
||||
#define LLEXT_RODATA_NO_RELOC Z_GENERIC_DOT_SECTION(LLEXT_SECT_RODATA_NO_RELOC)
|
||||
#else
|
||||
#define LLEXT_RODATA_NO_RELOC
|
||||
#endif
|
||||
|
||||
struct llext_loader;
|
||||
/** @endcond */
|
||||
|
||||
|
||||
@@ -108,6 +108,20 @@ config LLEXT_STORAGE_WRITABLE
|
||||
Select if LLEXT storage is writable, i.e. if extensions are stored in
|
||||
RAM and can be modified in place
|
||||
|
||||
config LLEXT_RODATA_NO_RELOC
|
||||
bool "Keep read-only data without relocations in flash"
|
||||
depends on !MMU && !USERSPACE
|
||||
help
|
||||
When enabled, read-only data sections (.rodata) that do not have
|
||||
any relocations are kept in their original location (typically flash)
|
||||
instead of being copied to RAM.
|
||||
|
||||
This is useful for large constant data like certificates, lookup
|
||||
tables, or string literals that don't contain any pointers.
|
||||
|
||||
This feature requires the extension to manually tag that data with
|
||||
the LLEXT_RODATA_NO_RELOC macro.
|
||||
|
||||
config LLEXT_EXPORT_DEVICES
|
||||
bool "Export all DT devices to llexts"
|
||||
select LLEXT_EXPORT_SYMBOL_GROUP_DEVICE
|
||||
|
||||
@@ -262,6 +262,10 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext,
|
||||
mem_idx = LLEXT_MEM_TEXT;
|
||||
} else if (shdr->sh_flags & SHF_WRITE) {
|
||||
mem_idx = LLEXT_MEM_DATA;
|
||||
#ifdef CONFIG_LLEXT_RODATA_NO_RELOC
|
||||
} else if (strcmp(name, LLEXT_SECTION_RODATA_NO_RELOC) == 0) {
|
||||
mem_idx = LLEXT_MEM_RODATA_NO_RELOC;
|
||||
#endif
|
||||
} else {
|
||||
mem_idx = LLEXT_MEM_RODATA;
|
||||
}
|
||||
@@ -534,6 +538,13 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LLEXT_RODATA_NO_RELOC
|
||||
if (ldr->sects[LLEXT_MEM_RODATA_NO_RELOC].sh_flags & SHF_LLEXT_HAS_RELOCS) {
|
||||
LOG_ERR("%s has relocations", LLEXT_SECTION_RODATA_NO_RELOC);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user