|  | /* Linker script for Nordic Semiconductor nRF5 devices | 
|  | * | 
|  | * Version: Sourcery G++ 4.5-1 | 
|  | * Support: https://support.codesourcery.com/GNUToolchain/ | 
|  | * | 
|  | * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. | 
|  | * | 
|  | * The authors hereby grant permission to use, copy, modify, distribute, | 
|  | * and license this software and its documentation for any purpose, provided | 
|  | * that existing copyright notices are retained in all copies and that this | 
|  | * notice is included verbatim in any distributions.  No written agreement, | 
|  | * license, or royalty fee is required for any of the authorized uses. | 
|  | * Modifications to this software may be copyrighted by their authors | 
|  | * and need not follow the licensing terms described here, provided that | 
|  | * the new terms are clearly indicated on the first page of each file where | 
|  | * they apply. | 
|  | */ | 
|  | OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") | 
|  |  | 
|  | MEMORY | 
|  | { | 
|  | FLASH (rx) : ORIGIN = 0x00023800, LENGTH = 0x1b800 | 
|  | RAM (rwx) :  ORIGIN = 0x20000000, LENGTH = 0x8000 | 
|  | } | 
|  |  | 
|  | /* 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_split : Entry of reset handler | 
|  | * | 
|  | * It defines following symbols, which code can use without definition: | 
|  | *   __exidx_start | 
|  | *   __exidx_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__ | 
|  | *   __HeapBase | 
|  | *   __HeapLimit | 
|  | *   __StackLimit | 
|  | *   __StackTop | 
|  | *   __stack | 
|  | *   __bssnz_start__ | 
|  | *   __bssnz_end__ | 
|  | */ | 
|  | ENTRY(Reset_Handler_split) | 
|  |  | 
|  | SECTIONS | 
|  | { | 
|  | .imghdr (NOLOAD): | 
|  | { | 
|  | . = . + 0x20; | 
|  | } > FLASH | 
|  |  | 
|  | .text : | 
|  | { | 
|  | __split_isr_vector_start = .; | 
|  | KEEP(*(.isr_vector_split)) | 
|  | __split_isr_vector_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) | 
|  |  | 
|  | INCLUDE "link_tables.ld.h" | 
|  | *(.rodata*) | 
|  |  | 
|  | *(.eh_frame*) | 
|  | . = ALIGN(4); | 
|  | } > FLASH | 
|  |  | 
|  |  | 
|  | .ARM.extab : | 
|  | { | 
|  | *(.ARM.extab* .gnu.linkonce.armextab.*) | 
|  | . = ALIGN(4); | 
|  | } > FLASH | 
|  |  | 
|  | __exidx_start = .; | 
|  | .ARM.exidx : | 
|  | { | 
|  | *(.ARM.exidx* .gnu.linkonce.armexidx.*) | 
|  | . = ALIGN(4); | 
|  | } > FLASH | 
|  | __exidx_end = .; | 
|  |  | 
|  | __etext = .; | 
|  |  | 
|  | /* save RAM used by the split image. This assumes that | 
|  | * the loader uses all the RAM up to its HeapBase  */ | 
|  | .loader_ram_contents : | 
|  | { | 
|  | _loader_ram_start = .; | 
|  | /* this symbol comes from the loader linker */ | 
|  | . = . + (ABSOLUTE(__HeapBase_loader) - _loader_ram_start); | 
|  | _loader_ram_end = .; | 
|  | } > RAM | 
|  |  | 
|  | .data : | 
|  | { | 
|  | __data_start__ = .; | 
|  | *(.data*) | 
|  |  | 
|  | . = ALIGN(4); | 
|  | /* preinit data */ | 
|  | PROVIDE_HIDDEN (__preinit_array_start = .); | 
|  | *(.preinit_array) | 
|  | PROVIDE_HIDDEN (__preinit_array_end = .); | 
|  |  | 
|  | . = ALIGN(4); | 
|  | /* init data */ | 
|  | PROVIDE_HIDDEN (__init_array_start = .); | 
|  | *(SORT(.init_array.*)) | 
|  | *(.init_array) | 
|  | PROVIDE_HIDDEN (__init_array_end = .); | 
|  |  | 
|  |  | 
|  | . = ALIGN(4); | 
|  | /* finit data */ | 
|  | PROVIDE_HIDDEN (__fini_array_start = .); | 
|  | *(SORT(.fini_array.*)) | 
|  | *(.fini_array) | 
|  | PROVIDE_HIDDEN (__fini_array_end = .); | 
|  |  | 
|  | *(.jcr) | 
|  | . = ALIGN(4); | 
|  | /* All data end */ | 
|  | __data_end__ = .; | 
|  | } > RAM AT > FLASH | 
|  |  | 
|  | .bss : | 
|  | { | 
|  | . = ALIGN(4); | 
|  | __bss_start__ = .; | 
|  | *(.bss*) | 
|  | *(COMMON) | 
|  | . = ALIGN(4); | 
|  | __bss_end__ = .; | 
|  | } > RAM | 
|  |  | 
|  | /* Heap starts after BSS */ | 
|  | . = ALIGN(8); | 
|  | __HeapBase = .; | 
|  |  | 
|  | /* .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): | 
|  | { | 
|  | *(.stack*) | 
|  | } > RAM | 
|  |  | 
|  | _ram_start = ORIGIN(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); | 
|  |  | 
|  | /* Top of head is the bottom of the stack */ | 
|  | __HeapLimit = __StackLimit; | 
|  |  | 
|  | /* Check if data + heap + stack exceeds RAM limit */ | 
|  | ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") | 
|  | } |