1/*
2 * Copyright (c) 2013-2014 Wind River Systems, Inc.
3 * Copyright (c) 2021 Intel Corporation
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#include <zephyr/devicetree.h>
9#include <zephyr/offsets.h>
10#include <zephyr/linker/linker-defs.h>
11#include <zephyr/linker/linker-tool.h>
12#include <zephyr/sys/util.h>
13#include <zephyr/kernel/mm.h>
14
15
16/* Bounds of physical RAM from DTS */
17#define PHYS_RAM_ADDR			DT_REG_ADDR(DT_CHOSEN(zephyr_sram))
18#define PHYS_RAM_SIZE			DT_REG_SIZE(DT_CHOSEN(zephyr_sram))
19
20/* Bounds of flash from DTS */
21#define FLASH_ROM_ADDR			DT_REG_ADDR(DT_CHOSEN(zephyr_flash))
22#define FLASH_ROM_SIZE			DT_REG_SIZE(DT_CHOSEN(zephyr_flash))
23
24/* Virtual base address for the kernel; with CONFIG_MMU this is not necessarily
25 * the same as its physical location, although an identity mapping for RAM
26 * is still supported by setting CONFIG_KERNEL_VM_BASE=CONFIG_SRAM_BASE_ADDRESS.
27 */
28#ifdef K_MEM_IS_VM_KERNEL
29
30#define KERNEL_BASE_ADDR \
31	(CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET)
32
33#define KERNEL_RAM_SIZE \
34	(CONFIG_KERNEL_VM_SIZE - CONFIG_KERNEL_VM_OFFSET)
35
36#define PHYS_RAM_AVAIL \
37	(PHYS_RAM_SIZE - CONFIG_SRAM_OFFSET)
38
39#else
40
41#define KERNEL_BASE_ADDR		(PHYS_RAM_ADDR + CONFIG_SRAM_OFFSET)
42#define KERNEL_RAM_SIZE			(PHYS_RAM_SIZE - CONFIG_SRAM_OFFSET)
43
44#endif
45
46/* "kernel RAM" for linker VMA allocations starts at the offset */
47
48/* Physical RAM location where the kernel image is loaded */
49#define PHYS_LOAD_ADDR			(PHYS_RAM_ADDR + CONFIG_SRAM_OFFSET)
50
51#ifdef CONFIG_USERSPACE
52#define SMEM_PARTITION_ALIGN(size)	MMU_PAGE_ALIGN_PERM
53#define APP_SHARED_ALIGN		MMU_PAGE_ALIGN_PERM
54#endif
55
56MEMORY
57    {
58#if defined(K_MEM_IS_VM_KERNEL)
59    ROM (rx)        : ORIGIN = PHYS_LOAD_ADDR, LENGTH = PHYS_RAM_AVAIL
60#endif
61    RAM (wx)        : ORIGIN = KERNEL_BASE_ADDR, LENGTH = KERNEL_RAM_SIZE
62
63#if defined(CONFIG_DEMAND_PAGING) && !defined(CONFIG_LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT)
64    FLASH (rw)      : ORIGIN = FLASH_ROM_ADDR, LENGTH = FLASH_ROM_SIZE
65#endif
66
67    /*
68     * On 32-bit x86, fake memory area for build-time IDT generation data.
69     *
70     * It doesn't matter where this region goes as it is stripped from the
71     * final ELF image. The address doesn't even have to be valid on the
72     * target. However, it shouldn't overlap any other regions.
73     */
74
75    IDT_LIST        : ORIGIN = 0xFFFF1000, LENGTH = 2K
76    }
77
78#if defined(K_MEM_IS_VM_KERNEL)
79	#define ROMABLE_REGION ROM
80	#define RAMABLE_REGION RAM
81#else
82	#define ROMABLE_REGION RAM
83	#define RAMABLE_REGION RAM
84#endif
85
86#ifdef CONFIG_MMU
87	#define MMU_PAGE_ALIGN		. = ALIGN(CONFIG_MMU_PAGE_SIZE);
88#else
89	#define MMU_PAGE_ALIGN
90#endif
91
92#if defined(CONFIG_DEMAND_PAGING) && !defined(CONFIG_LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT)
93
94#undef SECTION_PROLOGUE
95#define SECTION_PROLOGUE(name, options, align) \
96        name options : ALIGN_WITH_INPUT align
97
98#undef SECTION_DATA_PROLOGUE
99#define SECTION_DATA_PROLOGUE(name, options, align) \
100        name options : ALIGN_WITH_INPUT align
101
102#undef GROUP_ROM_LINK_IN
103#define GROUP_ROM_LINK_IN(vregion, lregion) > vregion AT > lregion
104
105#undef GROUP_DATA_LINK_IN
106#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion AT > lregion
107
108#undef GROUP_NOLOAD_LINK_IN
109#define GROUP_NOLOAD_LINK_IN(vregion, lregion) > vregion AT > lregion
110
111#endif
112
113/* Used to align areas with separate memory permission characteristics
114 * so that the page permissions can be set in the MMU. Without this,
115 * the kernel is just one blob with the same RWX permissions on all RAM
116 */
117#ifdef CONFIG_SRAM_REGION_PERMISSIONS
118	#define MMU_PAGE_ALIGN_PERM	MMU_PAGE_ALIGN
119#else
120	#define MMU_PAGE_ALIGN_PERM
121#endif
122
123/* For all source files under arch/x86/. */
124#define LIB_ARCH_X86_IN_SECT(lsect)					\
125	*libarch__x86__core.a.a:(.##lsect)				\
126	*libarch__x86__core.a:(.##lsect##.*)
127
128#ifdef CONFIG_MINIMAL_LIBC
129/* For all source files under lib/libc/minimal/.
130 * These files includes, for example, math and string functions.
131 */
132#define LIB_C_IN_SECT(lsect)						\
133	*liblib__libc__minimal.a:(.##lsect)				\
134	*liblib__libc__minimal.a:(.##lsect##.*)
135
136#endif /* CONFIG_MINIMAL_LIBC */
137
138#ifdef CONFIG_NEWLIB_LIBC
139/* For Newlib libc-hook.c. */
140#define LIB_C_IN_SECT(lsect)						\
141	*liblib__libc__newlib.a:libc-hooks.c.obj(.##lsect)		\
142	*liblib__libc__newlib.a:libc-hooks.c.obj(.##lsect##.*)
143
144#endif /* CONFIG_NEWLIB_LIBC */
145
146#ifdef CONFIG_PICOLIBC
147/* For Picolibc, all files under lib/libc/picolibc */
148#define LIB_C_IN_SECT(lsect)						\
149	*liblib__libc__picolibc.a:(.##lsect)				\
150	*liblib__libc__picolibc.a:(.##lsect##.*)
151
152#endif /* CONFIG_PICOLIBC */
153
154/*
155 * For drivers that are usually used (e.g. serial)
156 */
157#define LIB_DRIVERS_IN_SECT(lsect)					\
158	*libdrivers__serial.a:(.##lsect)				\
159	*libdrivers__serial.a:(.##lsect##.*)				\
160	*hpet.c.obj(.##lsect)						\
161	*hpet.c.obj(.##lsect##.*)					\
162	*intc_ioapic.c.obj(.##lsect)					\
163	*intc_ioapic.c.obj(.##lsect##.*)				\
164	*intc_loapic.c.obj(.##lsect)					\
165	*intc_loapic.c.obj(.##lsect##.*)				\
166	*intc_system_apic.c.obj(.##lsect)				\
167	*intc_system_apic.c.obj(.##lsect##.*)				\
168	*random_timer.c.obj(.##lsect)					\
169	*random_timer.c.obj(.##lsect##.*)				\
170	*uart_console.c.obj(.##lsect)					\
171	*uart_console.c.obj(.##lsect##.*)
172
173/* For all source files under kernel/. and kernel related files */
174#define LIB_KERNEL_IN_SECT(lsect)					\
175	*libkernel.a:(.##lsect)						\
176	*libkernel.a:(.##lsect##.*)					\
177	*libsubsys__demand_paging__*.a:(.##lsect)			\
178	*libsubsys__demand_paging__*.a:(.##lsect##.*)
179
180/* For particular file packaged in libzephyr.a. */
181#define LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, objfile)			\
182	*libzephyr.a:objfile.c.obj(.##lsect)				\
183	*libzephyr.a:objfile.c.obj(.##lsect##.*)
184
185/* For source files under lib/os/ with commonly used functions. */
186#define LIB_ZEPHYR_IN_SECT(lsect)					\
187	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, assert)			\
188	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, bitarray)			\
189	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, cbprintf_complete)	\
190	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, cbprintf_nano)		\
191	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, configs)			\
192	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, coverage)			\
193	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, heap)			\
194	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, heap-validate)		\
195	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, mutex)			\
196	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, notify)			\
197	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, printk)			\
198	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, sem)			\
199	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, stdout_console)		\
200	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, sys_clock_init)		\
201	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, rb)			\
202	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, tracing_none)		\
203	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, tracing_tracking)		\
204	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, thread_entry)		\
205	LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, work_q)
206
207/*
208 * Catch all for all internal/external kernel functions
209 * as they are usually defined as "static inline" where
210 * they are attached to the source which uses them.
211 * Hence the need to specify them here so they can be pinned.
212 */
213#define ZEPHYR_KERNEL_FUNCS_IN_SECT					\
214	*(.text.atomic_*)						\
215	*(.text.k_*)							\
216	*(.text.sys_*_bit)						\
217	*(.text.sys_bitfield_*)						\
218	*(.text.sys_clock_hw_cycles_per_sec)				\
219	*(.text.sys_cache_*)						\
220	*(.text.sys_dcache_*)						\
221	*(.text.sys_icache_*)						\
222	*(.text.sys_mutex_*)						\
223	*(.text.sys_notify_*)						\
224	*(.text.sys_dlist_*)						\
225	*(.text.sys_slist_*)						\
226	*(.text.sys_sflist_*)						\
227	*(.text.sys_sfnode_*)						\
228	*(.text.sys_io_*)						\
229	*(.text.sys_in*)						\
230	*(.text.sys_out*)						\
231	*(.text.sys_read*)						\
232	*(.text.sys_write*)						\
233	*(.text.sys_get_be*)						\
234	*(.text.sys_get_le*)						\
235	*(.text.sys_put_be*)						\
236	*(.text.sys_put_le*)						\
237	*(.text.sys_mem_swap)						\
238	*(.text.sys_memcpy_swap)					\
239	*(.text.z_*)
240
241/* For logging subsys */
242#define LIB_SUBSYS_LOGGING_IN_SECT(lsect)				\
243	*log_*.c.obj(.##lsect)						\
244	*log_*.c.obj(.##lsect.*)					\
245	*mpsc_pbuf.c.obj(.##lsect)					\
246	*mpsc_pbuf.c.obj(.##lsect.*)
247
248epoint = K_MEM_PHYS_ADDR(CONFIG_KERNEL_ENTRY);
249ENTRY(epoint)
250
251/* SECTIONS definitions */
252SECTIONS
253	{
254
255#include <zephyr/linker/rel-sections.ld>
256
257#ifdef CONFIG_LLEXT
258#include <zephyr/linker/llext-sections.ld>
259#endif
260
261    /DISCARD/ :
262	{
263	*(.plt)
264	}
265
266    /DISCARD/ :
267	{
268	*(.iplt)
269	}
270
271#ifdef CONFIG_LINKER_USE_BOOT_SECTION
272
273	SECTION_PROLOGUE(boot.text,,)
274	{
275#include <snippets-rom-start.ld>
276
277		MMU_PAGE_ALIGN
278		lnkr_boot_start = .;
279		z_mapped_start = .;
280
281		lnkr_boot_text_start = .;
282
283		KEEP(*(.boot_text.__start))
284		*(.boot_text)
285		*(.boot_text.*)
286
287		*(.text.k_mem_paging_backing_store_init)
288		*(.text.k_mem_paging_eviction_init)
289
290		MMU_PAGE_ALIGN_PERM
291
292		lnkr_boot_text_end = .;
293	} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
294
295	SECTION_PROLOGUE(boot.rodata,,)
296	{
297		MMU_PAGE_ALIGN_PERM
298
299		lnkr_boot_rodata_start = .;
300
301		*(.boot_rodata)
302		*(.boot_rodata.*)
303
304		MMU_PAGE_ALIGN_PERM
305
306		lnkr_boot_rodata_end = .;
307	} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
308
309	SECTION_PROLOGUE(boot.data,,)
310	{
311		MMU_PAGE_ALIGN_PERM
312
313		. = ALIGN(4);
314
315		lnkr_boot_data_start = .;
316
317		*(.boot_data)
318		*(.boot_data.*)
319
320		lnkr_boot_data_end = .;
321	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
322
323	SECTION_PROLOGUE(boot.bss, (NOLOAD),)
324	{
325		. = ALIGN(4);
326
327		lnkr_boot_bss_start = .;
328
329		*(.boot_bss)
330		*(.boot_bss.*)
331
332		lnkr_boot_bss_end = .;
333	} GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
334
335	SECTION_PROLOGUE(boot.noinit, (NOLOAD),)
336	{
337		. = ALIGN(4);
338
339		lnkr_boot_noinit_start = .;
340
341		*(.boot_noinit)
342		*(.boot_noinit.*)
343
344		lnkr_boot_noinit_end = .;
345
346		MMU_PAGE_ALIGN
347
348		lnkr_boot_end = .;
349	} GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
350
351	lnkr_boot_text_size = lnkr_boot_text_end - lnkr_boot_text_start;
352	lnkr_boot_rodata_size = lnkr_boot_rodata_end - lnkr_boot_rodata_start;
353	lnkr_boot_data_size = lnkr_boot_data_end - lnkr_boot_data_start;
354	lnkr_boot_bss_size = lnkr_boot_bss_end - lnkr_boot_bss_start;
355	lnkr_boot_noinit_size = lnkr_boot_noinit_end - lnkr_boot_noinit_start;
356
357#endif /* CONFIG_LINKER_USE_BOOT_SECTION */
358
359#ifdef CONFIG_LINKER_USE_PINNED_SECTION
360
361	SECTION_PROLOGUE(pinned.text,,)
362	{
363#ifndef CONFIG_LINKER_USE_BOOT_SECTION
364#include <snippets-rom-start.ld>
365#endif
366
367		MMU_PAGE_ALIGN
368
369		lnkr_pinned_start = .;
370
371#ifndef CONFIG_LINKER_USE_BOOT_SECTION
372		z_mapped_start = .;
373#endif
374
375		lnkr_pinned_text_start = .;
376
377		LIB_KERNEL_IN_SECT(text)
378		LIB_ARCH_X86_IN_SECT(text)
379		*(.text._OffsetAbsSyms)
380
381		*(.pinned_text)
382		*(.pinned_text.*)
383
384		LIB_ZEPHYR_IN_SECT(text)
385		LIB_C_IN_SECT(text)
386		LIB_DRIVERS_IN_SECT(text)
387		LIB_SUBSYS_LOGGING_IN_SECT(text)
388
389		*_divdi3.o(.text)
390		*_udivdi3.o(.text)
391		*_udivmoddi4.o(.text)
392		*_umoddi3.o(.text)
393		*_popcountsi2.o(.text)
394
395		*(.gnu.linkonce.t.exc_*)
396
397		*(.text.*.constprop)
398		*(.text.*.constprop.*)
399
400#if defined(CONFIG_NEWLIB_LIBC) || defined(CONFIG_PICOLIBC)
401		*libc*.a:(.text)
402		*libc*.a:(.text.*)
403#endif
404
405#ifdef CONFIG_COVERAGE
406		*(.text._sub_I_00100_0)
407#endif
408
409		ZEPHYR_KERNEL_FUNCS_IN_SECT
410
411#include <zephyr/linker/kobject-text.ld>
412
413		MMU_PAGE_ALIGN_PERM
414
415		lnkr_pinned_text_end = .;
416	} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
417
418	MMU_PAGE_ALIGN_PERM
419
420	lnkr_pinned_rodata_start = .;
421
422#include <zephyr/linker/common-rom.ld>
423/* Located in generated directory. This file is populated by calling
424 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs.
425 */
426#include <snippets-rom-sections.ld>
427#include <zephyr/linker/thread-local-storage.ld>
428
429	SECTION_PROLOGUE(pinned.rodata,,)
430	{
431#include <zephyr/arch/x86/ia32/scripts/static_intr.ld>
432
433		LIB_KERNEL_IN_SECT(rodata)
434		LIB_ARCH_X86_IN_SECT(rodata)
435
436		*(.pinned_rodata)
437		*(.pinned_rodata.*)
438
439		LIB_ZEPHYR_IN_SECT(rodata)
440		LIB_C_IN_SECT(rodata)
441		LIB_DRIVERS_IN_SECT(rodata)
442		LIB_SUBSYS_LOGGING_IN_SECT(rodata)
443
444		/* Static strings */
445		*(.rodata.str*.*)
446		*(.rodata.*.str*.*)
447
448#if defined(CONFIG_NEWLIB_LIBC) || defined(CONFIG_PICOLIBC)
449		*libc*.a:(.rodata)
450		*libc*.a:(.rodata.*)
451#endif
452
453#include <snippets-rodata.ld>
454#include <snippets-pinned-rodata.ld>
455
456#include <zephyr/linker/kobject-rom.ld>
457
458		MMU_PAGE_ALIGN_PERM
459
460		lnkr_pinned_rodata_end = .;
461	} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
462
463	SECTION_PROLOGUE(pinned.data,,)
464	{
465		MMU_PAGE_ALIGN_PERM
466
467		lnkr_pinned_data_start = .;
468
469		. = ALIGN(4);
470
471#include <zephyr/arch/x86/ia32/scripts/shared_kernel_pages.ld>
472#include <zephyr/arch/x86/ia32/scripts/dynamic_intr.ld>
473
474		LIB_KERNEL_IN_SECT(data)
475		LIB_ARCH_X86_IN_SECT(data)
476
477		*(.pinned_data)
478		*(.pinned_data.*)
479
480		LIB_ZEPHYR_IN_SECT(data)
481		LIB_C_IN_SECT(data)
482		LIB_DRIVERS_IN_SECT(data)
483		LIB_SUBSYS_LOGGING_IN_SECT(data)
484
485#ifdef CONFIG_COVERAGE
486		*(.data.__gcov_.*)
487
488		/*
489		 * This is for the struct gcov_info for
490		 * various functions.
491		 */
492		*(.data..LPBX*)
493#endif
494
495	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
496
497#include <zephyr/linker/common-ram.ld>
498#include <zephyr/arch/x86/pagetables.ld>
499#include <zephyr/linker/kobject-data.ld>
500
501/* Located in generated directory. This file is populated by the
502 * zephyr_linker_sources() Cmake function.
503 */
504#include <snippets-pinned-data-sections.ld>
505
506	lnkr_pinned_data_end = .;
507
508/* Located in generated directory. This file is populated by the
509 * zephyr_linker_sources() Cmake function.
510 */
511#include <snippets-pinned-ram-sections.ld>
512
513	SECTION_PROLOGUE(pinned.bss, (NOLOAD),)
514	{
515		. = ALIGN(4);
516
517		lnkr_pinned_bss_start = .;
518
519		LIB_KERNEL_IN_SECT(bss)
520		LIB_ARCH_X86_IN_SECT(bss)
521
522		*(.pinned_bss)
523		*(.pinned_bss.*)
524
525		LIB_ZEPHYR_IN_SECT(bss)
526		LIB_C_IN_SECT(bss)
527		LIB_DRIVERS_IN_SECT(bss)
528		LIB_SUBSYS_LOGGING_IN_SECT(bss)
529
530#ifdef CONFIG_COVERAGE
531		*(.bss.__gcov0.*)
532#endif
533
534		lnkr_pinned_bss_end = .;
535	} GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
536
537#ifdef CONFIG_USERSPACE
538	/* PINNED APP SHARED MEMORY REGION */
539#include <app_smem_pinned.ld>
540
541	_app_smem_pinned_size = _app_smem_pinned_end - _app_smem_pinned_start;
542	_app_smem_pinned_num_words = _app_smem_pinned_size >> 2;
543#endif /* CONFIG_USERSPACE */
544
545	SECTION_PROLOGUE(pinned.noinit, (NOLOAD),)
546	{
547		. = ALIGN(4);
548
549		lnkr_pinned_noinit_start = .;
550
551		LIB_KERNEL_IN_SECT(noinit)
552		LIB_ARCH_X86_IN_SECT(noinit)
553
554		*(.pinned_noinit)
555		*(.pinned_noinit.*)
556
557		LIB_ZEPHYR_IN_SECT(noinit)
558		LIB_C_IN_SECT(noinit)
559		LIB_DRIVERS_IN_SECT(noinit)
560		LIB_SUBSYS_LOGGING_IN_SECT(noinit)
561
562#ifdef CONFIG_ZTEST
563		/* For tests/kernel/mem_slab/ tests */
564		*(.noinit.*.k_mem_slab_buf_*)
565
566		/* For tests/kernel/mem_heap tests */
567		*(.noinit.*.kheap_buf_*)
568
569		/* Pin ztest_thread_stack.
570		 * This must be done or else double fault
571		 * may arise: testing exceptions while
572		 * page fault for the ztest stack.
573		 */
574		*libsubsys__testsuite__ztest.a:(.noinit.*)
575#endif
576
577		lnkr_pinned_noinit_end = .;
578
579		MMU_PAGE_ALIGN
580
581		lnkr_pinned_end = .;
582
583	} GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
584
585	lnkr_pinned_text_size = lnkr_pinned_text_end - lnkr_pinned_text_start;
586	lnkr_pinned_rodata_size = lnkr_pinned_rodata_end - lnkr_pinned_rodata_start;
587	lnkr_pinned_data_size = lnkr_pinned_data_end - lnkr_pinned_data_start;
588	lnkr_pinned_bss_size = lnkr_pinned_bss_end - lnkr_pinned_bss_start;
589	lnkr_pinned_noinit_size = lnkr_pinned_noinit_end - lnkr_pinned_noinit_start;
590
591#endif /* CONFIG_LINKER_USE_PINNED_SECTION */
592
593#if defined(CONFIG_DEMAND_PAGING) && !defined(CONFIG_LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT)
594/* From now on, put symbols into FLASH */
595#undef ROMABLE_REGION
596#define ROMABLE_REGION	FLASH
597
598	/* This is to align the following sections in flash
599	 * to their corresponding virtual addresses.
600	 * In other words, the offset from start of flash
601	 * for these sections would be the same from start of
602	 * their virtual addresses. This provides a simple and
603	 * direct mapping from backing store.
604	 */
605	flash_load_offset :
606	{
607		. = FLASH_ROM_ADDR + (lnkr_pinned_end - KERNEL_BASE_ADDR);
608	} > FLASH AT > FLASH
609
610#endif
611
612	GROUP_START(ROMABLE_REGION)
613
614	. = ALIGN(8);
615
616	SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
617	{
618	__text_region_start = .;
619
620#if !defined(CONFIG_LINKER_USE_BOOT_SECTION) || \
621    !defined(CONFIG_LINKER_USE_PINNED_SECTION)
622	z_mapped_start = .;
623#endif
624
625#if !defined(CONFIG_LINKER_USE_BOOT_SECTION) || \
626    !defined(CONFIG_LINKER_USE_PINNED_SECTION)
627/* Located in generated directory. This file is populated by calling
628 * zephyr_linker_sources(ROM_START ...). This typically contains the vector
629 * table and debug information.
630 */
631#include <snippets-rom-start.ld>
632#endif
633
634	/* Needs KEEP() as ENTRY() is given a physical address */
635	KEEP(*(.text.__start))
636	*(.text)
637	*(".text.*")
638	*(.gnu.linkonce.t.*)
639	*(.init)
640	*(.fini)
641	*(.eini)
642
643#ifndef CONFIG_LINKER_USE_PINNED_SECTION
644#include <zephyr/linker/kobject-text.ld>
645#endif
646
647	MMU_PAGE_ALIGN_PERM
648	} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
649
650	__text_region_end = .;
651	__text_region_size = __text_region_end - __text_region_start;
652	__rodata_region_start = .;
653
654#ifndef CONFIG_LINKER_USE_PINNED_SECTION
655#include <zephyr/linker/common-rom.ld>
656/* Located in generated directory. This file is populated by calling
657 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs.
658 */
659#include <snippets-rom-sections.ld>
660#include <zephyr/linker/thread-local-storage.ld>
661#endif
662
663	SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
664	{
665	*(.rodata)
666	*(".rodata.*")
667	*(.gnu.linkonce.r.*)
668
669#ifndef CONFIG_DYNAMIC_INTERRUPTS
670#ifndef CONFIG_LINKER_USE_PINNED_SECTION
671#include <zephyr/arch/x86/ia32/scripts/static_intr.ld>
672#endif /* !CONFIG_LINKER_USE_PINNED_SECTION */
673#endif /* CONFIG_DYNAMIC_INTERRUPTS */
674
675#ifndef CONFIG_LINKER_USE_PINNED_SECTION
676/* Located in generated directory. This file is populated by the
677 * zephyr_linker_sources() Cmake function.
678 */
679#include <snippets-rodata.ld>
680
681#include <zephyr/linker/kobject-rom.ld>
682#endif
683	} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
684
685#include <zephyr/linker/cplusplus-rom.ld>
686
687	MMU_PAGE_ALIGN_PERM
688	/* ROM ends here, position counter will now be in RAM areas */
689	__rodata_region_end = .;
690	__rodata_region_size = __rodata_region_end - __rodata_region_start;
691	GROUP_END(ROMABLE_REGION)
692	/*
693	 * Needed for dynamic linking which we do not have, do discard
694	 */
695	/DISCARD/ : {
696		*(.got.plt)
697		*(.igot.plt)
698		*(.got)
699		*(.igot)
700	}
701	/* RAMABLE_REGION */
702	GROUP_START(RAMABLE_REGION)
703
704/* Located in generated directory. This file is populated by the
705 * zephyr_linker_sources() Cmake function.
706 */
707#include <snippets-ram-sections.ld>
708
709#ifdef CONFIG_USERSPACE
710	/* APP SHARED MEMORY REGION */
711#include <app_smem.ld>
712
713	_image_ram_start = _app_smem_start;
714	_app_smem_size = _app_smem_end - _app_smem_start;
715	_app_smem_num_words = _app_smem_size >> 2;
716	_app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
717#endif /* CONFIG_USERSPACE */
718
719	SECTION_PROLOGUE(_BSS_SECTION_NAME, (NOLOAD),)
720	{
721	MMU_PAGE_ALIGN_PERM
722#if !defined(CONFIG_USERSPACE)
723	_image_ram_start = .;
724#endif
725	/*
726	 * For performance, BSS section is forced to be both 4 byte aligned and
727	 * a multiple of 4 bytes.
728	 */
729	. = ALIGN(4);
730	__kernel_ram_start = .;
731	__bss_start = .;
732
733	*(.bss)
734	*(".bss.*")
735	*(COMMON)
736	*(".kernel_bss.*")
737
738	/*
739	 * As memory is cleared in words only, it is simpler to ensure the BSS
740	 * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
741	 */
742	. = ALIGN(4);
743	__bss_end = .;
744	} GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
745
746	__bss_num_words	= (__bss_end - __bss_start) >> 2;
747
748#include <zephyr/linker/common-noinit.ld>
749
750	MMU_PAGE_ALIGN_PERM
751
752	SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
753	{
754
755	__data_ram_start = .;
756
757	*(.data)
758	*(".data.*")
759	*(".kernel.*")
760
761#ifdef CONFIG_DYNAMIC_INTERRUPTS
762#ifndef CONFIG_LINKER_USE_PINNED_SECTION
763#include <zephyr/arch/x86/ia32/scripts/dynamic_intr.ld>
764#endif /* !CONFIG_LINKER_USE_PINNED_SECTION */
765#endif /* CONFIG_DYNAMIC_INTERRUPTS */
766
767/* Located in generated directory. This file is populated by the
768 * zephyr_linker_sources() Cmake function.
769 */
770#include <snippets-rwdata.ld>
771
772#ifndef CONFIG_LINKER_USE_PINNED_SECTION
773#include <zephyr/arch/x86/ia32/scripts/shared_kernel_pages.ld>
774#endif /* !CONFIG_LINKER_USE_PINNED_SECTION */
775
776	. = ALIGN(4);
777	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
778
779	__data_rom_start = LOADADDR(_DATA_SECTION_NAME);
780
781#include <zephyr/linker/cplusplus-ram.ld>
782
783#ifndef CONFIG_LINKER_USE_PINNED_SECTION
784#include <zephyr/linker/common-ram.ld>
785#include <zephyr/arch/x86/pagetables.ld>
786
787/* Must be last in RAM */
788#include <zephyr/linker/kobject-data.ld>
789#endif /* !CONFIG_LINKER_USE_PINNED_SECTION */
790
791/* Located in generated directory. This file is populated by the
792 * zephyr_linker_sources() Cmake function.
793 */
794#include <snippets-data-sections.ld>
795
796	MMU_PAGE_ALIGN
797	__data_ram_end = .;
798
799	/* All unused memory also owned by the kernel for heaps */
800	__kernel_ram_end = KERNEL_BASE_ADDR + KERNEL_RAM_SIZE;
801	__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
802
803	_image_ram_all = (KERNEL_BASE_ADDR + KERNEL_RAM_SIZE) - _image_ram_start;
804
805	z_mapped_size = z_mapped_end - z_mapped_start;
806
807#ifndef LINKER_ZEPHYR_FINAL
808	/* static interrupts */
809	SECTION_PROLOGUE(intList,,)
810	{
811	KEEP(*(.spurIsr))
812	KEEP(*(.spurNoErrIsr))
813	KEEP(*(.intList))
814	KEEP(*(.gnu.linkonce.intList.*))
815	} > IDT_LIST
816#else
817	/DISCARD/ :
818	{
819	KEEP(*(.spurIsr))
820	KEEP(*(.spurNoErrIsr))
821	KEEP(*(.intList))
822	KEEP(*(.gnu.linkonce.intList.*))
823	}
824#endif
825
826
827
828/* Located in generated directory. This file is populated by the
829 * zephyr_linker_sources() Cmake function.
830 */
831#include <snippets-sections.ld>
832
833#define LAST_RAM_ALIGN MMU_PAGE_ALIGN
834
835#include <zephyr/linker/ram-end.ld>
836
837    GROUP_END(RAMABLE_REGION)
838
839#include <zephyr/linker/debug-sections.ld>
840
841	/DISCARD/ : { *(.note.GNU-stack) }
842
843	}
844