2019-12-18 01:59:00 +00:00
|
|
|
PROVIDE(_stext = ORIGIN(REGION_TEXT));
|
|
|
|
PROVIDE(_stack_start = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK));
|
|
|
|
PROVIDE(_max_hart_id = 0);
|
|
|
|
PROVIDE(_hart_stack_size = 2K);
|
|
|
|
PROVIDE(_heap_size = 0);
|
|
|
|
|
|
|
|
PROVIDE(trap_handler = default_trap_handler);
|
|
|
|
|
|
|
|
/* # Pre-initialization function */
|
|
|
|
/* If the user overrides this using the `#[pre_init]` attribute or by creating a `__pre_init` function,
|
|
|
|
then the function this points to will be called before the RAM is initialized. */
|
|
|
|
PROVIDE(__pre_init = default_pre_init);
|
|
|
|
|
|
|
|
/* # Multi-processing hook function
|
|
|
|
fn _mp_hook() -> bool;
|
|
|
|
|
|
|
|
This function is called from all the harts and must return true only for one hart,
|
|
|
|
which will perform memory initialization. For other harts it must return false
|
|
|
|
and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
|
|
|
|
*/
|
|
|
|
PROVIDE(_mp_hook = default_mp_hook);
|
|
|
|
|
|
|
|
ENTRY(_start)
|
|
|
|
|
|
|
|
SECTIONS
|
|
|
|
{
|
|
|
|
.text.dummy (NOLOAD) :
|
|
|
|
{
|
|
|
|
/* This section is intended to make _stext address work */
|
|
|
|
. = _stext;
|
|
|
|
} > REGION_TEXT
|
|
|
|
|
|
|
|
.text _stext :
|
|
|
|
{
|
|
|
|
/* Put reset handler first in .text section so it ends up as the entry */
|
|
|
|
/* point of the program. */
|
|
|
|
KEEP(*(.text.init));
|
|
|
|
KEEP(*(.init));
|
|
|
|
KEEP(*(.init.rust));
|
|
|
|
. = ALIGN(4);
|
|
|
|
KEEP(*(.trap));
|
|
|
|
KEEP(*(.trap.rust));
|
|
|
|
|
|
|
|
*(.text .text.*);
|
|
|
|
} > REGION_TEXT
|
|
|
|
|
|
|
|
.rodata : ALIGN(4)
|
|
|
|
{
|
|
|
|
*(.rodata .rodata.*);
|
|
|
|
|
|
|
|
/* 4-byte align the end (VMA) of this section.
|
|
|
|
This is required by LLD to ensure the LMA of the following .data
|
|
|
|
section will have the correct alignment. */
|
|
|
|
. = ALIGN(4);
|
2019-12-25 12:11:15 +00:00
|
|
|
_etext = .;
|
2019-12-18 01:59:00 +00:00
|
|
|
} > REGION_RODATA
|
|
|
|
|
|
|
|
.data : ALIGN(4)
|
|
|
|
{
|
|
|
|
_sidata = LOADADDR(.data);
|
|
|
|
_sdata = .;
|
|
|
|
/* Must be called __global_pointer$ for linker relaxations to work. */
|
|
|
|
PROVIDE(__global_pointer$ = . + 0x800);
|
|
|
|
*(.sdata .sdata.* .sdata2 .sdata2.*);
|
|
|
|
*(.data .data.*);
|
|
|
|
. = ALIGN(4);
|
|
|
|
_edata = .;
|
|
|
|
} > REGION_DATA AT > REGION_RODATA
|
|
|
|
|
|
|
|
.bss (NOLOAD) :
|
|
|
|
{
|
|
|
|
_sbss = .;
|
|
|
|
*(.sbss .sbss.* .bss .bss.*);
|
|
|
|
. = ALIGN(4);
|
|
|
|
_ebss = .;
|
|
|
|
} > REGION_BSS
|
|
|
|
|
|
|
|
/* fictitious region that represents the memory available for the stack */
|
|
|
|
.stack (NOLOAD) :
|
|
|
|
{
|
|
|
|
_estack = .;
|
2019-12-24 01:33:02 +00:00
|
|
|
PROVIDE(_stack_start = .);
|
|
|
|
. += _stack_size;
|
2019-12-18 01:59:00 +00:00
|
|
|
_sstack = .;
|
|
|
|
} > REGION_STACK
|
|
|
|
|
2019-12-24 01:33:02 +00:00
|
|
|
/* fictitious region that represents the memory available for the heap */
|
|
|
|
.heap (NOLOAD) :
|
|
|
|
{
|
|
|
|
. = ALIGN(4);
|
|
|
|
_sheap = .;
|
|
|
|
/* _eheap is defined elsewhere and is the remainder of RAM */
|
|
|
|
} > REGION_HEAP
|
|
|
|
|
2019-12-18 01:59:00 +00:00
|
|
|
/* fake output .got section */
|
|
|
|
/* Dynamic relocations are unsupported. This section is only used to detect
|
|
|
|
relocatable code in the input files and raise an error if relocatable code
|
|
|
|
is found */
|
|
|
|
.got (INFO) :
|
|
|
|
{
|
|
|
|
KEEP(*(.got .got.*));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Discard .eh_frame, we are not doing unwind on panic so it is not needed */
|
|
|
|
/DISCARD/ :
|
|
|
|
{
|
|
|
|
*(.eh_frame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do not exceed this mark in the error messages above | */
|
|
|
|
ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
|
|
|
|
ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
|
|
|
|
|
|
|
|
ASSERT(ORIGIN(REGION_RODATA) % 4 == 0, "
|
|
|
|
ERROR(riscv-rt): the start of the REGION_RODATA must be 4-byte aligned");
|
|
|
|
|
|
|
|
ASSERT(ORIGIN(REGION_DATA) % 4 == 0, "
|
|
|
|
ERROR(riscv-rt): the start of the REGION_DATA must be 4-byte aligned");
|
|
|
|
|
|
|
|
ASSERT(ORIGIN(REGION_HEAP) % 4 == 0, "
|
|
|
|
ERROR(riscv-rt): the start of the REGION_HEAP must be 4-byte aligned");
|
|
|
|
|
|
|
|
ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
|
|
|
|
ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
|
|
|
|
|
|
|
|
ASSERT(ORIGIN(REGION_STACK) % 4 == 0, "
|
|
|
|
ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned");
|
|
|
|
|
|
|
|
ASSERT(_stext % 4 == 0, "
|
|
|
|
ERROR(riscv-rt): `_stext` must be 4-byte aligned");
|
|
|
|
|
|
|
|
ASSERT(_sdata % 4 == 0 && _edata % 4 == 0, "
|
|
|
|
BUG(riscv-rt): .data is not 4-byte aligned");
|
|
|
|
|
|
|
|
ASSERT(_sidata % 4 == 0, "
|
|
|
|
BUG(riscv-rt): the LMA of .data is not 4-byte aligned");
|
|
|
|
|
|
|
|
ASSERT(_sbss % 4 == 0 && _ebss % 4 == 0, "
|
|
|
|
BUG(riscv-rt): .bss is not 4-byte aligned");
|
|
|
|
|
|
|
|
ASSERT(_sheap % 4 == 0, "
|
|
|
|
BUG(riscv-rt): start of .heap is not 4-byte aligned");
|
|
|
|
|
|
|
|
ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), "
|
|
|
|
ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region.
|
|
|
|
Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'");
|
|
|
|
|
|
|
|
ASSERT(SIZEOF(.stack) > (_max_hart_id + 1) * _hart_stack_size, "
|
|
|
|
ERROR(riscv-rt): .stack section is too small for allocating stacks for all the harts.
|
|
|
|
Consider changing `_max_hart_id` or `_hart_stack_size`.");
|
|
|
|
|
|
|
|
ASSERT(SIZEOF(.got) == 0, "
|
|
|
|
.got section detected in the input files. Dynamic relocations are not
|
|
|
|
supported. If you are linking to C code compiled using the `gcc` crate
|
|
|
|
then modify your build script to compile the C code _without_ the
|
|
|
|
-fPIC flag. See the documentation of the `gcc::Config.fpic` method for
|
|
|
|
details.");
|
|
|
|
|
|
|
|
/* Do not exceed this mark in the error messages above | */
|