233 lines
5.8 KiB
Text
233 lines
5.8 KiB
Text
/*
|
|
* SPDX-License-Identifier: CC0-1.0
|
|
*
|
|
* SPDX-FileContributor: Antonio Niño Díaz, 2022
|
|
*/
|
|
|
|
/*
|
|
* Some links with information about linker scripts:
|
|
*
|
|
* - https://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/specialsections.html
|
|
*
|
|
* - https://blog.thea.codes/the-most-thoroughly-commented-linker-script/
|
|
*
|
|
* - http://beefchunk.com/documentation/sys-programming/binary_formats/elf/elf_from_the_programmers_perspective/node4.html
|
|
*/
|
|
|
|
OUTPUT_FORMAT("elf32-littlearm")
|
|
OUTPUT_ARCH(arm)
|
|
ENTRY(entrypoint)
|
|
|
|
MEMORY {
|
|
ROM : ORIGIN = 0x08000000, LENGTH = 32M
|
|
IWRAM : ORIGIN = 0x03000000, LENGTH = 32K
|
|
EWRAM : ORIGIN = 0x02000000, LENGTH = 256K
|
|
}
|
|
|
|
/* Set stack pointers the same way as the BIOS */
|
|
|
|
__STACK_SVC_SIZE__ = 0x40;
|
|
__STACK_IRQ_SIZE__ = 0xA0;
|
|
__STACK_USR_SIZE_MIN__ = 0x200; /* Minimum size, the real size may be bigger */
|
|
|
|
__STACK_END__ = ORIGIN(IWRAM) + LENGTH(IWRAM) - 0x20; /* Used by BIOS */
|
|
__STACK_SVC_END__ = __STACK_END__;
|
|
__STACK_SVC_START__ = __STACK_SVC_END__ - __STACK_SVC_SIZE__;
|
|
__STACK_IRQ_END__ = __STACK_SVC_START__;
|
|
__STACK_IRQ_START__ = __STACK_IRQ_END__ - __STACK_IRQ_SIZE__;
|
|
__STACK_USR_END__ = __STACK_IRQ_START__;
|
|
__STACK_USR_START__ = __STACK_USR_END__ - __STACK_USR_SIZE_MIN__;
|
|
__STACK_START__ = __STACK_USR_START__;
|
|
|
|
SECTIONS
|
|
{
|
|
/*
|
|
* ROM sections
|
|
* ============
|
|
*/
|
|
|
|
/* Header and crt0 */
|
|
|
|
.gba_crt0 : ALIGN(4)
|
|
{
|
|
KEEP (*(.gba_crt0))
|
|
} > ROM
|
|
|
|
/* Code */
|
|
|
|
.text : ALIGN(4)
|
|
{
|
|
*(.text)
|
|
*(.text*)
|
|
*(.gnu.linkonce.t.*) /* Used for vague linking */
|
|
|
|
/* ARM/Thumb interworking code */
|
|
*(.glue_7) /* glue arm to thumb code */
|
|
*(.glue_7t) /* glue thumb to arm code */
|
|
|
|
/* Array of functions to be called at the start of the program */
|
|
KEEP(*(.init))
|
|
/* Array of functions to be called at the end of the program */
|
|
KEEP(*(.fini))
|
|
} > ROM
|
|
|
|
/* Read-only data */
|
|
|
|
.rodata : ALIGN(4)
|
|
{
|
|
*(.rodata)
|
|
*(.rodata*)
|
|
*(.gnu.linkonce.r.*) /* Used for vague linking */
|
|
} > ROM
|
|
|
|
/*
|
|
* Required for C++ and for C programs that try to examine backtraces. Each
|
|
* function that can throw exceptions has entries in exidx and extab.
|
|
*
|
|
* - exidx is used to contain index entries for stack unwinding.
|
|
* - extab names sections containing exception unwinding information.
|
|
*/
|
|
|
|
.ARM.extab : ALIGN(4)
|
|
{
|
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
|
} > ROM
|
|
|
|
.ARM.exidx : ALIGN(4)
|
|
{
|
|
PROVIDE_HIDDEN(__exidx_start = .);
|
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
|
PROVIDE_HIDDEN(__exidx_end = .);
|
|
} > ROM
|
|
|
|
/* Array of functions to be called during initialization of the program */
|
|
|
|
.preinit_array : ALIGN(4)
|
|
{
|
|
__preinit_array_start = .;
|
|
KEEP(*(.preinit_array*))
|
|
__preinit_array_end = .;
|
|
} > ROM
|
|
|
|
/*
|
|
* Array of functions to be called during initialization of the program.
|
|
* They are called after calling everything in .preinit_array
|
|
*/
|
|
|
|
.init_array : ALIGN(4)
|
|
{
|
|
__init_array_start = .;
|
|
KEEP(*(SORT(.init_array.*)))
|
|
KEEP(*(.init_array*))
|
|
__init_array_end = .;
|
|
} > ROM
|
|
|
|
/* Array of functions called when the program ends. */
|
|
|
|
.fini_array : ALIGN(4)
|
|
{
|
|
__fini_array_start = .;
|
|
KEEP(*(SORT(.fini_array.*)))
|
|
KEEP(*(.fini_array*))
|
|
__fini_array_end = .;
|
|
} > ROM
|
|
|
|
/*
|
|
* IWRAM sections
|
|
* ==============
|
|
*/
|
|
|
|
/* Uninitialized variables */
|
|
|
|
.bss (NOLOAD) : ALIGN(4)
|
|
{
|
|
*(.bss)
|
|
*(.bss*)
|
|
*(.gnu.linkonce.b.*) /* Used for vague linking */
|
|
*(COMMON) /* In case -fcommon is used in gcc (not used by default) */
|
|
. = ALIGN(4);
|
|
} > IWRAM
|
|
|
|
__IWRAM_BSS_START__ = ADDR(.bss);
|
|
__IWRAM_BSS_SIZE__ = SIZEOF(.bss);
|
|
__IWRAM_BSS_END__ = __IWRAM_BSS_START__ + __IWRAM_BSS_SIZE__;
|
|
|
|
/* Read-write data goes into IWRAM */
|
|
|
|
.data : ALIGN(4)
|
|
{
|
|
__DATA_START__ = .;
|
|
*(.data)
|
|
*(.data*)
|
|
*(.gnu.linkonce.d.*) /* Used for vague linking */
|
|
. = ALIGN(4);
|
|
__DATA_END__ = .;
|
|
} > IWRAM AT> ROM
|
|
|
|
__DATA_SIZE__ = __DATA_END__ - __DATA_START__;
|
|
__DATA_LMA__ = LOADADDR(.data);
|
|
|
|
/* Sections that the user requests to add to IWRAM */
|
|
|
|
.iwram : ALIGN(4)
|
|
{
|
|
__IWRAM_START__ = .;
|
|
*(.iwram)
|
|
*(.iwram*)
|
|
*iwram.*(.text*)
|
|
*iwram.*(.data*)
|
|
. = ALIGN(4);
|
|
__IWRAM_END__ = .;
|
|
} > IWRAM AT> ROM
|
|
|
|
__IWRAM_SIZE__ = __IWRAM_END__ - __IWRAM_START__;
|
|
__IWRAM_LMA__ = LOADADDR(.iwram);
|
|
|
|
/* The stack goes afterwards, check that there aren't overflows */
|
|
|
|
ASSERT(__IWRAM_END__ <= __STACK_START__,
|
|
"Not enough free IWRAM for stack")
|
|
|
|
/* Calculate real size of the user stack */
|
|
|
|
__STACK_USR_SIZE__ = __STACK_USR_END__ - __IWRAM_END__;
|
|
|
|
/*
|
|
* EWRAM sections
|
|
* ==============
|
|
*/
|
|
|
|
/*
|
|
* Uninitialized data explicitly placed in EWRAM. This section must be
|
|
* called ".sbss" for compatibility with devkitARM.
|
|
*/
|
|
|
|
.sbss (NOLOAD) : ALIGN(4)
|
|
{
|
|
*(.sbss)
|
|
*(.sbss*)
|
|
. = ALIGN(4);
|
|
} > EWRAM
|
|
|
|
/* Initialized data explicitly placed in EWRAM */
|
|
|
|
.ewram : ALIGN(4)
|
|
{
|
|
__EWRAM_START__ = .;
|
|
*(.ewram)
|
|
*(.ewram*)
|
|
*ewram.*(.text*)
|
|
*ewram.*(.data*)
|
|
. = ALIGN(4);
|
|
__EWRAM_END__ = .;
|
|
} > EWRAM AT > ROM
|
|
|
|
__EWRAM_SIZE__ = __EWRAM_END__ - __EWRAM_START__;
|
|
__EWRAM_LMA__ = LOADADDR(.ewram);
|
|
|
|
/* The heap information should be after the last EWRAM section */
|
|
|
|
__HEAP_START__ = __EWRAM_END__;
|
|
__HEAP_END__ = ORIGIN(EWRAM) + LENGTH(EWRAM);
|
|
__HEAP_SIZE__ = __HEAP_END__ - __HEAP_START__;
|
|
}
|