diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 89cdefdc87f..36b753dd4a8 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -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 diff --git a/include/zephyr/arch/arm64/scripts/linker.ld b/include/zephyr/arch/arm64/scripts/linker.ld index 67ac090705e..648ebba5690 100644 --- a/include/zephyr/arch/arm64/scripts/linker.ld +++ b/include/zephyr/arch/arm64/scripts/linker.ld @@ -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 SECTION_PROLOGUE(.ARM.attributes, 0,) diff --git a/include/zephyr/linker/linker-defs.h b/include/zephyr/linker/linker-defs.h index d860222ffac..5c1089c0fcf 100644 --- a/include/zephyr/linker/linker-defs.h +++ b/include/zephyr/linker/linker-defs.h @@ -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_ */ diff --git a/include/zephyr/linker/section_tags.h b/include/zephyr/linker/section_tags.h index 546ba4e09ad..560d7611b7a 100644 --- a/include/zephyr/linker/section_tags.h +++ b/include/zephyr/linker/section_tags.h @@ -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 diff --git a/include/zephyr/linker/sections.h b/include/zephyr/linker/sections.h index 1557d72d867..36159427fa6 100644 --- a/include/zephyr/linker/sections.h +++ b/include/zephyr/linker/sections.h @@ -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