/* Linker script for the fx9860g platform. Most of the symbols defined here are used in the initialization routine in core/start.c; others are used in core/setup.c. */ /* fx9860g may mean SH3 or SH4 and we want full compatibility */ OUTPUT_ARCH(sh3) /* ELF offers a lot of symbol/section/relocation insights */ OUTPUT_FORMAT(elf32-sh) /* Located in core/start.c */ ENTRY(_start) MEMORY { /* Userspace mapping of the add-in (0x200 B are for the G1A header). 220k is the maximum amount of simultaneously-mappable code */ rom (rx): o = 0x00300200, l = 220k /* This is mapped to RAM; 8k on SH3, apparently 32k on SH4 */ ram (rw): o = 0x08100000, l = 8k /* gint's VBR space, mentioned here for completeness */ vbr (rwx): o = 0x8800e000, l = 5k /* Some RAM region from P1 area; gint's data will reside here */ rram (rwx): o = 0x8800f400, l = 3k /* On-chip IL memory */ ilram (rwx): o = 0xe5200000, l = 4k /* On-chip X and Y memory */ xram (rwx): o = 0xe5007000, l = 8k yram (rwx): o = 0xe5017000, l = 8k } SECTIONS { /* ** ROM sections */ /* First address to be mapped to ROM (including G1A header) */ _brom = 0x00300000; /* Size of ROM mappings */ _srom = 0x200 + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.gint.drivers) + SIZEOF(.gint.blocks); /* Machine code going to ROM: - Initialization sections (.pretext.entry and .pretext) - Compiler-provided constructors (.ctors) and destructors (.dtors) - All text from .text and .text.* (including user code) - Code sections from fxlib, named "C" and "P" */ .pretext : { *(.pretext.entry) *(.pretext) _btors = . ; *(.ctors .ctors.*) _mtors = . ; *(.dtors .dtors.*) _etors = . ; } > rom .text : { _gint_exch_tlbh_start = . ; *(.gint.exch_tlbh); _gint_exch_tlbh_size = ABSOLUTE(. - _gint_exch_tlbh_start); *(.text .text.*) *(C P) } > rom /* Interrupt handlers going to ROM: - gint's interrupt handler blocks (.gint.blocks) Although gint's blocks end up in VBR space, they are selected and installed on-the-fly by the library and the drivers, so we can't just put them in the vbr region and wait for the copy */ .gint.blocks : { KEEP(*(.gint.blocks)); } > rom /* Driver data going to ROM: - Exposed driver interfaces (.gint.drivers) The driver information is required to start and configure the driver, even if the symbols are not referenced */ .gint.drivers : { _bdrv = . ; KEEP(*(.gint.drivers.0)); KEEP(*(.gint.drivers.1)); KEEP(*(.gint.drivers.2)); KEEP(*(.gint.drivers.3)); KEEP(*(.gint.drivers.4)); KEEP(*(.gint.drivers.5)); KEEP(*(.gint.drivers.6)); _edrv = . ; } > rom /* Read-only data going to ROM: - Resources or assets from fxconv or similar converters - Data marked read-only by the compiler (.rodata and .rodata.*) */ .rodata : SUBALIGN(4) { /* Put these first, they need to be 4-aligned */ *(.rodata.4) *(.rodata .rodata.*) } > rom /* ** RAM sections */ . = ORIGIN(ram); /* BSS stuff going to RAM: - Data marked BSS by the compiler - BSS sections from fxlib, namely "B" and "R" The BSS section is to be stripped from the ELF file later, and wiped at startup. */ .bss (NOLOAD) : { _rbss = . ; *(.bss COMMON) *(B R) . = ALIGN(16); } > ram :NONE _sbss = SIZEOF(.bss); /* Read-write data going to RAM: - Data sections generated by the compiler (.data and .data.*) - Data sections from fxlib, "D" */ .data ALIGN(4) : ALIGN(4) { _ldata = LOADADDR(.data); _rdata = . ; *(.data .data.*) *(D) . = ALIGN(16); } > ram AT> rom /* Read-write data sub-aligned to 4 bytes (mainly from fxconv) */ .data.4 : SUBALIGN(4) { *(.data.4) . = ALIGN(16); } > ram AT> rom _sdata = SIZEOF(.data) + SIZEOF(.data.4); /* On-chip memory sections: IL, X and Y memory */ . = ORIGIN(ilram); .ilram ALIGN(4) : ALIGN(4) { _lilram = LOADADDR(.ilram); _rilram = . ; *(.ilram) . = ALIGN(16); } > ilram AT> rom . = ORIGIN(xram); .xram ALIGN(4) : ALIGN(4) { _lxram = LOADADDR(.xram); _rxram = . ; *(.xram) . = ALIGN(16); } > xram AT> rom . = ORIGIN(yram); .yram ALIGN(4) : ALIGN(4) { _lyram = LOADADDR(.yram); _ryram = . ; *(.yram) . = ALIGN(16); } > yram AT> rom _silram = SIZEOF(.ilram); _sxram = SIZEOF(.xram); _syram = SIZEOF(.yram); /* ** RRAM sections ** 8800e000:5k VBR space ** 8800f400:3k .gint.data and .gint.bss */ /* VBR address: let's just start at the beginning of the RRAM area. There's an unused 0x100-byte gap at the start of the VBR space. The VBR space is already a large block (> 2 kiB), so I'm cutting off the gap to spare some memory */ _gint_vbr = 0x8800df00; . = ORIGIN(rram); /* gint's data section, going to Real RAM. This section contains many small objects from the library (static/global variables, etc) */ .gint.data ALIGN(4) : ALIGN(4) { _lgdata = LOADADDR(.gint.data); _rgdata = . ; *(.gint.data .gint.data.*) . = ALIGN(16); } > rram AT> rom _sgdata = SIZEOF(.gint.data); /* gint's uninitialized BSS section, going to Real RAM. All the large data arrays will be located here */ .gint.bss (NOLOAD) : { /* Since it's uninitialized, the location doesn't matter */ *(.gint.bss .gint.bss.*) . = ALIGN(16); } > rram :NONE _sgbss = SIZEOF(.gint.bss); /* ** Other sections */ /* Unwanted sections going to meet Dave Null: - Debug sections, often come out of libgcc - Java classes registration (why are there even here?) - Asynchronous unwind tables: no C++ exception handling for now ^^ - Comments or anything the compiler might put in its assembler - A stack section sometimes generated for build/version.o */ /DISCARD/ : { *(.debug_info .debug_abbrev .debug_loc .debug_aranges .debug_ranges .debug_line .debug_str) *(.jcr) *(.eh_frame_hdr) *(.eh_frame) *(.comment) } }