blob: a72818c995c5c1a60f6ddcded73ac4a5a20d9572 [file] [log] [blame]
Roberto Vargase0e99462017-10-30 14:43:43 +00001/*
Masahiro Yamada0b67e562020-03-09 17:39:48 +09002 * Copyright (c) 2017-2020, 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
Masahiro Yamada0b67e562020-03-09 17:39:48 +09009#include <common/bl_common.ld.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010#include <lib/xlat_tables/xlat_tables_defs.h>
Roberto Vargase0e99462017-10-30 14:43:43 +000011
12OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
13OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
14ENTRY(bl2_entrypoint)
15
16MEMORY {
Jiafei Pan43a7bf42018-03-21 07:20:09 +000017#if BL2_IN_XIP_MEM
18 ROM (rx): ORIGIN = BL2_RO_BASE, LENGTH = BL2_RO_LIMIT - BL2_RO_BASE
19 RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE
20#else
Roberto Vargase0e99462017-10-30 14:43:43 +000021 RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
Jiafei Pan43a7bf42018-03-21 07:20:09 +000022#endif
Roberto Vargase0e99462017-10-30 14:43:43 +000023}
24
Masahiro Yamada5289b672019-06-14 17:49:17 +090025#if !BL2_IN_XIP_MEM
26#define ROM RAM
27#endif
Roberto Vargase0e99462017-10-30 14:43:43 +000028
29SECTIONS
30{
Jiafei Pan43a7bf42018-03-21 07:20:09 +000031#if BL2_IN_XIP_MEM
32 . = BL2_RO_BASE;
33 ASSERT(. == ALIGN(PAGE_SIZE),
34 "BL2_RO_BASE address is not aligned on a page boundary.")
35#else
Roberto Vargase0e99462017-10-30 14:43:43 +000036 . = BL2_BASE;
37 ASSERT(. == ALIGN(PAGE_SIZE),
38 "BL2_BASE address is not aligned on a page boundary.")
Jiafei Pan43a7bf42018-03-21 07:20:09 +000039#endif
Roberto Vargase0e99462017-10-30 14:43:43 +000040
41#if SEPARATE_CODE_AND_RODATA
42 .text . : {
43 __TEXT_START__ = .;
Roberto Vargas51abc342017-11-17 10:51:54 +000044 __TEXT_RESIDENT_START__ = .;
45 *bl2_el3_entrypoint.o(.text*)
46 *(.text.asm.*)
47 __TEXT_RESIDENT_END__ = .;
Samuel Holland23f5e542019-10-20 16:11:25 -050048 *(SORT_BY_ALIGNMENT(.text*))
Roberto Vargase0e99462017-10-30 14:43:43 +000049 *(.vectors)
Roberto Vargasd93fde32018-04-11 11:53:31 +010050 . = ALIGN(PAGE_SIZE);
Roberto Vargase0e99462017-10-30 14:43:43 +000051 __TEXT_END__ = .;
Jiafei Pan43a7bf42018-03-21 07:20:09 +000052 } >ROM
Roberto Vargase0e99462017-10-30 14:43:43 +000053
54 .rodata . : {
55 __RODATA_START__ = .;
Samuel Holland23f5e542019-10-20 16:11:25 -050056 *(SORT_BY_ALIGNMENT(.rodata*))
Roberto Vargase0e99462017-10-30 14:43:43 +000057
58 /* Ensure 8-byte alignment for descriptors and ensure inclusion */
59 . = ALIGN(8);
60 __PARSER_LIB_DESCS_START__ = .;
61 KEEP(*(.img_parser_lib_descs))
62 __PARSER_LIB_DESCS_END__ = .;
63
64 /*
65 * Ensure 8-byte alignment for cpu_ops so that its fields are also
66 * aligned. Also ensure cpu_ops inclusion.
67 */
68 . = ALIGN(8);
69 __CPU_OPS_START__ = .;
70 KEEP(*(cpu_ops))
71 __CPU_OPS_END__ = .;
72
Masahiro Yamada65d699d2020-01-17 13:45:02 +090073 /*
74 * Keep the .got section in the RO section as it is patched
75 * prior to enabling the MMU and having the .got in RO is better for
76 * security. GOT is a table of addresses so ensure 8-byte alignment.
77 */
78 . = ALIGN(8);
79 __GOT_START__ = .;
80 *(.got)
81 __GOT_END__ = .;
82
Roberto Vargasd93fde32018-04-11 11:53:31 +010083 . = ALIGN(PAGE_SIZE);
Roberto Vargase0e99462017-10-30 14:43:43 +000084 __RODATA_END__ = .;
Jiafei Pan43a7bf42018-03-21 07:20:09 +000085 } >ROM
Roberto Vargas51abc342017-11-17 10:51:54 +000086
87 ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE,
88 "Resident part of BL2 has exceeded its limit.")
Roberto Vargase0e99462017-10-30 14:43:43 +000089#else
90 ro . : {
91 __RO_START__ = .;
Roberto Vargas51abc342017-11-17 10:51:54 +000092 __TEXT_RESIDENT_START__ = .;
93 *bl2_el3_entrypoint.o(.text*)
94 *(.text.asm.*)
95 __TEXT_RESIDENT_END__ = .;
Samuel Holland23f5e542019-10-20 16:11:25 -050096 *(SORT_BY_ALIGNMENT(.text*))
97 *(SORT_BY_ALIGNMENT(.rodata*))
Roberto Vargase0e99462017-10-30 14:43:43 +000098
99 /*
100 * Ensure 8-byte alignment for cpu_ops so that its fields are also
101 * aligned. Also ensure cpu_ops inclusion.
102 */
103 . = ALIGN(8);
104 __CPU_OPS_START__ = .;
105 KEEP(*(cpu_ops))
106 __CPU_OPS_END__ = .;
107
108 /* Ensure 8-byte alignment for descriptors and ensure inclusion */
109 . = ALIGN(8);
110 __PARSER_LIB_DESCS_START__ = .;
111 KEEP(*(.img_parser_lib_descs))
112 __PARSER_LIB_DESCS_END__ = .;
113
Masahiro Yamada65d699d2020-01-17 13:45:02 +0900114 /*
115 * Keep the .got section in the RO section as it is patched
116 * prior to enabling the MMU and having the .got in RO is better for
117 * security. GOT is a table of addresses so ensure 8-byte alignment.
118 */
119 . = ALIGN(8);
120 __GOT_START__ = .;
121 *(.got)
122 __GOT_END__ = .;
123
Roberto Vargase0e99462017-10-30 14:43:43 +0000124 *(.vectors)
125 __RO_END_UNALIGNED__ = .;
126 /*
127 * Memory page(s) mapped to this section will be marked as
128 * read-only, executable. No RW data from the next section must
129 * creep in. Ensure the rest of the current memory page is unused.
130 */
Roberto Vargasd93fde32018-04-11 11:53:31 +0100131 . = ALIGN(PAGE_SIZE);
Roberto Vargase0e99462017-10-30 14:43:43 +0000132
133 __RO_END__ = .;
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000134 } >ROM
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000135#endif
Roberto Vargase0e99462017-10-30 14:43:43 +0000136
137 ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
138 "cpu_ops not defined for this platform.")
139
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000140#if BL2_IN_XIP_MEM
141 . = BL2_RW_BASE;
142 ASSERT(BL2_RW_BASE == ALIGN(PAGE_SIZE),
143 "BL2_RW_BASE address is not aligned on a page boundary.")
144#endif
145
Roberto Vargase0e99462017-10-30 14:43:43 +0000146 /*
147 * Define a linker symbol to mark start of the RW memory area for this
148 * image.
149 */
150 __RW_START__ = . ;
151
152 /*
153 * .data must be placed at a lower address than the stacks if the stack
154 * protector is enabled. Alternatively, the .data.stack_protector_canary
155 * section can be placed independently of the main .data section.
156 */
157 .data . : {
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000158 __DATA_RAM_START__ = .;
Samuel Holland23f5e542019-10-20 16:11:25 -0500159 *(SORT_BY_ALIGNMENT(.data*))
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000160 __DATA_RAM_END__ = .;
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000161 } >RAM AT>ROM
Roberto Vargase0e99462017-10-30 14:43:43 +0000162
Masahiro Yamada65d699d2020-01-17 13:45:02 +0900163 /*
164 * .rela.dyn needs to come after .data for the read-elf utility to parse
165 * this section correctly. Ensure 8-byte alignment so that the fields of
166 * RELA data structure are aligned.
167 */
168 . = ALIGN(8);
169 __RELA_START__ = .;
170 .rela.dyn . : {
171 } >RAM
172 __RELA_END__ = .;
173
Roberto Vargase0e99462017-10-30 14:43:43 +0000174 stacks (NOLOAD) : {
175 __STACKS_START__ = .;
176 *(tzfw_normal_stacks)
177 __STACKS_END__ = .;
178 } >RAM
179
180 /*
181 * The .bss section gets initialised to 0 at runtime.
182 * Its base address should be 16-byte aligned for better performance of the
183 * zero-initialization code.
184 */
185 .bss : ALIGN(16) {
186 __BSS_START__ = .;
187 *(SORT_BY_ALIGNMENT(.bss*))
188 *(COMMON)
189 __BSS_END__ = .;
190 } >RAM
191
Masahiro Yamada0b67e562020-03-09 17:39:48 +0900192 XLAT_TABLE_SECTION >RAM
Roberto Vargase0e99462017-10-30 14:43:43 +0000193
194#if USE_COHERENT_MEM
195 /*
196 * The base address of the coherent memory section must be page-aligned (4K)
197 * to guarantee that the coherent data are stored on their own pages and
198 * are not mixed with normal data. This is required to set up the correct
199 * memory attributes for the coherent data page tables.
200 */
201 coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
202 __COHERENT_RAM_START__ = .;
203 *(tzfw_coherent_mem)
204 __COHERENT_RAM_END_UNALIGNED__ = .;
205 /*
206 * Memory page(s) mapped to this section will be marked
207 * as device memory. No other unexpected data must creep in.
208 * Ensure the rest of the current memory page is unused.
209 */
Roberto Vargasd93fde32018-04-11 11:53:31 +0100210 . = ALIGN(PAGE_SIZE);
Roberto Vargase0e99462017-10-30 14:43:43 +0000211 __COHERENT_RAM_END__ = .;
212 } >RAM
213#endif
214
215 /*
216 * Define a linker symbol to mark end of the RW memory area for this
217 * image.
218 */
219 __RW_END__ = .;
220 __BL2_END__ = .;
221
Masahiro Yamada65d699d2020-01-17 13:45:02 +0900222 /DISCARD/ : {
223 *(.dynsym .dynstr .hash .gnu.hash)
224 }
225
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000226#if BL2_IN_XIP_MEM
227 __BL2_RAM_START__ = ADDR(.data);
228 __BL2_RAM_END__ = .;
229
230 __DATA_ROM_START__ = LOADADDR(.data);
231 __DATA_SIZE__ = SIZEOF(.data);
232
233 /*
234 * The .data section is the last PROGBITS section so its end marks the end
235 * of BL2's RO content in XIP memory..
236 */
237 __BL2_ROM_END__ = __DATA_ROM_START__ + __DATA_SIZE__;
238 ASSERT(__BL2_ROM_END__ <= BL2_RO_LIMIT,
239 "BL2's RO content has exceeded its limit.")
240#endif
Roberto Vargase0e99462017-10-30 14:43:43 +0000241 __BSS_SIZE__ = SIZEOF(.bss);
242
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000243
Roberto Vargase0e99462017-10-30 14:43:43 +0000244#if USE_COHERENT_MEM
245 __COHERENT_RAM_UNALIGNED_SIZE__ =
246 __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
247#endif
248
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000249#if BL2_IN_XIP_MEM
250 ASSERT(. <= BL2_RW_LIMIT, "BL2's RW content has exceeded its limit.")
251#else
Roberto Vargase0e99462017-10-30 14:43:43 +0000252 ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
Jiafei Pan43a7bf42018-03-21 07:20:09 +0000253#endif
Roberto Vargase0e99462017-10-30 14:43:43 +0000254}