aboutsummaryrefslogtreecommitdiff
path: root/src/host/imxrt-link.x
blob: dfe7355e03550927da5822c09dc791ff7c768976 (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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/* ===--- Begin imxrt-link.x ---===
 * This section of the linker script is a fork of the default linker script provided by
 * imxrt-rt, version 0.7.1. It's modified to support the needs of imxrt-rt.
 */

/* # Entry point = reset vector */
EXTERN(__RESET_VECTOR);
EXTERN(Reset);
ENTRY(Reset);

/* # Exception vectors */
/* This is effectively weak aliasing at the linker level */
/* The user can override any of these aliases by defining the corresponding symbol themselves (cf.
   the `exception!` macro) */
EXTERN(__EXCEPTIONS); /* depends on all the these PROVIDED symbols */

EXTERN(DefaultHandler);
EXTERN(__pre_init);

PROVIDE(NonMaskableInt = DefaultHandler);
EXTERN(HardFaultTrampoline);
PROVIDE(MemoryManagement = DefaultHandler);
PROVIDE(BusFault = DefaultHandler);
PROVIDE(UsageFault = DefaultHandler);
PROVIDE(SecureFault = DefaultHandler);
PROVIDE(SVCall = DefaultHandler);
PROVIDE(DebugMonitor = DefaultHandler);
PROVIDE(PendSV = DefaultHandler);
PROVIDE(SysTick = DefaultHandler);

PROVIDE(DefaultHandler = DefaultHandler_);
PROVIDE(HardFault = HardFault_);

/* # Interrupt vectors */
EXTERN(__INTERRUPTS); /* `static` variable similar to `__EXCEPTIONS` */

/* # Sections */
SECTIONS
{
  .stack (NOLOAD) : ALIGN(8)
  {
    __estack = .;
    . += ALIGN(__stack_size, 8);
    __sstack = .;
    /* Symbol expected by cortex-m-rt */
    _stack_start = __sstack;
  } > REGION_STACK

  .vector_table : ALIGN(1024)
  {
    FILL(0xff);
    __vector_table = .;
    __svector_table = .;

    /* Initial Stack Pointer (SP) value */
    LONG(__sstack);

    /* Reset vector */
    KEEP(*(.vector_table.reset_vector)); /* this is the `__RESET_VECTOR` symbol */
    __reset_vector = .;

    /* Exceptions */
    KEEP(*(.vector_table.exceptions)); /* this is the `__EXCEPTIONS` symbol */
    __eexceptions = .;

    /* Device specific interrupts */
    KEEP(*(.vector_table.interrupts)); /* this is the `__INTERRUPTS` symbol */
    __evector_table = .;
  } > REGION_VTABLE AT> REGION_LOAD_VTABLE
  __sivector_table = LOADADDR(.vector_table);

  /* This section guarantees VMA = LMA to allow the execute-in-place entry point to be inside the image. */
  .xip : ALIGN(4)
  {
    /* Included here if not otherwise included in the boot header. */
    *(.Reset);
    *(.__pre_init);
    *(.xip .xip.*);
  } > REGION_LOAD_TEXT

  .text : ALIGN(4)
  {
    FILL(0xff);
    __stext = .;
    *(.text .text.*);
    /* The HardFaultTrampoline uses the `b` instruction to enter `HardFault`,
       so must be placed close to it. */
    *(.HardFaultTrampoline);
    *(.HardFault.*);
    . = ALIGN(4); /* Pad .text to the alignment to workaround overlapping load section bug in old lld */
    __etext = .;
  } > REGION_TEXT AT> REGION_LOAD_TEXT
  __sitext = LOADADDR(.text);

  .rodata : ALIGN(4)
  {
    FILL(0xff);
    . = ALIGN(4);
    __srodata = .;
    *(.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);
    __erodata = .;
  } > REGION_RODATA AT> REGION_LOAD_RODATA
  __sirodata = LOADADDR(.rodata);

  .data : ALIGN(4)
  {
    FILL(0xff);
    . = ALIGN(4);
    __sdata = .;
    *(.data .data.*);
    . = ALIGN(4); /* 4-byte align the end (VMA) of this section */
    __edata = .;
  } > REGION_DATA AT> REGION_LOAD_DATA
  __sidata = LOADADDR(.data);

  .bss (NOLOAD) : ALIGN(4)
  {
    . = ALIGN(4);
    __sbss = .;
    *(.bss .bss.*);
    *(COMMON); /* Uninitialized C statics */
    . = ALIGN(4); /* 4-byte align the end (VMA) of this section */
      __ebss = .;
  } > REGION_BSS

  .uninit (NOLOAD) : ALIGN(4)
  {
    . = ALIGN(4);
    __suninit = .;
    *(.uninit .uninit.*);
    . = ALIGN(4);
    __euninit = .;
  } > REGION_UNINIT

  .heap (NOLOAD) : ALIGN(4)
  {
    __sheap = .;
    . += ALIGN(__heap_size, 4);
    __eheap = .;
  } > REGION_HEAP

  /* 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 (NOLOAD) :
  {
    KEEP(*(.got .got.*));
  }

  /DISCARD/ :
  {
    /* Unused exception related info that only wastes space */
    *(.ARM.exidx);
    *(.ARM.exidx.*);
    *(.ARM.extab.*);
  }
}

/* Do not exceed this mark in the error messages below                                    | */
/* # Alignment checks */

ASSERT(__sstack % 8 == 0 && __estack % 8 == 0, "
BUG(imxrt-rt): .stack is not 8-byte aligned");

ASSERT(__sdata % 4 == 0 && __edata % 4 == 0, "
BUG(imxrt-rt): .data is not 4-byte aligned");

ASSERT(__sidata % 4 == 0, "
BUG(imxrt-rt): the LMA of .data is not 4-byte aligned");

ASSERT(__sbss % 4 == 0 && __ebss % 4 == 0, "
BUG(imxrt-rt): .bss is not 4-byte aligned");

ASSERT(__sheap % 4 == 0, "
BUG(imxrt-rt): start of .heap is not 4-byte aligned");

/* # Position checks */

/* ## .vector_table */
ASSERT(__reset_vector == ADDR(.vector_table) + 0x8, "
BUG(imxrt-rt): the reset vector is missing");

ASSERT(__eexceptions == ADDR(.vector_table) + 0x40, "
BUG(imxrt-rt): the exception vectors are missing");

ASSERT(SIZEOF(.vector_table) > 0x40, "
ERROR(imxrt-rt): The interrupt vectors are missing.
Possible solutions, from most likely to less likely:
- Link to imxrt-ral, or another compatible device crate
- Check that you actually use the device/hal/bsp crate in your code
- Disable the 'device' feature of cortex-m-rt to build a generic application (a dependency
may be enabling it)
- Supply the interrupt handlers yourself. Check the documentation for details.");

/* # Other checks */
ASSERT(SIZEOF(.got) == 0, "
ERROR(imxrt-rt): .got section detected in the input object files
Dynamic relocations are not supported. If you are linking to C code compiled using
the 'cc' crate then modify your build script to compile the C code _without_
the -fPIC flag. See the documentation of the `cc::Build.pic` method for details.");

ASSERT((__dcd_end - __dcd_start) % 4 == 0, "
ERROR(imxrt-rt): .dcd (Device Configuration Data) size must be a multiple of 4 bytes.");
/* Do not exceed this mark in the error messages above                                    | */

/* ===--- End imxrt-link.x ---=== */