linker: introduce on-demand linker section tags

This provides __ondemand_func and __ondemand_rodata tags for annotating
functions and read-only data that should be loaded on demand so not to
exhaust all available RAM. The demand paging mechanism will be leveraged
to load so designated code/data as needed and to evict it from memory
when unused.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
Nicolas Pitre 2024-07-22 16:19:51 -04:00 committed by Anas Nashif
parent bd3b731ddc
commit cbbd8579b8
5 changed files with 84 additions and 0 deletions

View File

@ -260,6 +260,19 @@ config LINKER_USE_PINNED_SECTION
Requires that pinned sections exist in the architecture, SoC,
board or custom linker script.
config LINKER_USE_ONDEMAND_SECTION
bool "Use Evictable Linker Section"
depends on !LINKER_USE_PINNED_SECTION
depends on !ARCH_MAPS_ALL_RAM
help
If enabled, the symbols which may be evicted from memory
will be put into a linker section reserved for on-demand symbols.
During boot, the corresponding memory will be mapped as paged out.
This is conceptually the opposite of CONFIG_LINKER_USE_PINNED_SECTION.
Requires that on-demand sections exist in the architecture, SoC,
board or custom linker script.
config LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT
bool "Generic sections are present at boot" if DEMAND_PAGING && LINKER_USE_PINNED_SECTION
default y

View File

@ -70,6 +70,9 @@ MEMORY
LINKER_DT_REGIONS()
/* Used by and documented in include/linker/intlist.ld */
IDT_LIST (wx) : ORIGIN = 0xFFFF8000, LENGTH = 32K
#ifdef CONFIG_LINKER_USE_ONDEMAND_SECTION
ONDEMAND (rx) : ORIGIN = (CONFIG_KERNEL_VM_BASE), LENGTH = (CONFIG_KERNEL_VM_SIZE)
#endif
}
ENTRY(CONFIG_KERNEL_ENTRY)
@ -294,6 +297,35 @@ SECTIONS
GROUP_END(RAMABLE_REGION)
#ifdef CONFIG_LINKER_USE_ONDEMAND_SECTION
. = z_mapped_end;
MMU_ALIGN;
lnkr_ondemand_start = .;
ONDEMAND_TEXT_SECTION_NAME (.) : AT(ADDR(_BSS_SECTION_NAME))
{
lnkr_ondemand_text_start = .;
*(.ondemand_text)
*(.ondemand_text.*)
MMU_ALIGN;
lnkr_ondemand_text_end = .;
} > ONDEMAND
lnkr_ondemand_text_size = SIZEOF(ONDEMAND_TEXT_SECTION_NAME);
ONDEMAND_RODATA_SECTION_NAME :
{
lnkr_ondemand_rodata_start = .;
*(.ondemand_rodata)
*(.ondemand_rodata.*)
MMU_ALIGN;
lnkr_ondemand_rodata_end = .;
} > ONDEMAND
lnkr_ondemand_rodata_size = SIZEOF(ONDEMAND_RODATA_SECTION_NAME);
lnkr_ondemand_end = .;
lnkr_ondemand_load_start = LOADADDR(ONDEMAND_TEXT_SECTION_NAME);
#endif
#include <zephyr/linker/debug-sections.ld>
SECTION_PROLOGUE(.ARM.attributes, 0,)

View File

@ -337,6 +337,24 @@ static inline bool lnkr_is_region_pinned(uint8_t *addr, size_t sz)
#endif /* CONFIG_LINKER_USE_PINNED_SECTION */
#ifdef CONFIG_LINKER_USE_ONDEMAND_SECTION
/* lnkr_ondemand_start[] and lnkr_ondemand_end[] must encapsulate
* all the on-demand sections as these are used by
* the MMU code to mark the virtual pages with the appropriate backing store
* location token to have them be paged in on demand.
*/
extern char lnkr_ondemand_start[];
extern char lnkr_ondemand_end[];
extern char lnkr_ondemand_load_start[];
extern char lnkr_ondemand_text_start[];
extern char lnkr_ondemand_text_end[];
extern char lnkr_ondemand_text_size[];
extern char lnkr_ondemand_rodata_start[];
extern char lnkr_ondemand_rodata_end[];
extern char lnkr_ondemand_rodata_size[];
#endif /* CONFIG_LINKER_USE_ONDEMAND_SECTION */
#endif /* ! _ASMLANGUAGE */
#endif /* ZEPHYR_INCLUDE_LINKER_LINKER_DEFS_H_ */

View File

@ -100,6 +100,14 @@
#define __pinned_noinit __noinit
#endif /* CONFIG_LINKER_USE_PINNED_SECTION */
#if defined(CONFIG_LINKER_USE_ONDEMAND_SECTION)
#define __ondemand_func Z_GENERIC_DOT_SECTION(ONDEMAND_TEXT_SECTION_NAME)
#define __ondemand_rodata Z_GENERIC_DOT_SECTION(ONDEMAND_RODATA_SECTION_NAME)
#else
#define __ondemand_func
#define __ondemand_rodata
#endif /* CONFIG_LINKER_USE_ONDEMAND_SECTION */
#if defined(CONFIG_LINKER_USE_PINNED_SECTION)
#define __isr __pinned_func
#else

View File

@ -101,6 +101,11 @@
#define PINNED_NOINIT_SECTION_NAME pinned_noinit
#endif
#if defined(CONFIG_LINKER_USE_ONDEMAND_SECTION)
#define ONDEMAND_TEXT_SECTION_NAME ondemand_text
#define ONDEMAND_RODATA_SECTION_NAME ondemand_rodata
#endif
/* Short section references for use in ASM files */
#if defined(_ASMLANGUAGE)
/* Various text section names */
@ -140,6 +145,14 @@
#define PINNED_NOINIT NOINIT
#endif /* CONFIG_LINKER_USE_PINNED_SECTION */
#if defined(CONFIG_LINKER_USE_ONDEMAND_SECTION)
#define ONDEMAND_TEXT ONDEMAND_TEXT_SECTION_NAME
#define ONDEMAND_RODATA ONDEMAND_RODATA_SECTION_NAME
#else
#define ONDEMAND_TEXT TEXT
#define ONDEMAND_RODATA RODATA
#endif /* CONFIG_LINKER_USE_ONDEMAND_SECTION */
#endif /* _ASMLANGUAGE */
#include <zephyr/linker/section_tags.h>