1/* Excerpts written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> */
2/* Modified for i386/x86-64 Xen by Keir Fraser */
3/* Modified for ARM Xen by Ian Campbell */
4
5#include <xen/cache.h>
6#include <xen/lib.h>
7#include <xen/xen.lds.h>
8#include <asm/page.h>
9
10ENTRY(start)
11
12#if defined(__arm__)
13#define FORMAT arm
14#elif defined(__aarch64__)
15#define FORMAT aarch64
16#endif
17
18OUTPUT_ARCH(FORMAT)
19
20PHDRS
21{
22  text PT_LOAD ;
23#if defined(BUILD_ID)
24  note PT_NOTE ;
25#endif
26}
27SECTIONS
28{
29  . = XEN_VIRT_START;
30  _start = .;
31  .text : {
32       _stext = .;             /* Text section */
33       _idmap_start = .;
34       *(.text.header)
35       *(.text.idmap)
36       *(.rodata.idmap)
37       *(.data.idmap)
38       _idmap_end = .;
39
40       *(.text.cold)
41       *(.text.unlikely .text.*_unlikely .text.unlikely.*)
42
43       *(.text)
44#ifdef CONFIG_CC_SPLIT_SECTIONS
45       *(.text.*)
46#endif
47
48       *(.gnu.warning)
49       _etext = .;             /* End of text section */
50  } :text = 0x9090
51
52  . = ALIGN(PAGE_SIZE);
53  .rodata : {
54        _srodata = .;          /* Read-only data */
55
56        BUGFRAMES
57
58       *(.rodata)
59       *(.rodata.*)
60       VPCI_ARRAY
61       *(.data.rel.ro)
62       *(.data.rel.ro.*)
63
64       . = ALIGN(4);
65       __proc_info_start = .;
66       *(.proc.info)
67       __proc_info_end = .;
68  } :text
69
70#if defined(BUILD_ID)
71  . = ALIGN(4);
72  .note.gnu.build-id : {
73       __note_gnu_build_id_start = .;
74       *(.note.gnu.build-id)
75       __note_gnu_build_id_end = .;
76  } :note :text
77#endif
78  _erodata = .;                /* End of read-only data */
79
80  . = ALIGN(PAGE_SIZE);
81  .data.ro_after_init : {
82      __ro_after_init_start = .;
83      *(.data.ro_after_init)
84      . = ALIGN(PAGE_SIZE);
85      __ro_after_init_end = .;
86  } : text
87
88  .data.read_mostly : {
89       *(.data.read_mostly)
90  } :text
91
92  . = ALIGN(SMP_CACHE_BYTES);
93  .data : {                    /* Data */
94       *(.data.page_aligned)
95       . = ALIGN(8);
96       __start_schedulers_array = .;
97       *(.data.schedulers)
98       __end_schedulers_array = .;
99
100       HYPFS_PARAM
101
102       *(.data .data.*)
103       CONSTRUCTORS
104  } :text
105
106  . = ALIGN(8);
107  .arch.info : {
108      _splatform = .;
109      *(.arch.info)
110      _eplatform = .;
111  } :text
112
113  DT_DEV_INFO
114
115#ifdef CONFIG_ACPI
116  ACPI_DEV_INFO
117#endif
118
119  . = ALIGN(8);
120  .teemediator.info : {
121      _steemediator = .;
122      *(.teemediator.info)
123      _eteemediator = .;
124  } :text
125
126  . = ALIGN(PAGE_SIZE);             /* Init code and data */
127  __init_begin = .;
128  .init.text : {
129       _sinittext = .;
130       *(.init.text)
131       _einittext = .;
132       . = ALIGN(PAGE_SIZE);        /* Avoid mapping alt insns executable */
133       *(.altinstr_replacement)
134  } :text
135  . = ALIGN(PAGE_SIZE);
136  __init_data_begin = .;
137  .init.data : {
138       *(.init.rodata)
139       *(.init.rodata.*)
140
141       . = ALIGN(POINTER_ALIGN);
142       __setup_start = .;
143       *(.init.setup)
144       __setup_end = .;
145
146       __initcall_start = .;
147       *(.initcallpresmp.init)
148       __presmp_initcall_end = .;
149       *(.initcall1.init)
150       __initcall_end = .;
151
152       . = ALIGN(4);
153       __alt_instructions = .;
154       *(.altinstructions)
155       __alt_instructions_end = .;
156
157       LOCK_PROFILE_DATA
158
159       *(.init.data)
160       *(.init.data.rel)
161       *(.init.data.rel.*)
162
163       . = ALIGN(8);
164       __ctors_start = .;
165       *(.ctors)
166       *(.init_array)
167       *(SORT(.init_array.*))
168       __ctors_end = .;
169  } :text
170  __init_end_efi = .;
171  . = ALIGN(STACK_SIZE);
172  __init_end = .;
173
174  .bss : {                     /* BSS */
175       __bss_start = .;
176       *(.bss.stack_aligned)
177       *(.bss.page_aligned)
178       PERCPU_BSS
179       *(.bss .bss.*)
180       . = ALIGN(POINTER_ALIGN);
181       __bss_end = .;
182  } :text
183  . = ALIGN(PAGE_SIZE);
184  _end = . ;
185
186  /* Section for the device tree blob (if any). */
187  .dtb : { *(.dtb) } :text
188
189  DWARF2_DEBUG_SECTIONS
190
191  DISCARD_SECTIONS
192
193  STABS_DEBUG_SECTIONS
194
195  ELF_DETAILS_SECTIONS
196}
197
198PROVIDE(cpu_present_map = cpu_possible_map);
199
200/*
201 * The assembly code use _start and XEN_VIRT_START interchangeably to
202 * match the context.
203 */
204ASSERT(_start == XEN_VIRT_START, "_start != XEN_VIRT_START")
205#ifdef CONFIG_MPU
206/*
207 * On MPU based platforms, the starting address is to be provided by user.
208 * One need to check that it is 4KB aligned.
209 */
210ASSERT(IS_ALIGNED(_start,       4096), "starting address should be aligned to 4KB")
211#endif
212
213/*
214 * We require that Xen is loaded at a page boundary, so this ensures that any
215 * code running on the identity map cannot cross a section boundary.
216 */
217ASSERT(IS_ALIGNED(_idmap_start, PAGE_SIZE), "_idmap_start should be page-aligned")
218ASSERT(_idmap_end - _idmap_start <= PAGE_SIZE, "Identity mapped code is larger than a page size")
219
220/*
221 * __init_[begin|end] MUST be at word size boundary otherwise we cannot
222 * write fault instructions in the space properly.
223 */
224ASSERT(IS_ALIGNED(__init_begin,     4), "__init_begin is misaligned")
225ASSERT(IS_ALIGNED(__init_end,       4), "__init_end is misaligned")
226ASSERT(IS_ALIGNED(__bss_start,      POINTER_ALIGN), "__bss_start is misaligned")
227ASSERT(IS_ALIGNED(__bss_end,        POINTER_ALIGN), "__bss_end is misaligned")
228/* To simplify the logic in head.S, we want to _end to be page aligned */
229ASSERT(IS_ALIGNED(_end,             PAGE_SIZE), "_end is not page aligned")
230#ifdef CONFIG_MMU
231ASSERT((_end - _start) <= XEN_VIRT_SIZE, "Xen is too big")
232#endif
233