292 lines
		
	
	
	
		
			7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			292 lines
		
	
	
	
		
			7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| /***************************************************************************//**
 | ||
|  * @file     gcc_EFR32MG21.ld
 | ||
|  * @brief    GNU Linker Script for Cortex-M based device
 | ||
|  * @version  V2.2.0
 | ||
|  * @date     16. December 2020
 | ||
|  * Linker script for Silicon Labs EFR32MG21 devices
 | ||
|  *******************************************************************************
 | ||
|  * # License
 | ||
|  * <b>Copyright 2024 Silicon Laboratories, Inc. www.silabs.com </b>
 | ||
|  *******************************************************************************
 | ||
|  *
 | ||
|  * SPDX-License-Identifier: Zlib
 | ||
|  *
 | ||
|  * The licensor of this software is Silicon Laboratories Inc.
 | ||
|  *
 | ||
|  * This software is provided 'as-is', without any express or implied
 | ||
|  * warranty. In no event will the authors be held liable for any damages
 | ||
|  * arising from the use of this software.
 | ||
|  *
 | ||
|  * Permission is granted to anyone to use this software for any purpose,
 | ||
|  * including commercial applications, and to alter it and redistribute it
 | ||
|  * freely, subject to the following restrictions:
 | ||
|  *
 | ||
|  * 1. The origin of this software must not be misrepresented; you must not
 | ||
|  *    claim that you wrote the original software. If you use this software
 | ||
|  *    in a product, an acknowledgment in the product documentation would be
 | ||
|  *    appreciated but is not required.
 | ||
|  * 2. Altered source versions must be plainly marked as such, and must not be
 | ||
|  *    misrepresented as being the original software.
 | ||
|  * 3. This notice may not be removed or altered from any source distribution.
 | ||
|  *
 | ||
|  ******************************************************************************/
 | ||
| 
 | ||
| MEMORY
 | ||
| {
 | ||
|   FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1024K
 | ||
|   RAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 96K
 | ||
| }
 | ||
| 
 | ||
| /* 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
 | ||
|  *   __HeapLimit
 | ||
|  *   __StackLimit
 | ||
|  *   __StackTop
 | ||
|  *   __stack
 | ||
|  *   __StackSeal      (only if ARMv8-M stack sealing is used)
 | ||
|  */
 | ||
| 
 | ||
| ENTRY(Reset_Handler)
 | ||
| 
 | ||
| SECTIONS
 | ||
