| /*-------------------------------------------------------------------------- | |
| * 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) } | |
| } | |