;/* ; * Copyright (c) 2009-2023 Arm Limited ; * ; * Licensed under the Apache License, Version 2.0 (the "License"); ; * you may not use this file except in compliance with the License. ; * You may obtain a copy of the License at ; * ; * http://www.apache.org/licenses/LICENSE-2.0 ; * ; * Unless required by applicable law or agreed to in writing, software ; * distributed under the License is distributed on an "AS IS" BASIS, ; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; * See the License for the specific language governing permissions and ; * limitations under the License. ; */ /* Linker script to configure memory regions. */ /* This file will be run trough the pre-processor. */ #include "region_defs.h" MEMORY { FLASH (rx) : ORIGIN = S_CODE_START, LENGTH = S_CODE_SIZE RAM (rwx) : ORIGIN = S_DATA_START, LENGTH = S_DATA_SIZE } __heap_size__ = HEAP_SIZE; __stack_size__ = STACK_SIZE; /* Library configurations */ GROUP(libgcc.a libc.a libm.a libnosys.a) /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be defined in code: * Reset_Handler : Entry of reset handler * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end * __copy_table_start__ * __copy_table_end__ * __zero_table_start__ * __zero_table_end__ * __etext * __data_start__ * __preinit_array_start * __preinit_array_end * __init_array_start * __init_array_end * __fini_array_start * __fini_array_end * __data_end__ * __bss_start__ * __bss_end__ * __end__ * end * __HeapBase * __HeapLimit * __StackLimit * __StackTop * __stack * __Vectors_End * __Vectors_Size */ ENTRY(Reset_Handler) SECTIONS { .text : { KEEP(*(.vectors)) __Vectors_End = .; __Vectors_Size = __Vectors_End - __Vectors; __end__ = .; *(.text*) KEEP(*(.init)) KEEP(*(.fini)) /* .ctors */ *crtbegin.o(.ctors) *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) *(SORT(.ctors.*)) *(.ctors) /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) *(SORT(.dtors.*)) *(.dtors) *(.rodata*) KEEP(*(.eh_frame*)) } > FLASH /* * Place the CMSE Veneers (containing the SG instruction) after the code, in a * separate 32 bytes aligned region so that the SAU can programmed to just set * this region as Non-Secure Callable. The maximum size of this executable * region makes it only used the space left over by the ER_CODE region * so that you can rely on code+veneer size combined will not exceed the * S_CODE_SIZE value. We also substract from the available space the * area used to align this section on 32 bytes boundary (for SAU conf). */ .gnu.sgstubs : ALIGN(32) { *(.gnu.sgstubs*) } > FLASH . = ALIGN(32); Image$$ER_CODE_CMSE_VENEER$$Base = ADDR(.gnu.sgstubs); Image$$ER_CODE_CMSE_VENEER$$Limit = .; Image$$ER_CODE_CMSE_VENEER$$Length = Image$$ER_CODE_CMSE_VENEER$$Limit - Image$$ER_CODE_CMSE_VENEER$$Base; /* Make sure veneers fit into code memory */ ASSERT(((S_CODE_START + S_CODE_SIZE) > Image$$ER_CODE_CMSE_VENEER$$Limit), "Veneer region does not fit into code memory") .ARM.extab : ALIGN(32) { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH __exidx_start = .; .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > FLASH __exidx_end = .; /* To copy multiple ROM to RAM sections, * define etext2/data2_start/data2_end and * define __STARTUP_COPY_MULTIPLE in startup_cmsdk_mps2_sse_200.S */ .copy.table : ALIGN(4) { __copy_table_start__ = .; LONG (__etext) LONG (__data_start__) LONG ((__data_end__ - __data_start__) / 4) LONG (DEFINED(__etext2) ? __etext2 : 0) LONG (DEFINED(__data2_start__) ? __data2_start__ : 0) LONG (DEFINED(__data2_start__) ? ((__data2_end__ - __data2_start__) / 4) : 0) __copy_table_end__ = .; } > FLASH /* To clear multiple BSS sections, * uncomment .zero.table section and, * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ .zero.table : ALIGN(4) { __zero_table_start__ = .; LONG (__bss_start__) LONG ((__bss_end__ - __bss_start__) / 4) LONG (DEFINED(__bss2_start__) ? __bss2_start__ : 0) LONG (DEFINED(__bss2_start__) ? ((__bss2_end__ - __bss2_start__) / 4) : 0) __zero_table_end__ = .; } > FLASH __etext = ALIGN(4); .data : ALIGN(4) { __data_start__ = .; *(vtable) *(.data*) . = ALIGN(4); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) . = ALIGN(4); /* All data end */ __data_end__ = .; } > RAM AT> FLASH .bss : ALIGN(4) { __bss_start__ = .; *(.bss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; } > RAM bss_size = __bss_end__ - __bss_start__; .stack : ALIGN(8) { __StackLimit = .; KEEP(*(.stack*)) . += __stack_size__ - 0x8; __StackTop = .; } > RAM .msp_stack_seal_res : { . += 0x8; } > RAM __StackSeal = ADDR(.msp_stack_seal_res); .heap : ALIGN(8) { __end__ = .; PROVIDE(end = .); __HeapBase = .; . += __heap_size__; __HeapLimit = .; __heap_limit = .; /* Add for _sbrk */ } > RAM /* Set stack top to end of the used RAM section, and stack limit move down by * size of stack_dummy section */ PROVIDE(__stack = __StackTop); /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__StackTop <= (S_DATA_START + S_DATA_SIZE), "Secure RAM region overflowed") }