You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
423 lines
14 KiB
423 lines
14 KiB
/* 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. Can be overridden from
|
|
* 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 = 0) ; Defined on the command line */
|
|
/* INCLUDE procdefs.ld */
|
|
|
|
/*************************************************************************
|
|
* Processor-specific object file. Contains SFR definitions.
|
|
*************************************************************************/
|
|
INPUT("processor.o")
|
|
|
|
/*************************************************************************
|
|
* Processor-specific peripheral libraries are optional
|
|
*************************************************************************/
|
|
OPTIONAL("libmchp_peripheral.a")
|
|
OPTIONAL("libmchp_peripheral_32MX534F064H.a")
|
|
|
|
/*************************************************************************
|
|
* For interrupt vector handling
|
|
*************************************************************************/
|
|
PROVIDE(_vector_spacing = 0x00000001);
|
|
_ebase_address = 0x9FC01000;
|
|
|
|
/*************************************************************************
|
|
* Memory Address Equates
|
|
* _RESET_ADDR -- Reset Vector
|
|
* _BEV_EXCPT_ADDR -- Boot exception Vector
|
|
* _DBG_EXCPT_ADDR -- In-circuit Debugging Exception Vector
|
|
* _DBG_CODE_ADDR -- In-circuit Debug Executive address
|
|
* _DBG_CODE_SIZE -- In-circuit Debug Executive size
|
|
* _GEN_EXCPT_ADDR -- General Exception Vector
|
|
*************************************************************************/
|
|
_RESET_ADDR = 0xBFC00000;
|
|
_BEV_EXCPT_ADDR = 0xBFC00380;
|
|
_DBG_EXCPT_ADDR = 0xBFC00480;
|
|
_DBG_CODE_ADDR = 0xBFC02000;
|
|
_DBG_CODE_SIZE = 0xFF0 ;
|
|
_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
|
|
{
|
|
|
|
kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x3000 /* 12KB memory for bootloader */
|
|
kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x490
|
|
kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970
|
|
exception_mem : ORIGIN = 0x9FC01000, LENGTH = 0 /* Bootloader doesn't need IVT */
|
|
|
|
debug_exec_mem : ORIGIN = 0xBFC02000, LENGTH = 0xFF0
|
|
config3 : ORIGIN = 0xBFC02FF0, LENGTH = 0x4
|
|
config2 : ORIGIN = 0xBFC02FF4, LENGTH = 0x4
|
|
config1 : ORIGIN = 0xBFC02FF8, LENGTH = 0x4
|
|
config0 : ORIGIN = 0xBFC02FFC, LENGTH = 0x4
|
|
kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x4000
|
|
sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000
|
|
configsfrs : ORIGIN = 0xBFC02FF0, LENGTH = 0x10
|
|
|
|
}
|
|
|
|
SECTIONS
|
|
{
|
|
.config_BFC02FF0 : {
|
|
KEEP(*(.config_BFC02FF0))
|
|
} > config3
|
|
.config_BFC02FF4 : {
|
|
KEEP(*(.config_BFC02FF4))
|
|
} > config2
|
|
.config_BFC02FF8 : {
|
|
KEEP(*(.config_BFC02FF8))
|
|
} > config1
|
|
.config_BFC02FFC : {
|
|
KEEP(*(.config_BFC02FFC))
|
|
} > config0
|
|
}
|
|
|
|
|
|
|
|
PROVIDE(_DBG_CODE_ADDR = 0xBFC02000) ;
|
|
PROVIDE(_DBG_CODE_SIZE = 0xFF0) ;
|
|
SECTIONS
|
|
{
|
|
/* Boot Sections */
|
|
.reset _RESET_ADDR :
|
|
{
|
|
KEEP(*(.reset))
|
|
KEEP(*(.reset.startup))
|
|
} > kseg1_boot_mem
|
|
.bev_excpt _BEV_EXCPT_ADDR :
|
|
{
|
|
KEEP(*(.bev_handler))
|
|
} > kseg1_boot_mem
|
|
.dbg_excpt _DBG_EXCPT_ADDR (NOLOAD) :
|
|
{
|
|
. += (DEFINED (_DEBUGGER) ? 0x8 : 0x0);
|
|
} > kseg1_boot_mem
|
|
.dbg_code _DBG_CODE_ADDR (NOLOAD) :
|
|
{
|
|
. += (DEFINED (_DEBUGGER) ? _DBG_CODE_SIZE : 0x0);
|
|
} > debug_exec_mem
|
|
|
|
|
|
/* Starting with C32 v2.00, the startup code is in the .reset.startup section.
|
|
* Keep this here for backwards compatibility.
|
|
*/
|
|
.startup ORIGIN(kseg0_boot_mem) :
|
|
{
|
|
KEEP(*(.startup))
|
|
} > kseg0_boot_mem
|
|
/* Code Sections - Note that input sections *(.text) and *(.text.*)
|
|
** are not mapped here. Starting in C32 v2.00, 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) ;
|
|
.dbg_data (NOLOAD) :
|
|
{
|
|
. += (DEFINED (_DEBUGGER) ? 0x200 : 0x0);
|
|
} >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 no longer mapped here.
|
|
* Starting in C32 v2.00, 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.
|
|
* Starting in C32 v2.00, 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 = . ;
|
|
/* Starting with C32 v2.00, the heap and stack are dynamically
|
|
* allocated by the linker.
|
|
*/
|
|
/*
|
|
* 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.
|
|
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) }
|
|
}
|