ENTRY(_enter) MEMORY { itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000 ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 rom (irx!wa) : ORIGIN = 0x20000000, LENGTH = 0x10000000 } PHDRS { rom PT_LOAD; text PT_LOAD; ram PT_LOAD; ram_init PT_LOAD; itim_init PT_LOAD; lim_init PT_LOAD; } SECTIONS { __stack_size = DEFINED(__stack_size) ? __stack_size : 0x1000; /* ROM SECTION * * The following sections contain data which lives in read-only memory, if * such memory is present in the design, for the entire duration of program * execution. */ .init : { /* The _enter symbol is placed in the .text.metal.init.enter section * and must be placed at the beginning of the program */ KEEP (*(.text.metal.init.enter)) KEEP (*(.text.metal.init.*)) KEEP (*(SORT_NONE(.init))) KEEP (*(.text.libgloss.start)) } >rom :rom .fini : { KEEP (*(SORT_NONE(.fini))) } >rom :rom .preinit_array : ALIGN(8) { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); } >rom :rom .init_array : ALIGN(8) { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) PROVIDE_HIDDEN (__init_array_end = .); } >rom :rom .fini_array : ALIGN(8) { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) PROVIDE_HIDDEN (__fini_array_end = .); } >rom :rom .ctors : { KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin?.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) } >rom :rom .dtors : { KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin?.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) } >rom : rom .rodata : { *(.rdata) *(.rodata .rodata.*) *(.gnu.linkonce.r.*) . = ALIGN(8); *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) } >rom :rom /* ITIM SECTION * * The following sections contain data which is copied from read-only * memory into an instruction tightly-integrated memory (ITIM), if one * is present in the design, during pre-main program initialization. * * Generally, the data copied into the ITIM should be performance-critical * functions which benefit from low instruction-fetch latency. */ .itim : ALIGN(8) { *(.itim .itim.*) *(.itim2 .itim2.*) } >itim AT>rom :itim_init PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) ); PROVIDE( metal_segment_itim_target_start = ADDR(.itim) ); PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) ); /* LIM SECTION * * The following sections contain data which is copied from read-only * memory into a loosely integrated memory (LIM), which is shared with L2 * cache, during pre-main program initialization. * * Generally, the data copied into the LIM should be performance-critical * functions which benefit from low instruction-fetch latency. */ .lim : ALIGN(8) { *(.lim .lim.*) } >ram AT>rom :lim_init PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) ); PROVIDE( metal_segment_lim_target_start = ADDR(.lim) ); PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) ); /* TEXT SECTION * * The following section contains the code of the program, excluding * everything that's been allocated into the ITIM/LIM already */ .text : { *(.text.unlikely .text.unlikely.*) *(.text.startup .text.startup.*) *(.text .text.*) *(.gnu.linkonce.t.*) } >rom :text /* RAM SECTION * * The following sections contain data which is copied from read-only * memory into a read-write-capable memory such as data tightly-integrated * memory (DTIM) or another main memory, as well as the BSS, stack, and * heap. * * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all * have an apparently unnecessary ALIGN at their top. This is because * the implementation of _start in Freedom Metal libgloss depends on the * ADDR and LOADADDR being 8-byte aligned. */ .data : { *(.data .data.*) *(.gnu.linkonce.d.*) . = ALIGN(8); PROVIDE( __global_pointer$ = . + 0x800 ); *(.sdata .sdata.* .sdata2.*) *(.gnu.linkonce.s.*) } >ram AT>rom :ram_init PROVIDE( metal_segment_data_source_start = LOADADDR(.data) ); PROVIDE( metal_segment_data_target_start = ADDR(.data) ); PROVIDE( metal_segment_data_target_end = ADDR(.data) + SIZEOF(.data) ); .bss (NOLOAD) : { *(.sbss*) *(.gnu.linkonce.sb.*) *(.bss .bss.*) *(.gnu.linkonce.b.*) *(COMMON) } >ram :ram PROVIDE( metal_segment_bss_start = ADDR(.bss) ); PROVIDE( metal_segment_bss_end = ADDR(.bss) + SIZEOF(.bss) ); .stack (NOLOAD) : ALIGN(16) { . += __stack_size; PROVIDE( _sp = . ); } >ram :ram PROVIDE( metal_segment_stack_start = ADDR(.stack) ); PROVIDE( metal_segment_stack_end = ADDR(.stack) + SIZEOF(.stack) ); PROVIDE(__stack_size = __stack_size); .heap (NOLOAD) : ALIGN(8) { PROVIDE( __end = . ); PROVIDE( __heap_start = . ); . = LENGTH(ram) - ( . - ORIGIN(ram)); PROVIDE( _heap_end = . ); PROVIDE( __heap_end = . ); } >ram :ram PROVIDE( metal_segment_heap_start = ADDR(.heap) ); PROVIDE( metal_segment_heap_end = ADDR(.heap) + SIZEOF(.heap) ); /* C++ exception handling information is * not useful with our current runtime environment, * and it consumes flash space. Discard it until * we have something that can use it */ /DISCARD/ : { *(.eh_frame .eh_frame.*) } }