|
/* Linker script for ARM M-profile Simulator
|
|
*
|
|
* Version: Sourcery G++ Lite 2010q1-188
|
|
* 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")
|
|
ENTRY(Reset)
|
|
SEARCH_DIR(.)
|
|
GROUP(-lgcc -lc -lnosys)
|
|
|
|
|
|
MEMORY
|
|
{
|
|
rom (rx) : ORIGIN = 0x0, LENGTH = 131072
|
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16384
|
|
}
|
|
|
|
|
|
CY_APPL_ORIGIN = 0;
|
|
CY_FLASH_ROW_SIZE = 128;
|
|
CY_APPL_NUM = 1;
|
|
CY_METADATA_SIZE = 64;
|
|
|
|
|
|
/* These force the linker to search for particular symbols from
|
|
* the start of the link process and thus ensure the user's
|
|
* overrides are picked up
|
|
*/
|
|
EXTERN(Reset)
|
|
|
|
/* Bring in the interrupt routines & vector */
|
|
EXTERN(main)
|
|
|
|
/* Bring in the meta data */
|
|
EXTERN(cy_meta_loader cy_bootloader cy_meta_loadable cy_meta_bootloader)
|
|
EXTERN(cy_meta_flashprotect cy_metadata cy_meta_chipprotect)
|
|
EXTERN(cy_heap)
|
|
|
|
/* Provide fall-back values */
|
|
PROVIDE(__cy_heap_start = _end);
|
|
PROVIDE(__cy_region_num = (__cy_regions_end - __cy_regions) / 16);
|
|
|
|
/* Set stack top to end of RAM, and stack limit move down by
|
|
* size of .stack section.
|
|
*/
|
|
PROVIDE(__cy_stack = ORIGIN(ram) + LENGTH(ram));
|
|
|
|
PROVIDE(__cy_heap_end = __cy_stack - 0x0800);
|
|
|
|
|
|
SECTIONS
|
|
{
|
|
/* The bootloader location */
|
|
.cybootloader 0x0 : { KEEP(*(.cybootloader)) } >rom
|
|
|
|
/* Calculate where the loadables should start */
|
|
appl1_start = CY_APPL_ORIGIN ? CY_APPL_ORIGIN : ALIGN(CY_FLASH_ROW_SIZE);
|
|
appl2_start = appl1_start + ALIGN((LENGTH(rom) - appl1_start - 2 * CY_FLASH_ROW_SIZE) / 2, CY_FLASH_ROW_SIZE);
|
|
appl_start = (CY_APPL_NUM == 1) ? appl1_start : appl2_start;
|
|
|
|
.text appl_start :
|
|
{
|
|
CREATE_OBJECT_SYMBOLS
|
|
PROVIDE(__cy_interrupt_vector = RomVectors);
|
|
|
|
*(.romvectors)
|
|
|
|
/* Make sure we pulled in an interrupt vector. */
|
|
ASSERT (. != __cy_interrupt_vector, "No interrupt vector");
|
|
|
|
ASSERT (CY_APPL_ORIGIN ? (SIZEOF(.cybootloader) <= CY_APPL_ORIGIN) : 1, "Wrong image location");
|
|
|
|
PROVIDE(__cy_reset = Reset);
|
|
*(.text.Reset)
|
|
/* Make sure we pulled in some reset code. */
|
|
ASSERT (. != __cy_reset, "No reset code");
|
|
|
|
*(.psocinit)
|
|
|
|
. = MAX(., 0x100);
|
|
|
|
*(.text .text.* .gnu.linkonce.t.*)
|
|
*(.plt)
|
|
*(.gnu.warning)
|
|
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
|
|
|
|
KEEP(*(.bootloader)) /* necessary for bootloader's, but doesn't impact non-bootloaders */
|
|
|
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
|
*(.gcc_except_table)
|
|
} >rom
|
|
.eh_frame_hdr : ALIGN (4)
|
|
{
|
|
KEEP (*(.eh_frame_hdr))
|
|
} >rom
|
|
.eh_frame : ALIGN (4)
|
|
{
|
|
KEEP (*(.eh_frame))
|
|
} >rom
|
|
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
|
PROVIDE_HIDDEN (__exidx_start = .);
|
|
.ARM.exidx :
|
|
{
|
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
|
} >rom
|
|
__exidx_end = .;
|
|
.rodata : ALIGN (4)
|
|
{
|
|
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
|
|
|
. = ALIGN(4);
|
|
KEEP(*(.init))
|
|
|
|
. = ALIGN(4);
|
|
__preinit_array_start = .;
|
|
KEEP (*(.preinit_array))
|
|
__preinit_array_end = .;
|
|
|
|
. = ALIGN(4);
|
|
__init_array_start = .;
|
|
KEEP (*(SORT(.init_array.*)))
|
|
KEEP (*(.init_array))
|
|
__init_array_end = .;
|
|
|
|
. = ALIGN(4);
|
|
KEEP(*(.fini))
|
|
|
|
. = ALIGN(4);
|
|
__fini_array_start = .;
|
|
KEEP (*(.fini_array))
|
|
KEEP (*(SORT(.fini_array.*)))
|
|
__fini_array_end = .;
|
|
|
|
. = ALIGN(0x4);
|
|
KEEP (*crtbegin.o(.ctors))
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
|
KEEP (*(SORT(.ctors.*)))
|
|
KEEP (*crtend.o(.ctors))
|
|
|
|
. = ALIGN(0x4);
|
|
KEEP (*crtbegin.o(.dtors))
|
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
|
KEEP (*(SORT(.dtors.*)))
|
|
KEEP (*crtend.o(.dtors))
|
|
|
|
. = ALIGN(4);
|
|
__cy_regions = .;
|
|
LONG (__cy_region_init_ram)
|
|
LONG (__cy_region_start_data)
|
|
LONG (__cy_region_init_size_ram)
|
|
LONG (__cy_region_zero_size_ram)
|
|
__cy_regions_end = .;
|
|
|
|
. = ALIGN (8);
|
|
_etext = .;
|
|
} >rom
|
|
|
|
.ramvectors (NOLOAD) : ALIGN(8)
|
|
{
|
|
__cy_region_start_ram = .;
|
|
KEEP(*(.ramvectors))
|
|
}
|
|
|
|
.noinit (NOLOAD) : ALIGN(8)
|
|
{
|
|
KEEP(*(.noinit))
|
|
}
|
|
|
|
.data : ALIGN(8)
|
|
{
|
|
__cy_region_start_data = .;
|
|
|
|
KEEP(*(.jcr))
|
|
*(.got.plt) *(.got)
|
|
*(.shdata)
|
|
*(.data .data.* .gnu.linkonce.d.*)
|
|
. = ALIGN (8);
|
|
*(.ram)
|
|
_edata = .;
|
|
} >ram AT>rom
|
|
.bss : ALIGN(8)
|
|
{
|
|
PROVIDE(__bss_start__ = .);
|
|
*(.shbss)
|
|
*(.bss .bss.* .gnu.linkonce.b.*)
|
|
*(COMMON)
|
|
. = ALIGN (8);
|
|
*(.ram.b)
|
|
_end = .;
|
|
__end = .;
|
|
} >ram AT>rom
|
|
PROVIDE(end = .);
|
|
PROVIDE(__bss_end__ = .);
|
|
|
|
__cy_region_init_ram = LOADADDR (.data);
|
|
__cy_region_init_size_ram = _edata - ADDR (.data);
|
|
__cy_region_zero_size_ram = _end - _edata;
|
|
|
|
/* The .stack and .heap sections don't contain any symbols.
|
|
* They are only used for linker to calculate RAM utilization.
|
|
*/
|
|
.heap (NOLOAD) :
|
|
{
|
|
. = _end;
|
|
. += 0x80;
|
|
__cy_heap_limit = .;
|
|
} >ram
|
|
|
|
.stack (__cy_stack - 0x0800) (NOLOAD) :
|
|
{
|
|
__cy_stack_limit = .;
|
|
. += 0x0800;
|
|
} >ram
|
|
|
|
/* Check if data + heap + stack exceeds RAM limit */
|
|
ASSERT(__cy_stack_limit >= __cy_heap_limit, "region RAM overflowed with stack")
|
|
|
|
.cyloadermeta ((appl_start == 0) ? (LENGTH(rom) - CY_METADATA_SIZE) : 0xF0000000) :
|
|
{
|
|
KEEP(*(.cyloadermeta))
|
|
} : NONE
|
|
|
|
.cyloadablemeta (LENGTH(rom) - CY_FLASH_ROW_SIZE * (CY_APPL_NUM - 1) - CY_METADATA_SIZE) :
|
|
{
|
|
KEEP(*(.cyloadablemeta))
|
|
} >rom
|
|
|
|
.cyflashprotect 0x90400000 : { KEEP(*(.cyflashprotect)) } :NONE
|
|
.cymeta 0x90500000 : { KEEP(*(.cymeta)) } :NONE
|
|
.cychipprotect 0x90600000 : { KEEP(*(.cychipprotect)) } :NONE
|
|
|
|
.stab 0 (NOLOAD) : { *(.stab) }
|
|
.stabstr 0 (NOLOAD) : { *(.stabstr) }
|
|
/* DWARF debug sections.
|
|
* Symbols in the DWARF debugging sections are relative to the beginning
|
|
* of the section so we begin them at 0.
|
|
*/
|
|
/* DWARF 1 */
|
|
.debug 0 : { *(.debug) }
|
|
.line 0 : { *(.line) }
|
|
/* GNU DWARF 1 extensions */
|
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
|
.debug_sfnames 0 : { *(.debug_sfnames) }
|
|
/* DWARF 1.1 and DWARF 2 */
|
|
.debug_aranges 0 : { *(.debug_aranges) }
|
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
|
/* DWARF 2 */
|
|
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
|
.debug_abbrev 0 : { *(.debug_abbrev) }
|
|
.debug_line 0 : { *(.debug_line) }
|
|
.debug_frame 0 : { *(.debug_frame) }
|
|
.debug_str 0 : { *(.debug_str) }
|
|
.debug_loc 0 : { *(.debug_loc) }
|
|
.debug_macinfo 0 : { *(.debug_macinfo) }
|
|
/* DWARF 2.1 */
|
|
.debug_ranges 0 : { *(.debug_ranges) }
|
|
/* SGI/MIPS DWARF 2 extensions */
|
|
.debug_weaknames 0 : { *(.debug_weaknames) }
|
|
.debug_funcnames 0 : { *(.debug_funcnames) }
|
|
.debug_typenames 0 : { *(.debug_typenames) }
|
|
.debug_varnames 0 : { *(.debug_varnames) }
|
|
|
|
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
|
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
|
|
/DISCARD/ : { *(.note.GNU-stack) }
|
|
}
|
|
|