1/* 2 * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <common/bl_common.ld.h> 8#include <lib/xlat_tables/xlat_tables_defs.h> 9 10OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) 11OUTPUT_ARCH(PLATFORM_LINKER_ARCH) 12ENTRY(bl2_entrypoint) 13 14MEMORY { 15#if BL2_IN_XIP_MEM 16 ROM (rx): ORIGIN = BL2_RO_BASE, LENGTH = BL2_RO_LIMIT - BL2_RO_BASE 17 RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE 18#else /* BL2_IN_XIP_MEM */ 19 RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE 20#endif /* BL2_IN_XIP_MEM */ 21 22#if SEPARATE_BL2_NOLOAD_REGION 23 RAM_NOLOAD (rw!a): ORIGIN = BL2_NOLOAD_START, LENGTH = BL2_NOLOAD_LIMIT - BL2_NOLOAD_START 24#else /* SEPARATE_BL2_NOLOAD_REGION */ 25# define RAM_NOLOAD RAM 26#endif /* SEPARATE_BL2_NOLOAD_REGION */ 27} 28 29#if !BL2_IN_XIP_MEM 30# define ROM RAM 31#endif /* !BL2_IN_XIP_MEM */ 32 33SECTIONS { 34 RAM_REGION_START = ORIGIN(RAM); 35 RAM_REGION_LENGTH = LENGTH(RAM); 36#if BL2_IN_XIP_MEM 37 ROM_REGION_START = ORIGIN(ROM); 38 ROM_REGION_LENGTH = LENGTH(ROM); 39 40 . = BL2_RO_BASE; 41 42 ASSERT(. == ALIGN(PAGE_SIZE), 43 "BL2_RO_BASE address is not aligned on a page boundary.") 44#else /* BL2_IN_XIP_MEM */ 45 . = BL2_BASE; 46 47 ASSERT(. == ALIGN(PAGE_SIZE), 48 "BL2_BASE address is not aligned on a page boundary.") 49#endif /* BL2_IN_XIP_MEM */ 50 51#if SEPARATE_BL2_NOLOAD_REGION 52 RAM_NOLOAD_REGION_START = ORIGIN(RAM_NOLOAD); 53 RAM_NOLOAD_REGION_LENGTH = LENGTH(RAM_NOLOAD); 54#endif 55 56#if SEPARATE_CODE_AND_RODATA 57 .text . : { 58 __TEXT_START__ = .; 59 __TEXT_RESIDENT_START__ = .; 60 61 *bl2_el3_entrypoint.o(.text*) 62 *(.text.asm.*) 63 64 __TEXT_RESIDENT_END__ = .; 65 66 *(SORT_BY_ALIGNMENT(.text*)) 67 *(.vectors) 68 69 . = ALIGN(PAGE_SIZE); 70 71 __TEXT_END__ = .; 72 } >ROM 73 74 .rodata . : { 75 __RODATA_START__ = .; 76 77 *(SORT_BY_ALIGNMENT(.rodata*)) 78 79 RODATA_COMMON 80 81 . = ALIGN(PAGE_SIZE); 82 83 __RODATA_END__ = .; 84 } >ROM 85 86 ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE, 87 "Resident part of BL2 has exceeded its limit.") 88#else /* SEPARATE_CODE_AND_RODATA */ 89 .ro . : { 90 __RO_START__ = .; 91 __TEXT_RESIDENT_START__ = .; 92 93 *bl2_el3_entrypoint.o(.text*) 94 *(.text.asm.*) 95 96 __TEXT_RESIDENT_END__ = .; 97 98 *(SORT_BY_ALIGNMENT(.text*)) 99 *(SORT_BY_ALIGNMENT(.rodata*)) 100 101 RODATA_COMMON 102 103 *(.vectors) 104 105 __RO_END_UNALIGNED__ = .; 106 107 /* 108 * Memory page(s) mapped to this section will be marked as read-only, 109 * executable. No RW data from the next section must creep in. Ensure 110 * that the rest of the current memory page is unused. 111 */ 112 . = ALIGN(PAGE_SIZE); 113 114 __RO_END__ = .; 115 } >ROM 116#endif /* SEPARATE_CODE_AND_RODATA */ 117 118 ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__, 119 "cpu_ops not defined for this platform.") 120 121#if BL2_IN_XIP_MEM 122 ROM_REGION_END = .; 123 . = BL2_RW_BASE; 124 125 ASSERT(BL2_RW_BASE == ALIGN(PAGE_SIZE), 126 "BL2_RW_BASE address is not aligned on a page boundary.") 127#endif /* BL2_IN_XIP_MEM */ 128 129 __RW_START__ = .; 130 131 DATA_SECTION >RAM AT>ROM 132 133 __DATA_RAM_START__ = __DATA_START__; 134 __DATA_RAM_END__ = __DATA_END__; 135 136 RELA_SECTION >RAM 137 138#if SEPARATE_BL2_NOLOAD_REGION 139 SAVED_ADDR = .; 140 141 . = BL2_NOLOAD_START; 142 143 __BL2_NOLOAD_START__ = .; 144#endif /* SEPARATE_BL2_NOLOAD_REGION */ 145 146 STACK_SECTION >RAM_NOLOAD 147 BSS_SECTION >RAM_NOLOAD 148 XLAT_TABLE_SECTION >RAM_NOLOAD 149 150#if SEPARATE_BL2_NOLOAD_REGION 151 __BL2_NOLOAD_END__ = .; 152 RAM_NOLOAD_REGION_END = .; 153 154 . = SAVED_ADDR; 155#endif /* SEPARATE_BL2_NOLOAD_REGION */ 156 157#if USE_COHERENT_MEM 158 /* 159 * The base address of the coherent memory section must be page-aligned to 160 * guarantee that the coherent data are stored on their own pages and are 161 * not mixed with normal data. This is required to set up the correct 162 * memory attributes for the coherent data page tables. 163 */ 164 .coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) { 165 __COHERENT_RAM_START__ = .; 166 167 *(.tzfw_coherent_mem) 168 169 __COHERENT_RAM_END_UNALIGNED__ = .; 170 171 /* 172 * Memory page(s) mapped to this section will be marked as device 173 * memory. No other unexpected data must creep in. Ensure the rest of 174 * the current memory page is unused. 175 */ 176 . = ALIGN(PAGE_SIZE); 177 178 __COHERENT_RAM_END__ = .; 179 } >RAM 180#endif /* USE_COHERENT_MEM */ 181 182 __RW_END__ = .; 183 __BL2_END__ = .; 184 185 /DISCARD/ : { 186 *(.dynsym .dynstr .hash .gnu.hash) 187 } 188 189#if BL2_IN_XIP_MEM 190 __BL2_RAM_START__ = ADDR(.data); 191 __BL2_RAM_END__ = .; 192 193 __DATA_ROM_START__ = LOADADDR(.data); 194 __DATA_SIZE__ = SIZEOF(.data); 195 196 /* 197 * The .data section is the last PROGBITS section so its end marks the end 198 * of BL2's RO content in XIP memory. 199 */ 200 __BL2_ROM_END__ = __DATA_ROM_START__ + __DATA_SIZE__; 201 202 ASSERT(__BL2_ROM_END__ <= BL2_RO_LIMIT, 203 "BL2's RO content has exceeded its limit.") 204#endif /* BL2_IN_XIP_MEM */ 205 206 __BSS_SIZE__ = SIZEOF(.bss); 207 208#if USE_COHERENT_MEM 209 __COHERENT_RAM_UNALIGNED_SIZE__ = 210 __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__; 211#endif /* USE_COHERENT_MEM */ 212 213 RAM_REGION_END = .; 214#if BL2_IN_XIP_MEM 215 ASSERT(. <= BL2_RW_LIMIT, "BL2's RW content has exceeded its limit.") 216#else /* BL2_IN_XIP_MEM */ 217 ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.") 218#endif /* BL2_IN_XIP_MEM */ 219} 220