/* Default linker script, for normal executables */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:5)

/*===========================================================
../doc/binutils/ld.html/MEMORY.html#MEMORY
=============================================================
memory regions defined here
used to place below sections into specific memory regions
options passed to linker can change these memory values
such as changing the origin of the data section to 0x800100
===========================================================*/

MEMORY
{
  text      (rx)   : ORIGIN = 0, LENGTH = 128K
  data      (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
  eeprom    (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
  fuse      (rw!x) : ORIGIN = 0x820000, LENGTH = 1K
  lock      (rw!x) : ORIGIN = 0x830000, LENGTH = 1K
  signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K
}


/*===========================================================
../doc/binutils/ld.html/SECTIONS.html#SECTIONS
===========================================================*/

SECTIONS
{
  /* Internal text space or external memory.  */
/*===========================================================
.text section

===========================================================*/  
  .text   :
  {
/*===========================================================
vector table goes here
KEEP prevents this section from being discarded
===========================================================*/
    *(.vectors)
    KEEP(*(.vectors))
    /* For data that needs to reside in the lower 64k of progmem.  */
    *(.progmem.gcc*)
/*===========================================================
PROGMEM data goes here
===========================================================*/    
    *(.progmem*)
/*===========================================================
get address aligned to a word boundary, as progmem data
is bytes, and we need word alignment for code that follows
===========================================================*/    
    . = ALIGN(2);
     __trampolines_start = . ;
    /* The jump trampolines for the 16-bit limited relocs will reside here.  */
    *(.trampolines)
    *(.trampolines*)
     __trampolines_end = . ;
    /* For future tablejump instruction arrays for 3 byte pc devices.
       We don't relax jump/call instructions within these sections.  */
    *(.jumptables)
    *(.jumptables*)
    /* For code that needs to reside in the lower 128k progmem.  */
    *(.lowtext)
    *(.lowtext*)
     __ctors_start = . ;
     *(.ctors)
     __ctors_end = . ;
     __dtors_start = . ;
     *(.dtors)
     __dtors_end = . ;
    KEEP(SORT(*)(.ctors))
    KEEP(SORT(*)(.dtors))
/*===========================================================
init code here
===========================================================*/    
    /* From this point on, we don't bother about wether the insns are
       below or above the 16 bits boundary.  */
    *(.init0)  /* Start here after reset.  */
    KEEP (*(.init0))
    *(.init1)
    KEEP (*(.init1))
    *(.init2)  /* Clear __zero_reg__, set up stack pointer.  */
    KEEP (*(.init2))
    *(.init3)
    KEEP (*(.init3))
    *(.init4)  /* Initialize data and BSS.  */
    KEEP (*(.init4))
    *(.init5)
    KEEP (*(.init5))
    *(.init6)  /* C++ constructors.  */
    KEEP (*(.init6))
    *(.init7)
    KEEP (*(.init7))
    *(.init8)
    KEEP (*(.init8))
    *(.init9)  /* Call main().  */
    KEEP (*(.init9))
/*===========================================================
application code here
===========================================================*/    
    *(.text)
    . = ALIGN(2);
    *(.text.*)
    . = ALIGN(2);
/*===========================================================
exit code here
===========================================================*/       
    *(.fini9)  /* _exit() starts here.  */
    KEEP (*(.fini9))
    *(.fini8)
    KEEP (*(.fini8))
    *(.fini7)
    KEEP (*(.fini7))
    *(.fini6)  /* C++ destructors.  */
    KEEP (*(.fini6))
    *(.fini5)
    KEEP (*(.fini5))
    *(.fini4)
    KEEP (*(.fini4))
    *(.fini3)
    KEEP (*(.fini3))
    *(.fini2)
    KEEP (*(.fini2))
    *(.fini1)
    KEEP (*(.fini1))
    *(.fini0)  /* Infinite loop after program termination.  */
    KEEP (*(.fini0))      
     _etext = . ;
/*===========================================================
all the above goes into memory region 'text'
===========================================================*/        
  }  > text

/*===========================================================
.data section
VMA (virtual memory address) is not defined here, and will
start at the current location counter in the memory region
'data' (and since this is the first section to use the 'data'
region, it will start at the beginning of the 'data' region)

LMA (load memory address) is defined here as starting at
the end of the .text section
this puts the .data section at the end of .text, so the
startup code can load this data into ram
===========================================================*/  
  .data      : AT (ADDR (.text) + SIZEOF (.text))
  {
     PROVIDE (__data_start = .) ;
    *(.data)
    *(.data*)
    *(.rodata)  /* We need to include .rodata here if gcc is used */
    *(.rodata*) /* with -fdata-sections.  */
    *(.gnu.linkonce.d*)
    . = ALIGN(2);
     _edata = . ;
     PROVIDE (__data_end = .) ;
/*===========================================================
all the above goes into memory region 'data'
===========================================================*/      
  }  > data
 
/*===========================================================
.bss section
VMA (virtual memory address) is not defined here, and will
start at the current location counter in the memory region
'data' (and will follow the .data section in this script)

LMA (load memory address) is defined here as starting at
the same address as the VMA address (prevent bss from taking
space in text region)
===========================================================*/   
  .bss   : AT (ADDR (.bss))
  {
     PROVIDE (__bss_start = .) ;
    *(.bss)
    *(.bss*)
    *(COMMON)
     PROVIDE (__bss_end = .) ;
/*===========================================================
all the above goes into memory region 'data'
===========================================================*/      
  }  > data
 
/*===========================================================
provide symbols for the startup code, so it knows where
to load data from (in flash)
===========================================================*/   
   __data_load_start = LOADADDR(.data);
   __data_load_end = __data_load_start + SIZEOF(.data);
   
   
  /* Global data not cleared after reset.  */
  .noinit  :
  {
     PROVIDE (__noinit_start = .) ;
    *(.noinit*)
     PROVIDE (__noinit_end = .) ;
     _end = . ;
     PROVIDE (__heap_start = .) ;
  }  > data
  .eeprom  :
  {
    *(.eeprom*)
     __eeprom_end = . ;
  }  > eeprom
  .fuse  :
  {
    KEEP(*(.fuse))
    KEEP(*(.lfuse))
    KEEP(*(.hfuse))
    KEEP(*(.efuse))
  }  > fuse
  .lock  :
  {
    KEEP(*(.lock*))
  }  > lock
  .signature  :
  {
    KEEP(*(.signature*))
  }  > signature
}