/*-------------------------------------------------------------------------- | |
* MPLAB XC Compiler - MEC1404 linker script | |
* Build date : Jul 14 2014 | |
* | |
* This software is developed by Microchip Technology Inc. and its | |
* subsidiaries ("Microchip"). | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions are | |
* met: | |
* | |
* 1. Redistributions of source code must retain the above copyright | |
* notice, this list of conditions and the following disclaimer. | |
* 2. Redistributions in binary form must reproduce the above | |
* copyright notice, this list of conditions and the following | |
* disclaimer in the documentation and/or other materials provided | |
* with the distribution. | |
* 3. Microchip's name may not be used to endorse or promote products | |
* derived from this software without specific prior written | |
* permission. | |
* | |
* THIS SOFTWARE IS PROVIDED BY MICROCHIP "AS IS" AND ANY EXPRESS OR IMPLIED | |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
* MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED. IN NO EVENT | |
* SHALL MICROCHIP BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING BUT NOT LIMITED TO | |
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS; | |
* OR BUSINESS INTERRUPTION) HOWSOEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
* | |
*-------------------------------------------------------------------------*/ | |
/* Default linker script, for normal executables */ | |
OUTPUT_FORMAT("elf32-tradlittlemips") | |
OUTPUT_ARCH(pic32mx) | |
ENTRY(_reset) | |
/* | |
* Provide for a minimum stack and heap size | |
* - _min_stack_size - represents the minimum space that must be made | |
* available for the stack. Can be overridden from | |
* the command line using the linker's --defsym option. | |
* - _min_heap_size - represents the minimum space that must be made | |
* available for the heap. Must be specified on | |
* the command line using the linker's --defsym option. | |
*/ | |
EXTERN (_min_stack_size _min_heap_size) | |
PROVIDE(_min_stack_size = 0x400) ; | |
PROVIDE(_min_heap_size = 0x400) ; | |
/************************************************************************* | |
* Processor-specific object file. Contains SFR definitions. | |
*************************************************************************/ | |
INPUT("processor.o") | |
/************************************************************************* | |
* For interrupt vector handling | |
*************************************************************************/ | |
PROVIDE(_vector_spacing = 0x00000001); | |
PROVIDE(_ebase_address = 0xBFD00000); | |
/************************************************************************* | |
* Memory Address Equates | |
* _RESET_ADDR -- Reset Vector | |
* _GEN_EXCPT_ADDR -- General Exception Vector | |
*************************************************************************/ | |
_RESET_ADDR = 0xBFD00000; | |
_GEN_EXCPT_ADDR = _ebase_address + 0x180; | |
/************************************************************************* | |
* Memory Regions | |
* | |
* Memory regions without attributes cannot be used for orphaned sections. | |
* Only sections specifically assigned to these regions can be allocated | |
* into these regions. | |
*************************************************************************/ | |
MEMORY | |
{ | |
rom (rx) : ORIGIN = 0xBFC00000, LENGTH = 0x10000 | |
kseg0_program_mem (rx) : ORIGIN = 0xBFD00000, LENGTH = 0x18000 | |
sfrs : ORIGIN = 0xBFBFEFF0, LENGTH = 0x100000 | |
kseg1_data_mem (rwx) : ORIGIN = 0xBFD18000, LENGTH = 0x8000 | |
} | |
SECTIONS | |
{ | |
.reset _RESET_ADDR : | |
{ | |
KEEP(*(.reset)) | |
} > kseg0_program_mem | |
.app_excpt _GEN_EXCPT_ADDR : | |
{ | |
KEEP(*(.gen_handler)) | |
} > kseg0_program_mem | |
/* MEC14x4 JTVIC has 19 aggregated interrupt sources in its | |
* power-on-reset configuration. MEC14xx data sheet uses nomenclature | |
* GIRQ00 - GIRQ18. | |
* MEC14x4 M14K core was built to support EIC Mode 2 only. The JTVIC | |
* supplies a 17-bit offset to the M14K core. The M14K combines this | |
* 17-bit offset with EBASE to produce the final vector location. | |
* Similar to the PIC32MZ EVIC, the JTVIC has a register for each | |
* GIRQx containing the 17-bit value supplied to the M14K core. | |
* This means ISR's can be located anywhere above EBASE except for | |
* the fixed location of the General Exception at EBASE + 0x180. | |
* To avoid overhead of XC32 .vector_N long jumps we will program | |
* the address of the C ISR directly into the JTVIC. All ISR's | |
* can be in .text | |
* C ISR's must also be marked with the interrupt(XXX_IPL) attribute | |
* so the compiler knows about priority, etc. | |
*/ | |
.vectors _ebase_address + 0x200 : | |
{ | |
/* | |
KEEP (*(.vector_0)) | |
KEEP (*(.vector_1)) | |
KEEP (*(.vector_2)) | |
KEEP (*(.vector_3)) | |
KEEP (*(.vector_4)) | |
KEEP (*(.vector_5)) | |
KEEP (*(.vector_6)) | |
KEEP (*(.vector_7)) | |
KEEP (*(.vector_8)) | |
KEEP (*(.vector_9)) | |
KEEP (*(.vector_10)) | |
KEEP (*(.vector_11)) | |
KEEP (*(.vector_12)) | |
KEEP (*(.vector_13)) | |
KEEP (*(.vector_14)) | |
KEEP (*(.vector_15)) | |
KEEP (*(.vector_16)) | |
KEEP (*(.vector_17)) | |
KEEP (*(.vector_18)) | |
*/ | |
KEEP (SORT_BY_NAME(*)(.girqs.*)) | |
KEEP (*(.vec_default)) | |
} > kseg0_program_mem | |
/* The startup code is in the .reset.startup section. | |
* SRAM Application startup code does NOT need to be | |
* located at the beginning of CODE SRAM. A processor/chip | |
* reset will go to the BootROM reset/startup code and | |
* begin the BootROM SPI application load sequence. | |
* Upon a successful SPI load and verification, BootROM | |
* will jump into the Application. We expect the jump address | |
* to be .startup(reset handler) of the application because | |
* .startup runs the XC32 startup code and calls C main. | |
* Since application .startup is never entered on a real HW | |
* reset/nmi/soft-reset it can be located anywhere in SRAM | |
* CODE space. | |
*/ | |
.startup : | |
{ | |
KEEP(*(.startup)) | |
KEEP(*(.reset.startup)) | |
} > kseg0_program_mem | |
/* Code Sections - Note that input sections *(.text) and *(.text.*) | |
* are not mapped here. The best-fit allocator locates them, | |
* so that .text may flow around absolute sections as needed. | |
*/ | |
.text : | |
{ | |
*(.stub .gnu.linkonce.t.*) | |
KEEP (*(.text.*personality*)) | |
*(.mips16.fn.*) | |
*(.mips16.call.*) | |
*(.gnu.warning) | |
. = ALIGN(4) ; | |
} >kseg0_program_mem | |
/* Global-namespace object initialization */ | |
.init : | |
{ | |
KEEP (*crti.o(.init)) | |
KEEP (*crtbegin.o(.init)) | |
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o *crtn.o ).init)) | |
KEEP (*crtend.o(.init)) | |
KEEP (*crtn.o(.init)) | |
. = ALIGN(4) ; | |
} >kseg0_program_mem | |
.fini : | |
{ | |
KEEP (*(.fini)) | |
. = ALIGN(4) ; | |
} >kseg0_program_mem | |
.preinit_array : | |
{ | |
PROVIDE_HIDDEN (__preinit_array_start = .); | |
KEEP (*(.preinit_array)) | |
PROVIDE_HIDDEN (__preinit_array_end = .); | |
. = ALIGN(4) ; | |
} >kseg0_program_mem | |
.init_array : | |
{ | |
PROVIDE_HIDDEN (__init_array_start = .); | |
KEEP (*(SORT(.init_array.*))) | |
KEEP (*(.init_array)) | |
PROVIDE_HIDDEN (__init_array_end = .); | |
. = ALIGN(4) ; | |
} >kseg0_program_mem | |
.fini_array : | |
{ | |
PROVIDE_HIDDEN (__fini_array_start = .); | |
KEEP (*(SORT(.fini_array.*))) | |
KEEP (*(.fini_array)) | |
PROVIDE_HIDDEN (__fini_array_end = .); | |
. = ALIGN(4) ; | |
} >kseg0_program_mem | |
.ctors : | |
{ | |
/* XC32 uses crtbegin.o to find the start of | |
the constructors, so we make sure it is | |
first. Because this is a wildcard, it | |
doesn't matter if the user does not | |
actually link against crtbegin.o; the | |
linker won't look for a file to match a | |
wildcard. The wildcard also means that it | |
doesn't matter which directory crtbegin.o | |
is in. */ | |
KEEP (*crtbegin.o(.ctors)) | |
KEEP (*crtbegin?.o(.ctors)) | |
/* We don't want to include the .ctor section from | |
the crtend.o file until after the sorted ctors. | |
The .ctor section from the crtend file contains the | |
end of ctors marker and it must be last */ | |
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) | |
KEEP (*(SORT(.ctors.*))) | |
KEEP (*(.ctors)) | |
. = ALIGN(4) ; | |
} >kseg0_program_mem | |
.dtors : | |
{ | |
KEEP (*crtbegin.o(.dtors)) | |
KEEP (*crtbegin?.o(.dtors)) | |
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) | |
KEEP (*(SORT(.dtors.*))) | |
KEEP (*(.dtors)) | |
. = ALIGN(4) ; | |
} >kseg0_program_mem | |
/* Read-only sections */ | |
.rodata : | |
{ | |
*( .gnu.linkonce.r.*) | |
*(.rodata1) | |
. = ALIGN(4) ; | |
} >kseg0_program_mem | |
/* | |
* Small initialized constant global and static data can be placed in the | |
* .sdata2 section. This is different from .sdata, which contains small | |
* initialized non-constant global and static data. | |
*/ | |
.sdata2 ALIGN(4) : | |
{ | |
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*) | |
. = ALIGN(4) ; | |
} >kseg0_program_mem | |
/* | |
* Uninitialized constant global and static data (i.e., variables which will | |
* always be zero). Again, this is different from .sbss, which contains | |
* small non-initialized, non-constant global and static data. | |
*/ | |
.sbss2 ALIGN(4) : | |
{ | |
*(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) | |
. = ALIGN(4) ; | |
} >kseg0_program_mem | |
.eh_frame_hdr : | |
{ | |
*(.eh_frame_hdr) | |
} >kseg0_program_mem | |
. = ALIGN(4) ; | |
.eh_frame : ONLY_IF_RO | |
{ | |
KEEP (*(.eh_frame)) | |
} >kseg0_program_mem | |
. = ALIGN(4) ; | |
.gcc_except_table : ONLY_IF_RO | |
{ | |
*(.gcc_except_table .gcc_except_table.*) | |
} >kseg0_program_mem | |
. = ALIGN(4) ; | |
.persist : | |
{ | |
_persist_begin = .; | |
*(.persist .persist.*) | |
*(.pbss .pbss.*) | |
. = ALIGN(4) ; | |
_persist_end = .; | |
} >kseg1_data_mem | |
.jcr : | |
{ | |
KEEP (*(.jcr)) | |
. = ALIGN(4) ; | |
} >kseg1_data_mem | |
.eh_frame : ONLY_IF_RW | |
{ | |
KEEP (*(.eh_frame)) | |
} >kseg1_data_mem | |
. = ALIGN(4) ; | |
.gcc_except_table : ONLY_IF_RW | |
{ | |
*(.gcc_except_table .gcc_except_table.*) | |
} >kseg1_data_mem | |
. = ALIGN(4) ; | |
/* Persistent data - Use the new C 'persistent' attribute instead. */ | |
/* | |
.persist : | |
{ | |
_persist_begin = .; | |
*(.persist .persist.*) | |
*(.pbss .pbss.*) | |
. = ALIGN(4) ; | |
_persist_end = .; | |
} >kseg1_data_mem | |
*/ | |
/* | |
* Note that input sections named .data* are not mapped here. | |
* The best-fit allocator locates them, so that they may flow | |
* around absolute sections as needed. | |
*/ | |
.data : | |
{ | |
*( .gnu.linkonce.d.*) | |
SORT(CONSTRUCTORS) | |
*(.data1) | |
. = ALIGN(4) ; | |
} >kseg1_data_mem | |
. = .; | |
_gp = ALIGN(16) + 0x7ff0; | |
.got ALIGN(4) : | |
{ | |
*(.got.plt) *(.got) | |
. = ALIGN(4) ; | |
} >kseg1_data_mem /* AT>kseg0_program_mem */ | |
/* | |
* Note that 'small' data sections are still mapped in the linker | |
* script. This ensures that they are grouped together for | |
* gp-relative addressing. Absolute sections are allocated after | |
* the 'small' data sections so small data cannot flow around them. | |
*/ | |
/* | |
* We want the small data sections together, so single-instruction offsets | |
* can access them all, and initialized data all before uninitialized, so | |
* we can shorten the on-disk segment size. | |
*/ | |
.sdata ALIGN(4) : | |
{ | |
_sdata_begin = . ; | |
*(.sdata .sdata.* .gnu.linkonce.s.*) | |
. = ALIGN(4) ; | |
_sdata_end = . ; | |
} >kseg1_data_mem | |
.lit8 : | |
{ | |
*(.lit8) | |
} >kseg1_data_mem | |
.lit4 : | |
{ | |
*(.lit4) | |
} >kseg1_data_mem | |
. = ALIGN (4) ; | |
_data_end = . ; | |
_bss_begin = . ; | |
.sbss ALIGN(4) : | |
{ | |
_sbss_begin = . ; | |
*(.dynsbss) | |
*(.sbss .sbss.* .gnu.linkonce.sb.*) | |
*(.scommon) | |
_sbss_end = . ; | |
. = ALIGN(4) ; | |
} >kseg1_data_mem | |
/* | |
* Align here to ensure that the .bss section occupies space up to | |
* _end. Align after .bss to ensure correct alignment even if the | |
* .bss section disappears because there are no input sections. | |
* | |
* Note that input sections named .bss* are no longer mapped here. | |
* The best-fit allocator locates them, so that they may flow | |
* around absolute sections as needed. | |
* | |
*/ | |
.bss : | |
{ | |
*(.dynbss) | |
*(COMMON) | |
/* Align here to ensure that the .bss section occupies space up to | |
_end. Align after .bss to ensure correct alignment even if the | |
.bss section disappears because there are no input sections. */ | |
. = ALIGN(. != 0 ? 4 : 1); | |
} >kseg1_data_mem | |
. = ALIGN(4) ; | |
_end = . ; | |
_bss_end = . ; | |
/* | |
* The heap and stack are best-fit allocated by the linker after other | |
* data and bss sections have been allocated. | |
*/ | |
/* MCHP - disable best-fit allocation of stack & heap */ | |
.heap ALIGN(16) : | |
{ | |
_heap_bottom = .; | |
. += _min_heap_size; | |
_heap_top = .; | |
} >kseg1_data_mem | |
.stack ALIGN(16) : | |
{ | |
_stack_bottom = .; | |
. += _min_stack_size; | |
. = ALIGN(16); | |
_stack_top = .; | |
} >kseg1_data_mem | |
PROVIDE( _heap = _heap_bottom ); | |
PROVIDE( _stack = _stack_top ); | |
PROVIDE( _stack_start = _stack_bottom ); | |
/* | |
* RAM functions go at the end of our stack and heap allocation. | |
* Alignment of 2K required by the boundary register (BMXDKPBA). | |
* | |
* RAM functions are now allocated by the linker. The linker generates | |
* _ramfunc_begin and _bmxdkpba_address symbols depending on the | |
* location of RAM functions. | |
*/ | |
_bmxdudba_address = LENGTH(kseg1_data_mem) ; | |
_bmxdupba_address = LENGTH(kseg1_data_mem) ; | |
/* The .pdr section belongs in the absolute section */ | |
/DISCARD/ : { *(.pdr) } | |
.gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } | |
.gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } | |
.mdebug.abi32 : { KEEP(*(.mdebug.abi32)) } | |
.mdebug.abiN32 : { KEEP(*(.mdebug.abiN32)) } | |
.mdebug.abi64 : { KEEP(*(.mdebug.abi64)) } | |
.mdebug.abiO64 : { KEEP(*(.mdebug.abiO64)) } | |
.mdebug.eabi32 : { KEEP(*(.mdebug.eabi32)) } | |
.mdebug.eabi64 : { KEEP(*(.mdebug.eabi64)) } | |
.gcc_compiled_long32 : { KEEP(*(.gcc_compiled_long32)) } | |
.gcc_compiled_long64 : { KEEP(*(.gcc_compiled_long64)) } | |
/* Stabs debugging sections. */ | |
.stab 0 : { *(.stab) } | |
.stabstr 0 : { *(.stabstr) } | |
.stab.excl 0 : { *(.stab.excl) } | |
.stab.exclstr 0 : { *(.stab.exclstr) } | |
.stab.index 0 : { *(.stab.index) } | |
.stab.indexstr 0 : { *(.stab.indexstr) } | |
.comment 0 : { *(.comment) } | |
/* DWARF debug sections used by MPLAB X for source-level debugging. | |
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) } | |
/* 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) } | |
.debug_pubtypes 0 : { *(.debug_pubtypes) } | |
.debug_ranges 0 : { *(.debug_ranges) } | |
/DISCARD/ : { *(.rel.dyn) } | |
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } | |
/DISCARD/ : { *(.note.GNU-stack) } | |
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.discard) } | |
} | |