| {
 | ||
|   .text :
 | ||
|   {
 | ||
|     KEEP(*(.vectors))
 | ||
|     *(.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
 | ||
|   /*
 | ||
|    * SG veneers:
 | ||
|    * All SG veneers are placed in the special output section .gnu.sgstubs. Its start address
 | ||
|    * must be set, either with the command line option ‘--section-start’ or in a linker script,
 | ||
|    * to indicate where to place these veneers in memory.
 | ||
|    */
 | ||
| /*
 | ||
|   .gnu.sgstubs : ALIGN(32)
 | ||
|   {
 | ||
|     . = ALIGN(32);
 | ||
|     linker_sg_begin = .;
 | ||
|     KEEP(*(.gnu.sgstubs*))
 | ||
|     . = ALIGN(32);
 | ||
|   } > FLASH
 | ||
|   linker_sg_end = linker_sg_begin + SIZEOF(.gnu.sgstubs);
 | ||
| */
 | ||
|   .ARM.extab :
 | ||
|   {
 | ||
|     *(.ARM.extab* .gnu.linkonce.armextab.*)
 | ||
|   } > FLASH
 | ||
| 
 | ||
|   __exidx_start = .;
 | ||
|   .ARM.exidx :
 | ||
|   {
 | ||
|     *(.ARM.exidx* .gnu.linkonce.armexidx.*)
 | ||
|   } > FLASH
 | ||
|   __exidx_end = .;
 | ||
| 
 | ||
|   .copy.table :
 | ||
|   {
 | ||
|     . = ALIGN(4);
 | ||
|     __copy_table_start__ = .;
 | ||
| 
 | ||
|     LONG (__etext)
 | ||
|     LONG (__data_start__)
 | ||
|     LONG ((__data_end__ - __data_start__) / 4)
 | ||
| 
 | ||
|     /* Add each additional data section here */
 | ||
| /*
 | ||
|     LONG (__etext2)
 | ||
|     LONG (__data2_start__)
 | ||
|     LONG ((__data2_end__ - __data2_start__) / 4)
 | ||
| */
 | ||
|     __copy_table_end__ = .;
 | ||
|   } > FLASH
 | ||
| 
 | ||
|   .zero.table :
 | ||
|   {
 | ||
|     . = ALIGN(4);
 | ||
|     __zero_table_start__ = .;
 | ||
|     /* Add each additional bss section here */
 | ||
| /*
 | ||
|     LONG (__bss2_start__)
 | ||
|     LONG ((__bss2_end__ - __bss2_start__) / 4)
 | ||
| */
 | ||
|     __zero_table_end__ = .;
 | ||
|     __etext = ALIGN(4);
 | ||
|   } > FLASH
 | ||
| 
 | ||
|   .data : AT (__etext)
 | ||
|   {
 | ||
|     __data_start__ = .;
 | ||
|     *(vtable)
 | ||
|     *(.data*)
 | ||
|     . = ALIGN (4);
 | ||
|     PROVIDE (__ram_func_section_start = .);
 | ||
|     *(.ram)
 | ||
|     PROVIDE (__ram_func_section_end = .);
 | ||
| 
 | ||
|     . = 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
 | ||
| 
 | ||
|   /*
 | ||
|    * Secondary data section, optional
 | ||
|    *
 | ||
|    * Remember to add each additional data section
 | ||
|    * to the .copy.table above to asure proper
 | ||
|    * initialization during startup.
 | ||
|    */
 | ||
| /*
 | ||
|   __etext2 = ALIGN (4);
 | ||
| 
 | ||
|   .data2 : AT (__etext2)
 | ||
|   {
 | ||
|     . = ALIGN(4);
 | ||
|     __data2_start__ = .;
 | ||
|     *(.data2)
 | ||
|     *(.data2.*)
 | ||
|     . = ALIGN(4);
 | ||
|     __data2_end__ = .;
 | ||
| 
 | ||
|   } > RAM2
 | ||
| */
 | ||
|   .bss :
 | ||
|   {
 | ||
|     . = ALIGN(4);
 | ||
|     __bss_start__ = .;
 | ||
|     *(.bss)
 | ||
|     *(.bss.*)
 | ||
|     *(COMMON)
 | ||
|     . = ALIGN(4);
 | ||
|     __bss_end__ = .;
 | ||
|   } > RAM AT > RAM
 | ||
| 
 | ||
|   /*
 | ||
|    * Secondary bss section, optional
 | ||
|    *
 | ||
|    * Remember to add each additional bss section
 | ||
|    * to the .zero.table above to asure proper
 | ||
|    * initialization during startup.
 | ||
|    */
 | ||
| /*
 | ||
|   .bss2 :
 | ||
|   {
 | ||
|     . = ALIGN(4);
 | ||
|     __bss2_start__ = .;
 | ||
|     *(.bss2)
 | ||
|     *(.bss2.*)
 | ||
|     . = ALIGN(4);
 | ||
|     __bss2_end__ = .;
 | ||
|   } > RAM2 AT > RAM2
 | ||
| */
 | ||
| 
 | ||
|   .heap (COPY):
 | ||
|   {
 | ||
|     __HeapBase = .;
 | ||
|     __end__ = .;
 | ||
|     end = __end__;
 | ||
|     _end = __end__;
 | ||
|     KEEP(*(.heap*))
 | ||
|     __HeapLimit = .;
 | ||
|   } > RAM
 | ||
|   /* ARMv8-M stack sealing:
 | ||
|      to use ARMv8-M stack sealing uncomment '.stackseal' section and KEEP(*(.stackseal*))
 | ||
|      in .stack_dummy section
 | ||
|    */
 | ||
| /*
 | ||
|   .stackseal (COPY) :
 | ||
|   {
 | ||
|     . = ALIGN(8);
 | ||
|     __StackSeal = .;
 | ||
|     . = . + 8;
 | ||
|     . = ALIGN(8);
 | ||
|   } > RAM
 | ||
| */
 | ||
| 
 | ||
|   /* .stack_dummy section doesn't contains any symbols. It is only
 | ||
|    * used for linker to calculate size of stack sections, and assign
 | ||
|    * values to stack symbols later */
 | ||
|   .stack_dummy (COPY):
 | ||
|   {
 | ||
|     KEEP(*(.stack*))
 | ||
|  /* KEEP(*(.stackseal*))*/
 | ||
|   } > RAM
 | ||
| 
 | ||
|   /* Set stack top to end of RAM, and stack limit move down by
 | ||
|    * size of stack_dummy section */
 | ||
|   __StackTop = ORIGIN(RAM) + LENGTH(RAM);
 | ||
|   __StackLimit = __StackTop - SIZEOF(.stack_dummy);
 | ||
|   PROVIDE(__stack = __StackTop);
 | ||
| 
 | ||
|   /* Check if data + heap + stack exceeds RAM limit */
 | ||
|   ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
 | ||
| 
 | ||
|   /* Check if FLASH usage exceeds FLASH size */
 | ||
|   ASSERT( LENGTH(FLASH) >= (__etext + SIZEOF(.data)), "FLASH memory overflowed !")
 | ||
| }
 |