summaryrefslogtreecommitdiff
path: root/ports/risc-v64/gnu/example_build/erbium/link.lds
blob: 25ba92190450b36e5ec4979712e703931be72ea0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/***************************************************************************
 * Copyright (c) 2026 Eclipse ThreadX contributors
 *
 * This program and the accompanying materials are made available under the
 * terms of the MIT License which is available at
 * https://opensource.org/licenses/MIT.
 *
 * AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5.5).
 * The AI-generated portions may be considered public domain (CC0-1.0)
 * and not subject to the project's licence. The human contributor has
 * reviewed and verified that the code is correct.
 *
 * SPDX-License-Identifier: MIT and CC0-1.0
 **************************************************************************/

/* Erbium memory layout.
 *
 *   Address         Size       Usage
 *   ─────────────   ────────   ──────────────────────────────────────
 *   0x0200_0000     4 KiB      System registers (SystemConfig at +0x08)
 *   0x0200_4000     4 KiB      UART0
 *   0x4000_0000     512 B      MRAM, reserved for the boot flow
 *   0x4000_0200     ~16 MiB    MRAM: code, data, stacks and free memory
 *   0x80F4_0200     16 B       mtime, mtimecmp
 *   0xA000_0000     64 MiB     PLIC
 *
 * MRAM is directly readable, writable and executable, so .data runs in
 * place and needs no copy from a load address.
 */

OUTPUT_ARCH( "riscv" )
ENTRY( _start )

MEMORY
{
  MRAM (rwx) : ORIGIN = 0x40000200, LENGTH = 0x00FFFE00
}

PHDRS
{
  text PT_LOAD FLAGS(5);   /* PF_R | PF_X */
  data PT_LOAD FLAGS(6);   /* PF_R | PF_W */
}

SECTIONS
{
  /* _start must stay at the load address, so the 4 KiB aligned trap
     vector goes in the next output section rather than this one.  */
  .text.entry : {
    KEEP(*(.text.entry))
  } > MRAM :text

  .text : {
    KEEP(*(.text.trap))
    *(.text .text.*)
  } > MRAM :text

  .rodata : {
    . = ALIGN(16);
    *(.srodata .srodata.*)
    . = ALIGN(16);
    *(.rodata .rodata.*)
  } > MRAM :text

  .data : {
    . = ALIGN(16);
    PROVIDE( __global_pointer$ = . + 0x800 );
    *(.sdata .sdata.*)
    . = ALIGN(16);
    *(.data .data.*)
  } > MRAM :data

  .bss (NOLOAD) : {
    . = ALIGN(16);
    _bss_start = .;
    *(.sbss .sbss.*)
    . = ALIGN(16);
    *(.bss .bss.*)
    *(COMMON)
    . = ALIGN(16);
    _bss_end = .;
  } > MRAM :data

  .stack (NOLOAD) : {
    . = ALIGN(16);
    _sysstack_start = .;
    . += 0x1000;
    _sysstack_end = .;
  } > MRAM :data

  PROVIDE(_end = .);
}