1212
1313- `PROVIDE` is used to provide default values that can be overridden by a user linker script
1414
15- - In this linker script, you may find symbols that look like `${...}` (e.g., `${ARCH_WIDTH}`).
16- These are wildcards used by the `build.rs` script to adapt to different target particularities.
17- Check `build.rs` for more details about these symbols.
18-
1915- On alignment: it's important for correctness that the VMA boundaries of both .bss and .data *and*
20- the LMA of .data are all `${ARCH_WIDTH }`-byte aligned. These alignments are assumed by the RAM
21- initialization routine. There's also a second benefit: `${ARCH_WIDTH }`-byte aligned boundaries
16+ the LMA of .data are all `{{ cfg.arch_width } }`-byte aligned. These alignments are assumed by the RAM
17+ initialization routine. There's also a second benefit: `{{ cfg.arch_width } }`-byte aligned boundaries
2218 means that you won't see "Address (..) is out of bounds" in the disassembly produced by `objdump`.
2319*/
2420
@@ -67,7 +63,63 @@ PROVIDE(DefaultHandler = abort);
6763 to avoid compilation errors in direct mode, not to allow users to overwrite the symbol. */
6864PROVIDE(_start_DefaultHandler_trap = _start_trap);
6965
70- ${INCLUDE_LINKER_FILES}
66+ {% if not contains(cfg.feature, "no-exceptions") %}
67+ /* # EXCEPTION HANDLERS DESCRIBED IN THE STANDARD RISC-V ISA
68+
69+ It is possible to define a special handler for each exception type.
70+ By default, all exceptions are handled by ExceptionHandler. However,
71+ users can override these alias by defining the symbol themselves
72+ */
73+ PROVIDE(InstructionMisaligned = ExceptionHandler);
74+ PROVIDE(InstructionFault = ExceptionHandler);
75+ PROVIDE(IllegalInstruction = ExceptionHandler);
76+ PROVIDE(Breakpoint = ExceptionHandler);
77+ PROVIDE(LoadMisaligned = ExceptionHandler);
78+ PROVIDE(LoadFault = ExceptionHandler);
79+ PROVIDE(StoreMisaligned = ExceptionHandler);
80+ PROVIDE(StoreFault = ExceptionHandler);
81+ PROVIDE(UserEnvCall = ExceptionHandler);
82+ PROVIDE(SupervisorEnvCall = ExceptionHandler);
83+ PROVIDE(MachineEnvCall = ExceptionHandler);
84+ PROVIDE(InstructionPageFault = ExceptionHandler);
85+ PROVIDE(LoadPageFault = ExceptionHandler);
86+ PROVIDE(StorePageFault = ExceptionHandler);
87+ {% endif %}
88+
89+ {% if not contains(cfg.feature, "no-interrupts") %}
90+ /* # CORE INTERRUPT HANDLERS DESCRIBED IN THE STANDARD RISC-V ISA
91+
92+ It is possible to define a special handler for each interrupt type.
93+ By default, all interrupts are handled by DefaultHandler. However, users can
94+ override these alias by defining the symbol themselves
95+ */
96+ PROVIDE(SupervisorSoft = DefaultHandler);
97+ PROVIDE(MachineSoft = DefaultHandler);
98+ PROVIDE(SupervisorTimer = DefaultHandler);
99+ PROVIDE(MachineTimer = DefaultHandler);
100+ PROVIDE(SupervisorExternal = DefaultHandler);
101+ PROVIDE(MachineExternal = DefaultHandler);
102+
103+ /* When vectored trap mode is enabled, each interrupt source must implement its own
104+ trap entry point. By default, all interrupts start in _DefaultHandler_trap.
105+ However, users can override these alias by defining the symbol themselves */
106+ PROVIDE(_start_SupervisorSoft_trap = _start_DefaultHandler_trap);
107+ PROVIDE(_start_MachineSoft_trap = _start_DefaultHandler_trap);
108+ PROVIDE(_start_SupervisorTimer_trap = _start_DefaultHandler_trap);
109+ PROVIDE(_start_MachineTimer_trap = _start_DefaultHandler_trap);
110+ PROVIDE(_start_SupervisorExternal_trap = _start_DefaultHandler_trap);
111+ PROVIDE(_start_MachineExternal_trap = _start_DefaultHandler_trap);
112+ {% endif %}
113+
114+ {% if contains(cfg.feature, "device")%}
115+ /* Device-specific exception and interrupt handlers, usually provided by PACs */
116+ INCLUDE device.x
117+ {% endif %}
118+
119+ {% if contains(cfg.feature, "memory")%}
120+ /* Device-specific memory layout, usually provided by BSPs */
121+ INCLUDE memory.x
122+ {% endif %}
71123
72124PROVIDE(_stext = ORIGIN(REGION_TEXT));
73125PROVIDE(_stack_start = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK));
@@ -108,16 +160,16 @@ SECTIONS
108160 *(.srodata .srodata.*);
109161 *(.rodata .rodata.*);
110162
111- /* ${ARCH_WIDTH }-byte align the end (VMA) of this section.
163+ /* {{ cfg.arch_width } }-byte align the end (VMA) of this section.
112164 This is required by LLD to ensure the LMA of the following .data
113165 section will have the correct alignment. */
114- . = ALIGN(${ARCH_WIDTH });
166+ . = ALIGN({{ cfg.arch_width } });
115167 __erodata = .;
116168 } > REGION_RODATA
117169
118- .data : ALIGN(${ARCH_WIDTH })
170+ .data : ALIGN({{ cfg.arch_width } })
119171 {
120- . = ALIGN(${ARCH_WIDTH });
172+ . = ALIGN({{ cfg.arch_width } });
121173 __sdata = .;
122174
123175 /* Must be called __global_pointer$ for linker relaxations to work. */
@@ -130,15 +182,15 @@ SECTIONS
130182 /* Allow sections from user `memory.x` injected using `INSERT AFTER .data` to
131183 * use the .data loading mechanism by pushing __edata. Note: do not change
132184 * output region or load region in those user sections! */
133- . = ALIGN(${ARCH_WIDTH });
185+ . = ALIGN({{ cfg.arch_width } });
134186 __edata = .;
135187
136188 /* LMA of .data */
137189 __sidata = LOADADDR(.data);
138190
139- .bss (NOLOAD) : ALIGN(${ARCH_WIDTH })
191+ .bss (NOLOAD) : ALIGN({{ cfg.arch_width } })
140192 {
141- . = ALIGN(${ARCH_WIDTH });
193+ . = ALIGN({{ cfg.arch_width } });
142194 __sbss = .;
143195
144196 *(.sbss .sbss.* .bss .bss.*);
@@ -147,7 +199,7 @@ SECTIONS
147199 /* Allow sections from user `memory.x` injected using `INSERT AFTER .bss` to
148200 * use the .bss zeroing mechanism by pushing __ebss. Note: do not change
149201 * output region or load region in those user sections! */
150- . = ALIGN(${ARCH_WIDTH });
202+ . = ALIGN({{ cfg.arch_width } });
151203 __ebss = .;
152204
153205 /* fictitious region that represents the memory available for the heap */
@@ -184,8 +236,8 @@ ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");
184236ASSERT(ORIGIN(REGION_RODATA) % 4 == 0, "
185237ERROR(riscv-rt): the start of the REGION_RODATA must be 4-byte aligned");
186238
187- ASSERT(ORIGIN(REGION_DATA) % ${ARCH_WIDTH } == 0, "
188- ERROR(riscv-rt): the start of the REGION_DATA must be ${ARCH_WIDTH }-byte aligned");
239+ ASSERT(ORIGIN(REGION_DATA) % {{ cfg.arch_width } } == 0, "
240+ ERROR(riscv-rt): the start of the REGION_DATA must be {{ cfg.arch_width } }-byte aligned");
189241
190242ASSERT(ORIGIN(REGION_HEAP) % 4 == 0, "
191243ERROR(riscv-rt): the start of the REGION_HEAP must be 4-byte aligned");
@@ -196,14 +248,14 @@ ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned");
196248ASSERT(_stext % 4 == 0, "
197249ERROR(riscv-rt): `_stext` must be 4-byte aligned");
198250
199- ASSERT(__sdata % ${ARCH_WIDTH} == 0 && __edata % ${ARCH_WIDTH } == 0, "
200- BUG(riscv-rt): .data is not ${ARCH_WIDTH }-byte aligned");
251+ ASSERT(__sdata % {{ cfg.arch_width }} == 0 && __edata % {{ cfg.arch_width } } == 0, "
252+ BUG(riscv-rt): .data is not {{ cfg.arch_width } }-byte aligned");
201253
202- ASSERT(__sidata % ${ARCH_WIDTH } == 0, "
203- BUG(riscv-rt): the LMA of .data is not ${ARCH_WIDTH }-byte aligned");
254+ ASSERT(__sidata % {{ cfg.arch_width } } == 0, "
255+ BUG(riscv-rt): the LMA of .data is not {{ cfg.arch_width } }-byte aligned");
204256
205- ASSERT(__sbss % ${ARCH_WIDTH} == 0 && __ebss % ${ARCH_WIDTH } == 0, "
206- BUG(riscv-rt): .bss is not ${ARCH_WIDTH }-byte aligned");
257+ ASSERT(__sbss % {{ cfg.arch_width }} == 0 && __ebss % {{ cfg.arch_width } } == 0, "
258+ BUG(riscv-rt): .bss is not {{ cfg.arch_width } }-byte aligned");
207259
208260ASSERT(__sheap % 4 == 0, "
209261BUG(riscv-rt): start of .heap is not 4-byte aligned");
0 commit comments