|
| 1 | +PROVIDE(_stext = ORIGIN(REGION_TEXT)); |
| 2 | +PROVIDE(_stack_start = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK)); |
| 3 | +PROVIDE(_max_hart_id = 0); |
| 4 | +PROVIDE(_hart_stack_size = 2K); |
| 5 | +PROVIDE(_heap_size = 0); |
| 6 | + |
| 7 | +PROVIDE(UserSoft = DefaultHandler); |
| 8 | +PROVIDE(SupervisorSoft = DefaultHandler); |
| 9 | +PROVIDE(MachineSoft = DefaultHandler); |
| 10 | +PROVIDE(UserTimer = DefaultHandler); |
| 11 | +PROVIDE(SupervisorTimer = DefaultHandler); |
| 12 | +PROVIDE(MachineTimer = DefaultHandler); |
| 13 | +PROVIDE(UserExternal = DefaultHandler); |
| 14 | +PROVIDE(SupervisorExternal = DefaultHandler); |
| 15 | +PROVIDE(MachineExternal = DefaultHandler); |
| 16 | + |
| 17 | +PROVIDE(DefaultHandler = DefaultInterruptHandler); |
| 18 | +PROVIDE(ExceptionHandler = DefaultExceptionHandler); |
| 19 | + |
| 20 | +/* # Pre-initialization function */ |
| 21 | +/* If the user overrides this using the `#[pre_init]` attribute or by creating a `__pre_init` function, |
| 22 | + then the function this points to will be called before the RAM is initialized. */ |
| 23 | +PROVIDE(__pre_init = default_pre_init); |
| 24 | + |
| 25 | +/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */ |
| 26 | +PROVIDE(_setup_interrupts = default_setup_interrupts); |
| 27 | + |
| 28 | +/* # Multi-processing hook function |
| 29 | + fn _mp_hook() -> bool; |
| 30 | + |
| 31 | + This function is called from all the harts and must return true only for one hart, |
| 32 | + which will perform memory initialization. For other harts it must return false |
| 33 | + and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt). |
| 34 | +*/ |
| 35 | +PROVIDE(_mp_hook = default_mp_hook); |
| 36 | + |
| 37 | +/* # Start trap function override |
| 38 | + By default uses the riscv crates default trap handler |
| 39 | + but by providing the `_start_trap` symbol external crates can override. |
| 40 | +*/ |
| 41 | +PROVIDE(_start_trap = default_start_trap); |
| 42 | + |
| 43 | +SECTIONS |
| 44 | +{ |
| 45 | + .text.dummy (NOLOAD) : |
| 46 | + { |
| 47 | + /* This section is intended to make _stext address work */ |
| 48 | + . = ABSOLUTE(_stext); |
| 49 | + } > REGION_TEXT |
| 50 | + |
| 51 | + .text _stext : |
| 52 | + { |
| 53 | + /* Put reset handler first in .text section so it ends up as the entry */ |
| 54 | + /* point of the program. */ |
| 55 | + KEEP(*(.init)); |
| 56 | + KEEP(*(.init.rust)); |
| 57 | + . = ALIGN(4); |
| 58 | + *(.trap); |
| 59 | + *(.trap.rust); |
| 60 | + *(.text.abort); |
| 61 | + *(.text .text.*); |
| 62 | + } > REGION_TEXT |
| 63 | + |
| 64 | + .rodata : ALIGN(4) |
| 65 | + { |
| 66 | + *(.srodata .srodata.*); |
| 67 | + *(.rodata .rodata.*); |
| 68 | + |
| 69 | + /* 4-byte align the end (VMA) of this section. |
| 70 | + This is required by LLD to ensure the LMA of the following .data |
| 71 | + section will have the correct alignment. */ |
| 72 | + . = ALIGN(4); |
| 73 | + } > REGION_RODATA |
| 74 | + |
| 75 | + .data : ALIGN(8) |
| 76 | + { |
| 77 | + _sidata = LOADADDR(.data); |
| 78 | + _sdata = .; |
| 79 | + /* Must be called __global_pointer$ for linker relaxations to work. */ |
| 80 | + PROVIDE(__global_pointer$ = . + 0x800); |
| 81 | + *(.sdata .sdata.* .sdata2 .sdata2.*); |
| 82 | + *(.data .data.*); |
| 83 | + . = ALIGN(8); |
| 84 | + _edata = .; |
| 85 | + } > REGION_DATA AT > REGION_RODATA |
| 86 | + |
| 87 | + .bss (NOLOAD) : ALIGN(8) |
| 88 | + { |
| 89 | + _sbss = .; |
| 90 | + *(.sbss .sbss.* .bss .bss.*); |
| 91 | + . = ALIGN(8); |
| 92 | + _ebss = .; |
| 93 | + } > REGION_BSS |
| 94 | + |
| 95 | + /* fictitious region that represents the memory available for the heap */ |
| 96 | + .heap (NOLOAD) : |
| 97 | + { |
| 98 | + _sheap = .; |
| 99 | + . += _heap_size; |
| 100 | + . = ALIGN(4); |
| 101 | + _eheap = .; |
| 102 | + } > REGION_HEAP |
| 103 | + |
| 104 | + /* fictitious region that represents the memory available for the stack */ |
| 105 | + .stack (NOLOAD) : |
| 106 | + { |
| 107 | + _estack = .; |
| 108 | + . = ABSOLUTE(_stack_start); |
| 109 | + _sstack = .; |
| 110 | + } > REGION_STACK |
| 111 | + |
| 112 | + /* fake output .got section */ |
| 113 | + /* Dynamic relocations are unsupported. This section is only used to detect |
| 114 | + relocatable code in the input files and raise an error if relocatable code |
| 115 | + is found */ |
| 116 | + .got (INFO) : |
| 117 | + { |
| 118 | + KEEP(*(.got .got.*)); |
| 119 | + } |
| 120 | + |
| 121 | + .eh_frame (INFO) : { KEEP(*(.eh_frame)) } |
| 122 | + .eh_frame_hdr (INFO) : { *(.eh_frame_hdr) } |
| 123 | +} |
| 124 | + |
| 125 | +/* Do not exceed this mark in the error messages above | */ |
| 126 | +ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, " |
| 127 | +ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned"); |
| 128 | + |
| 129 | +ASSERT(ORIGIN(REGION_RODATA) % 4 == 0, " |
| 130 | +ERROR(riscv-rt): the start of the REGION_RODATA must be 4-byte aligned"); |
| 131 | + |
| 132 | +ASSERT(ORIGIN(REGION_DATA) % 8 == 0, " |
| 133 | +ERROR(riscv-rt): the start of the REGION_DATA must be 8-byte aligned"); |
| 134 | + |
| 135 | +ASSERT(ORIGIN(REGION_HEAP) % 4 == 0, " |
| 136 | +ERROR(riscv-rt): the start of the REGION_HEAP must be 4-byte aligned"); |
| 137 | + |
| 138 | +ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, " |
| 139 | +ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned"); |
| 140 | + |
| 141 | +ASSERT(ORIGIN(REGION_STACK) % 4 == 0, " |
| 142 | +ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned"); |
| 143 | + |
| 144 | +ASSERT(_stext % 4 == 0, " |
| 145 | +ERROR(riscv-rt): `_stext` must be 4-byte aligned"); |
| 146 | + |
| 147 | +ASSERT(_sdata % 8 == 0 && _edata % 8 == 0, " |
| 148 | +BUG(riscv-rt): .data is not 8-byte aligned"); |
| 149 | + |
| 150 | +ASSERT(_sidata % 8 == 0, " |
| 151 | +BUG(riscv-rt): the LMA of .data is not 8-byte aligned"); |
| 152 | + |
| 153 | +ASSERT(_sbss % 8 == 0 && _ebss % 8 == 0, " |
| 154 | +BUG(riscv-rt): .bss is not 8-byte aligned"); |
| 155 | + |
| 156 | +ASSERT(_sheap % 4 == 0, " |
| 157 | +BUG(riscv-rt): start of .heap is not 4-byte aligned"); |
| 158 | + |
| 159 | +ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), " |
| 160 | +ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region. |
| 161 | +Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'"); |
| 162 | + |
| 163 | +ASSERT(SIZEOF(.stack) > (_max_hart_id + 1) * _hart_stack_size, " |
| 164 | +ERROR(riscv-rt): .stack section is too small for allocating stacks for all the harts. |
| 165 | +Consider changing `_max_hart_id` or `_hart_stack_size`."); |
| 166 | + |
| 167 | +ASSERT(SIZEOF(.got) == 0, " |
| 168 | +.got section detected in the input files. Dynamic relocations are not |
| 169 | +supported. If you are linking to C code compiled using the `gcc` crate |
| 170 | +then modify your build script to compile the C code _without_ the |
| 171 | +-fPIC flag. See the documentation of the `gcc::Config.fpic` method for |
| 172 | +details."); |
| 173 | + |
| 174 | +/* Do not exceed this mark in the error messages above | */ |
0 commit comments