/*****************************************************************************
 * \brief		Linker script for STM32F407 Device with
 *				1024KByte FLASH, 128KByte RAM
 *				Set heap size, stack size and stack location according
 *				to application requirements.
 *				Set memory bank area and size if external memory is used.
 *
 * \file		stm32f4_flash.ld
 * \version		1.0
 * \date		2013-02-18
 * \author		rct1
 ****************************************************************************/

/* Entry Point */
ENTRY(Reset_Handler)

/* Libraries */
SEARCH_DIR("./libs")
INPUT(libBSP.a)
INPUT(libsGUI.a)

/* Highest address of the user mode stack */
_estack = 0x20020000;		/* end of 128K RAM */

/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x1000;	/* required amount of heap  */
_Min_Stack_Size = 0x1000;	/* required amount of stack */

/* Specify the memory areas */
MEMORY
{
	FLASH(rx)		: ORIGIN = 0x08000000, LENGTH = 1024K
	RAM(xrw)		: ORIGIN = 0x20000000, LENGTH = 128K
	MEMORY_B1(rx)	: ORIGIN = 0x60000000, LENGTH = 0K
	CCMRAM(rw)		: ORIGIN = 0x10000000, LENGTH = 64K
}

/* Define output sections */
SECTIONS
{
	/* The startup code goes first into FLASH */
	.isr_vector :
	{
		. = ALIGN(4);
		KEEP(*(.isr_vector)) /* Startup code */
		. = ALIGN(4);
	} >FLASH

	/* The program code and other data goes into FLASH */
	.text :
	{
		. = ALIGN(4);
		*(.text)			/* .text sections (code) */
		*(.text*)			/* .text* sections (code) */
		*(.rodata)			/* .rodata sections (constants, strings, etc.)	*/
		*(.rodata*)			/* .rodata* sections (constants, strings, etc.)	*/
		*(.glue_7)			/* glue arm to thumb code */
		*(.glue_7t)			/* glue thumb to arm code */
		*(.eh_frame)

		KEEP(*(.init))
		KEEP(*(.fini))

		. = ALIGN(4);
		_etext = .;			/* define a global symbols at end of code */
	} >FLASH

	.ARM.extab :
	{
		*(.ARM.extab* .gnu.linkonce.armextab.*)
	} >FLASH
	.ARM :
	{
		__exidx_start = .;
		*(.ARM.exidx*)
		__exidx_end = .;
	} >FLASH

	.preinit_array :
	{
		PROVIDE_HIDDEN(__preinit_array_start = .);
		KEEP(*(.preinit_array*))
		PROVIDE_HIDDEN(__preinit_array_end = .);
	} >FLASH
	.init_array :
	{
		PROVIDE_HIDDEN(__init_array_start = .);
		KEEP(*(SORT(.init_array.*)))
		KEEP(*(.init_array*))
		PROVIDE_HIDDEN(__init_array_end = .);
	} >FLASH
	.fini_array :
	{
		PROVIDE_HIDDEN(__fini_array_start = .);
		KEEP(*(SORT(.fini_array.*)))
		KEEP(*(.fini_array*))
		PROVIDE_HIDDEN(__fini_array_end = .);
	} >FLASH

	/* used by the startup to initialize data */
	_sidata = LOADADDR(.data);

	/* Initialized data sections goes into RAM, load LMA copy after code */
	.data : 
	{
		. = ALIGN(4);
		_sdata = .;			/* create a global symbol at data start */
		*(.data)			/* .data sections */
		*(.data*)			/* .data* sections */

		. = ALIGN(4);
		_edata = .;			/* define a global symbol at data end */
	} >RAM AT> FLASH

	_siccmram = LOADADDR(.ccmram);

	/* CCM-RAM section 
	 *
	 * IMPORTANT NOTE! 
	 * If initialized variables will be placed in this section, 
	 * the startup code needs to be modified to copy the init-values.  
	 */
	.ccmram :
	{
		. = ALIGN(4);
		_sccmram = .;		/* create a global symbol at ccmram start */
		*(.ccmram)
		*(.ccmram*)

		. = ALIGN(4);
		_eccmram = .;		/* create a global symbol at ccmram end */
	} >CCMRAM AT> FLASH

	/* Uninitialized data section */
	. = ALIGN(4);
	.bss :
	{
		/* This is used by the startup in order to initialize the .bss secion */
		_sbss = .;			/* define a global symbol at bss start */
		__bss_start__ = _sbss;
		*(.bss)
		*(.bss*)
		*(COMMON)

		. = ALIGN(4);
		_ebss = .;			/* define a global symbol at bss end */
		__bss_end__ = _ebss;
	} >RAM

	/* User_heap_stack section, used to check that there is enough RAM left */
	._user_heap_stack :
	{
		. = ALIGN(4);
		PROVIDE(end = .);
		PROVIDE(_end = .);
		. = . + _Min_Heap_Size;
		. = . + _Min_Stack_Size;
		. = ALIGN(4);
	} >RAM

	/* MEMORY_bank1 section, code must be located here explicitly			*/
	/* Example: extern int foo(void) __attribute__ ((section (".mb1text")));*/
	.memory_b1_text :
	{
		*(.mb1text)			/* .mb1text sections (code)		*/
		*(.mb1text*)		/* .mb1text* sections (code)	*/
		*(.mb1rodata)		/* read-only data (constants)	*/
		*(.mb1rodata*)
	} >MEMORY_B1

	/* Remove information from the standard libraries */
	/DISCARD/ :
	{
		libc.a(*)
		libm.a(*)
		libgcc.a(*)
	}

	.ARM.attributes 0 :
	{
		*(.ARM.attributes)
	}
}
