blob: b6570ee3e2745dc6781ff6e555e3eb77f1181c0f [file] [log] [blame]
Roberto Vargase0e99462017-10-30 14:43:43 +00001/*
Samuel Holland23f5e542019-10-20 16:11:25 -05002 * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
Roberto Vargase0e99462017-10-30 14:43:43 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <platform_def.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00008
9#include <lib/xlat_tables/xlat_tables_defs.h>
Roberto Vargase0e99462017-10-30 14:43:43 +000010
11OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
12OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
13ENTRY(bl2_entrypoint)
14
15MEMORY {
Jiafei Pan43a7bf42018-03-21 07:20:09 +000016#if BL2_IN_XIP_MEM
17 ROM (rx): ORIGIN = BL2_RO_BASE, LENGTH = BL2_RO_LIMIT - BL2_RO_BASE
18 RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE
19#else
Roberto Vargase0e99462017-10-30 14:43:43 +000020 RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
Jiafei Pan43a7bf42018-03-21 07:20:09 +000021#endif
Roberto Vargase0e99462017-10-30 14:43:43 +000022}
23
Masahiro Yamada5289b672019-06-14 17:49:17 +090024#if !BL2_IN_XIP_MEM
25#define ROM RAM
26#endif
Roberto Vargase0e99462017-10-30 14:43:43 +000027
28SECTIONS
29{
Jiafei Pan43a7bf42018-03-21 07:20:09 +000030#if BL2_IN_XIP_MEM
31 . = BL2_RO_BASE;
32 ASSERT(. == ALIGN(PAGE_SIZE),
33 "BL2_RO_BASE address is not aligned on a page boundary.")
34#else
Roberto Vargase0e99462017-10-30 14:43:43 +000035 . = BL2_BASE;
36 ASSERT(. == ALIGN(PAGE_SIZE),
37 "BL2_BASE address is not aligned on a page boundary.")
Jiafei Pan43a7bf42018-03-21 07:20:09 +000038#endif
Roberto Vargase0e99462017-10-30 14:43:43 +000039
40#if SEPARATE_CODE_AND_RODATA
41 .text . : {
42 __TEXT_START__ = .;
Roberto Vargas51abc342017-11-17 10:51:54 +000043 __TEXT_RESIDENT_START__ = .;
44 *bl2_el3_entrypoint.o(.text*)
45 *(.text.asm.*)
46 __TEXT_RESIDENT_END__ = .;
Samuel Holland23f5e542019-10-20 16:11:25 -050047 *(SORT_BY_ALIGNMENT(.text*))
Roberto Vargase0e99462017-10-30 14:43:43 +000048 *(.vectors)
Roberto Vargasd93fde32018-04-11 11:53:31 +010049 . = ALIGN(PAGE_SIZE);
Roberto Vargase0e99462017-10-30 14:43:43 +000050 __TEXT_END__ = .;
Jiafei Pan43a7bf42018-03-21 07:20:09 +000051 } >ROM
Roberto Vargase0e99462017-10-30 14:43:43 +000052
53 .rodata . : {
54 __RODATA_START__ = .;
Samuel Holland23f5e542019-10-20 16:11:25 -050055 *(SORT_BY_ALIGNMENT(.rodata*))
Roberto Vargase0e99462017-10-30 14:43:43 +000056
57 /* Ensure 8-byte alignment for descriptors and ensure inclusion */
58 . = ALIGN(8);
59 __PARSER_LIB_DESCS_START__ = .;
60 KEEP(*(.img_parser_lib_descs))
61 __PARSER_LIB_DESCS_END__ = .;
62
63 /*
64 * Ensure 8-byte alignment for cpu_ops so that its fields are also
65 * aligned. Also ensure cpu_ops inclusion.
66 */
67 . = ALIGN(8);
68 __CPU_OPS_START__ = .;
69 KEEP(*(cpu_ops))
70 __CPU_OPS_END__ = .;
71
Masahiro Yamada65d699d2020-01-17 13:45:02 +090072 /*
73 * Keep the .got section in the RO section as it is patched
74 * prior to enabling the MMU and having the .got in RO is better for
75 * security. GOT is a table of addresses so ensure 8-byte alignment.
76 */
77 . = ALIGN(8);
78 __GOT_START__ = .;
79 *(.got)
80 __GOT_END__ = .;
81
Roberto Vargasd93fde32018-04-11 11:53:31 +010082 . = ALIGN(PAGE_SIZE);
Roberto Vargase0e99462017-10-30 14:43:43 +000083 __RODATA_END__ = .;
Jiafei Pan43a7bf42018-03-21 07:20:09 +000084 } >ROM
Roberto Vargas51abc342017-11-17 10:51:54 +000085
86 ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE,
87 "Resident part of BL2 has exceeded its limit.")
Roberto Vargase0e99462017-10-30 14:43:43 +000088#else
89 ro . : {
90 __RO_START__ = .;
Roberto Vargas51abc342017-11-17 10:51:54 +000091 __TEXT_RESIDENT_START__ = .;
92 *bl2_el3_entrypoint.o(.text*)
93 *(.text.asm.*)
94 __TEXT_RESIDENT_END__ = .;
Samuel Holland23f5e542019-10-20 16:11:25 -050095 *(SORT_BY_ALIGNMENT(.text*))
96 *(SORT_BY_ALIGNMENT(.rodata*))
Roberto Vargase0e99462017-10-30 14:43:43 +000097
98 /*
99 * Ensure 8-byte alignment for cpu_ops so that its fields are also
100 * aligned. Also ensure cpu_ops inclusion.
101 */
102 . = ALIGN(8);
103 __CPU_OPS_START__ = .;
104 KEEP(*(cpu_ops))
105 __CPU_OPS_END__ = .;
106
107 /* Ensure 8-byte alignment for descriptors and ensure inclusion */
108 . = ALIGN(8);
109 __PARSER_LIB_DESCS_START__ = .;
110 KEEP(*(.img_parser_lib_descs))
111 __PARSER_LIB_DESCS_END__ = .;
112
Masahiro Yamada65d699d2020-01-17 13:45:02 +0900113 /*
114 * Keep the .got section in the RO section as it is patched
115 * prior to enabling the MMU and having the .got in RO is better for
116 * security. GOT is a table of addresses so ensure 8-byte alignment.
117 */
118 . = ALIGN(8);
119 __GOT_START__ = .;
120 *(.got)
121 __GOT_END__ = .;
122
Roberto Vargase0e99462017-10-30 14:43:43 +0000123 *(.vectors)
124 __RO_END_UNALIGNED__ = .;
125 /*
126 * Memory page(s) mapped to this section will be marked as
127 * read-only, executable. No RW data from the next section must
128 * creep in. Ensure the rest of the current memory page is unused.
129 */
Roberto Vargasd93fde32018-04-11 11:53:31 +0100130 . = ALIGN(PAGE_SIZE);
Roberto Vargase0e99462017-10-30 14:43:43 +0000131
132 __RO_END__ = .;
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000133 } >ROM
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000134#endif
Roberto Vargase0e99462017-10-30 14:43:43 +0000135
136 ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
137 "cpu_ops not defined for this platform.")
138
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000139#if BL2_IN_XIP_MEM
140 . = BL2_RW_BASE;
141 ASSERT(BL2_RW_BASE == ALIGN(PAGE_SIZE),
142 "BL2_RW_BASE address is not aligned on a page boundary.")
143#endif
144
Roberto Vargase0e99462017-10-30 14:43:43 +0000145 /*
146 * Define a linker symbol to mark start of the RW memory area for this
147 * image.
148 */
149 __RW_START__ = . ;
150
151 /*
152 * .data must be placed at a lower address than the stacks if the stack
153 * protector is enabled. Alternatively, the .data.stack_protector_canary
154 * section can be placed independently of the main .data section.
155 */
156 .data . : {
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000157 __DATA_RAM_START__ = .;
Samuel Holland23f5e542019-10-20 16:11:25 -0500158 *(SORT_BY_ALIGNMENT(.data*))
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000159 __DATA_RAM_END__ = .;
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000160 } >RAM AT>ROM
Roberto Vargase0e99462017-10-30 14:43:43 +0000161
Masahiro Yamada65d699d2020-01-17 13:45:02 +0900162 /*
163 * .rela.dyn needs to come after .data for the read-elf utility to parse
164 * this section correctly. Ensure 8-byte alignment so that the fields of
165 * RELA data structure are aligned.
166 */
167 . = ALIGN(8);
168 __RELA_START__ = .;
169 .rela.dyn . : {
170 } >RAM
171 __RELA_END__ = .;
172
Roberto Vargase0e99462017-10-30 14:43:43 +0000173 stacks (NOLOAD) : {
174 __STACKS_START__ = .;
175 *(tzfw_normal_stacks)
176 __STACKS_END__ = .;
177 } >RAM
178
179 /*
180 * The .bss section gets initialised to 0 at runtime.
181 * Its base address should be 16-byte aligned for better performance of the
182 * zero-initialization code.
183 */
184 .bss : ALIGN(16) {
185 __BSS_START__ = .;
186 *(SORT_BY_ALIGNMENT(.bss*))
187 *(COMMON)
188 __BSS_END__ = .;
189 } >RAM
190
191 /*
192 * The xlat_table section is for full, aligned page tables (4K).
193 * Removing them from .bss avoids forcing 4K alignment on
Antonio Nino Diaz7c2a3ca2018-02-23 15:07:54 +0000194 * the .bss section. The tables are initialized to zero by the translation
195 * tables library.
Roberto Vargase0e99462017-10-30 14:43:43 +0000196 */
197 xlat_table (NOLOAD) : {
198 *(xlat_table)
199 } >RAM
200
201#if USE_COHERENT_MEM
202 /*
203 * The base address of the coherent memory section must be page-aligned (4K)
204 * to guarantee that the coherent data are stored on their own pages and
205 * are not mixed with normal data. This is required to set up the correct
206 * memory attributes for the coherent data page tables.
207 */
208 coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
209 __COHERENT_RAM_START__ = .;
210 *(tzfw_coherent_mem)
211 __COHERENT_RAM_END_UNALIGNED__ = .;
212 /*
213 * Memory page(s) mapped to this section will be marked
214 * as device memory. No other unexpected data must creep in.
215 * Ensure the rest of the current memory page is unused.
216 */
Roberto Vargasd93fde32018-04-11 11:53:31 +0100217 . = ALIGN(PAGE_SIZE);
Roberto Vargase0e99462017-10-30 14:43:43 +0000218 __COHERENT_RAM_END__ = .;
219 } >RAM
220#endif
221
222 /*
223 * Define a linker symbol to mark end of the RW memory area for this
224 * image.
225 */
226 __RW_END__ = .;
227 __BL2_END__ = .;
228
Masahiro Yamada65d699d2020-01-17 13:45:02 +0900229 /DISCARD/ : {
230 *(.dynsym .dynstr .hash .gnu.hash)
231 }
232
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000233#if BL2_IN_XIP_MEM
234 __BL2_RAM_START__ = ADDR(.data);
235 __BL2_RAM_END__ = .;
236
237 __DATA_ROM_START__ = LOADADDR(.data);
238 __DATA_SIZE__ = SIZEOF(.data);
239
240 /*
241 * The .data section is the last PROGBITS section so its end marks the end
242 * of BL2's RO content in XIP memory..
243 */
244 __BL2_ROM_END__ = __DATA_ROM_START__ + __DATA_SIZE__;
245 ASSERT(__BL2_ROM_END__ <= BL2_RO_LIMIT,
246 "BL2's RO content has exceeded its limit.")
247#endif
Roberto Vargase0e99462017-10-30 14:43:43 +0000248 __BSS_SIZE__ = SIZEOF(.bss);
249
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000250
Roberto Vargase0e99462017-10-30 14:43:43 +0000251#if USE_COHERENT_MEM
252 __COHERENT_RAM_UNALIGNED_SIZE__ =
253 __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
254#endif
255
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000256#if BL2_IN_XIP_MEM
257 ASSERT(. <= BL2_RW_LIMIT, "BL2's RW content has exceeded its limit.")
258#else
Roberto Vargase0e99462017-10-30 14:43:43 +0000259 ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000260#endif
Roberto Vargase0e99462017-10-30 14:43:43 +0000261}