Skip to content

Commit cbbd857

Browse files
Nicolas Pitrenashif
Nicolas Pitre
authored andcommittedSep 10, 2024
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>
1 parent bd3b731 commit cbbd857

File tree

5 files changed

+84
-0
lines changed

5 files changed

+84
-0
lines changed
 

‎Kconfig.zephyr

+13
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,19 @@ config LINKER_USE_PINNED_SECTION
260260
Requires that pinned sections exist in the architecture, SoC,
261261
board or custom linker script.
262262

263+
config LINKER_USE_ONDEMAND_SECTION
264+
bool "Use Evictable Linker Section"
265+
depends on !LINKER_USE_PINNED_SECTION
266+
depends on !ARCH_MAPS_ALL_RAM
267+
help
268+
If enabled, the symbols which may be evicted from memory
269+
will be put into a linker section reserved for on-demand symbols.
270+
During boot, the corresponding memory will be mapped as paged out.
271+
This is conceptually the opposite of CONFIG_LINKER_USE_PINNED_SECTION.
272+
273+
Requires that on-demand sections exist in the architecture, SoC,
274+
board or custom linker script.
275+
263276
config LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT
264277
bool "Generic sections are present at boot" if DEMAND_PAGING && LINKER_USE_PINNED_SECTION
265278
default y

‎include/zephyr/arch/arm64/scripts/linker.ld

+32
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ MEMORY
7070
LINKER_DT_REGIONS()
7171
/* Used by and documented in include/linker/intlist.ld */
7272
IDT_LIST (wx) : ORIGIN = 0xFFFF8000, LENGTH = 32K
73+
#ifdef CONFIG_LINKER_USE_ONDEMAND_SECTION
74+
ONDEMAND (rx) : ORIGIN = (CONFIG_KERNEL_VM_BASE), LENGTH = (CONFIG_KERNEL_VM_SIZE)
75+
#endif
7376
}
7477

7578
ENTRY(CONFIG_KERNEL_ENTRY)
@@ -294,6 +297,35 @@ SECTIONS
294297

295298
GROUP_END(RAMABLE_REGION)
296299

300+
#ifdef CONFIG_LINKER_USE_ONDEMAND_SECTION
301+
. = z_mapped_end;
302+
MMU_ALIGN;
303+
lnkr_ondemand_start = .;
304+
305+
ONDEMAND_TEXT_SECTION_NAME (.) : AT(ADDR(_BSS_SECTION_NAME))
306+
{
307+
lnkr_ondemand_text_start = .;
308+
*(.ondemand_text)
309+
*(.ondemand_text.*)
310+
MMU_ALIGN;
311+
lnkr_ondemand_text_end = .;
312+
} > ONDEMAND
313+
lnkr_ondemand_text_size = SIZEOF(ONDEMAND_TEXT_SECTION_NAME);
314+
315+
ONDEMAND_RODATA_SECTION_NAME :
316+
{
317+
lnkr_ondemand_rodata_start = .;
318+
*(.ondemand_rodata)
319+
*(.ondemand_rodata.*)
320+
MMU_ALIGN;
321+
lnkr_ondemand_rodata_end = .;
322+
} > ONDEMAND
323+
lnkr_ondemand_rodata_size = SIZEOF(ONDEMAND_RODATA_SECTION_NAME);
324+
325+
lnkr_ondemand_end = .;
326+
lnkr_ondemand_load_start = LOADADDR(ONDEMAND_TEXT_SECTION_NAME);
327+
#endif
328+
297329
#include <zephyr/linker/debug-sections.ld>
298330

299331
SECTION_PROLOGUE(.ARM.attributes, 0,)

‎include/zephyr/linker/linker-defs.h

+18
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,24 @@ static inline bool lnkr_is_region_pinned(uint8_t *addr, size_t sz)
337337

338338
#endif /* CONFIG_LINKER_USE_PINNED_SECTION */
339339

340+
#ifdef CONFIG_LINKER_USE_ONDEMAND_SECTION
341+
/* lnkr_ondemand_start[] and lnkr_ondemand_end[] must encapsulate
342+
* all the on-demand sections as these are used by
343+
* the MMU code to mark the virtual pages with the appropriate backing store
344+
* location token to have them be paged in on demand.
345+
*/
346+
extern char lnkr_ondemand_start[];
347+
extern char lnkr_ondemand_end[];
348+
extern char lnkr_ondemand_load_start[];
349+
350+
extern char lnkr_ondemand_text_start[];
351+
extern char lnkr_ondemand_text_end[];
352+
extern char lnkr_ondemand_text_size[];
353+
extern char lnkr_ondemand_rodata_start[];
354+
extern char lnkr_ondemand_rodata_end[];
355+
extern char lnkr_ondemand_rodata_size[];
356+
357+
#endif /* CONFIG_LINKER_USE_ONDEMAND_SECTION */
340358
#endif /* ! _ASMLANGUAGE */
341359

342360
#endif /* ZEPHYR_INCLUDE_LINKER_LINKER_DEFS_H_ */

‎include/zephyr/linker/section_tags.h

+8
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@
100100
#define __pinned_noinit __noinit
101101
#endif /* CONFIG_LINKER_USE_PINNED_SECTION */
102102

103+
#if defined(CONFIG_LINKER_USE_ONDEMAND_SECTION)
104+
#define __ondemand_func Z_GENERIC_DOT_SECTION(ONDEMAND_TEXT_SECTION_NAME)
105+
#define __ondemand_rodata Z_GENERIC_DOT_SECTION(ONDEMAND_RODATA_SECTION_NAME)
106+
#else
107+
#define __ondemand_func
108+
#define __ondemand_rodata
109+
#endif /* CONFIG_LINKER_USE_ONDEMAND_SECTION */
110+
103111
#if defined(CONFIG_LINKER_USE_PINNED_SECTION)
104112
#define __isr __pinned_func
105113
#else

‎include/zephyr/linker/sections.h

+13
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@
101101
#define PINNED_NOINIT_SECTION_NAME pinned_noinit
102102
#endif
103103

104+
#if defined(CONFIG_LINKER_USE_ONDEMAND_SECTION)
105+
#define ONDEMAND_TEXT_SECTION_NAME ondemand_text
106+
#define ONDEMAND_RODATA_SECTION_NAME ondemand_rodata
107+
#endif
108+
104109
/* Short section references for use in ASM files */
105110
#if defined(_ASMLANGUAGE)
106111
/* Various text section names */
@@ -140,6 +145,14 @@
140145
#define PINNED_NOINIT NOINIT
141146
#endif /* CONFIG_LINKER_USE_PINNED_SECTION */
142147

148+
#if defined(CONFIG_LINKER_USE_ONDEMAND_SECTION)
149+
#define ONDEMAND_TEXT ONDEMAND_TEXT_SECTION_NAME
150+
#define ONDEMAND_RODATA ONDEMAND_RODATA_SECTION_NAME
151+
#else
152+
#define ONDEMAND_TEXT TEXT
153+
#define ONDEMAND_RODATA RODATA
154+
#endif /* CONFIG_LINKER_USE_ONDEMAND_SECTION */
155+
143156
#endif /* _ASMLANGUAGE */
144157

145158
#include <zephyr/linker/section_tags.h>

0 commit comments

Comments
 (0)
Please sign in to comment.