rp23xx_btldr.ld 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /**
  2. * ZuluSCSI™ - Copyright (c) 2022-2025 Rabbit Hole Computing™
  3. *
  4. * ZuluSCSI™ firmware is licensed under the GPL version 3 or any later version. 
  5. *
  6. * https://www.gnu.org/licenses/gpl-3.0.html
  7. * ----
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version. 
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. * GNU General Public License for more details. 
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  20. **/
  21. /*
  22. *
  23. * Customized linker script for building bootloader
  24. *
  25. */
  26. MEMORY
  27. {
  28. FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 128k
  29. PSRAM(rwx) : ORIGIN = 0x11000000, LENGTH = 0
  30. RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 512k
  31. SCRATCH_X(rwx) : ORIGIN = 0x20080000, LENGTH = 4k
  32. SCRATCH_Y(rwx) : ORIGIN = 0x20081000, LENGTH = 4k
  33. }
  34. PROVIDE ( _EEPROM_start = __EEPROM_START__ );
  35. PROVIDE ( _FS_start = __FS_START__ );
  36. PROVIDE ( _FS_end = __FS_END__ );
  37. ENTRY(_entry_point)
  38. SECTIONS
  39. {
  40. .flash_begin : {
  41. __flash_binary_start = .;
  42. } > FLASH
  43. .text : {
  44. __logical_binary_start = .;
  45. KEEP (*(.btldr_vectors))
  46. KEEP (*(.binary_info_header))
  47. __binary_info_header_end = .;
  48. . = ALIGN(256);
  49. __real_vectors_start = .;
  50. KEEP (*(.vectors))
  51. KEEP (*(.embedded_block))
  52. __embedded_block_end = .;
  53. KEEP (*(.reset))
  54. /* TODO revisit this now memset/memcpy/float in ROM */
  55. /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from
  56. * FLASH ... we will include any thing excluded here in .data below by default */
  57. *(.init)
  58. *libgcc.a:cmse_nonsecure_call.o
  59. *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*)
  60. *(.fini)
  61. /* Pull all c'tors into .text */
  62. *crtbegin.o(.ctors)
  63. *crtbegin?.o(.ctors)
  64. *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
  65. *(SORT(.ctors.*))
  66. *(.ctors)
  67. /* Followed by destructors */
  68. *crtbegin.o(.dtors)
  69. *crtbegin?.o(.dtors)
  70. *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
  71. *(SORT(.dtors.*))
  72. *(.dtors)
  73. . = ALIGN(4);
  74. /* preinit data */
  75. PROVIDE_HIDDEN (__preinit_array_start = .);
  76. KEEP(*(SORT(.preinit_array.*)))
  77. KEEP(*(.preinit_array))
  78. PROVIDE_HIDDEN (__preinit_array_end = .);
  79. . = ALIGN(4);
  80. /* init data */
  81. PROVIDE_HIDDEN (__init_array_start = .);
  82. KEEP(*(SORT(.init_array.*)))
  83. KEEP(*(.init_array))
  84. PROVIDE_HIDDEN (__init_array_end = .);
  85. . = ALIGN(4);
  86. /* finit data */
  87. PROVIDE_HIDDEN (__fini_array_start = .);
  88. *(SORT(.fini_array.*))
  89. *(.fini_array)
  90. PROVIDE_HIDDEN (__fini_array_end = .);
  91. *(.eh_frame*)
  92. . = ALIGN(4);
  93. } > FLASH
  94. /* Note the boot2 section is optional, and should be discarded if there is
  95. no reference to it *inside* the binary, as it is not called by the
  96. bootrom. (The bootrom performs a simple best-effort XIP setup and
  97. leaves it to the binary to do anything more sophisticated.) However
  98. there is still a size limit of 256 bytes, to ensure the boot2 can be
  99. stored in boot RAM.
  100. Really this is a "XIP setup function" -- the name boot2 is historic and
  101. refers to its dual-purpose on RP2040, where it also handled vectoring
  102. from the bootrom into the user image.
  103. */
  104. .rodata : {
  105. *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*)
  106. *(.srodata*)
  107. . = ALIGN(4);
  108. *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
  109. . = ALIGN(4);
  110. } > FLASH
  111. .ARM.extab :
  112. {
  113. *(.ARM.extab* .gnu.linkonce.armextab.*)
  114. } > FLASH
  115. __exidx_start = .;
  116. .ARM.exidx :
  117. {
  118. *(.ARM.exidx* .gnu.linkonce.armexidx.*)
  119. } > FLASH
  120. __exidx_end = .;
  121. /* Machine inspectable binary information */
  122. . = ALIGN(4);
  123. __binary_info_start = .;
  124. .binary_info :
  125. {
  126. KEEP(*(.binary_info.keep.*))
  127. *(.binary_info.*)
  128. } > FLASH
  129. __binary_info_end = .;
  130. . = ALIGN(4);
  131. .ram_vector_table (NOLOAD): {
  132. *(.ram_vector_table)
  133. } > RAM
  134. .uninitialized_data (NOLOAD): {
  135. . = ALIGN(4);
  136. *(.uninitialized_data*)
  137. } > RAM
  138. .data : {
  139. __data_start__ = .;
  140. *(vtable)
  141. *(.time_critical*)
  142. /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */
  143. *(.text*)
  144. . = ALIGN(4);
  145. *(.rodata*)
  146. . = ALIGN(4);
  147. *(.data*)
  148. *(.sdata*)
  149. . = ALIGN(4);
  150. *(.after_data.*)
  151. . = ALIGN(4);
  152. /* preinit data */
  153. PROVIDE_HIDDEN (__mutex_array_start = .);
  154. KEEP(*(SORT(.mutex_array.*)))
  155. KEEP(*(.mutex_array))
  156. PROVIDE_HIDDEN (__mutex_array_end = .);
  157. *(.jcr)
  158. . = ALIGN(4);
  159. } > RAM AT> FLASH
  160. .tdata : {
  161. . = ALIGN(4);
  162. *(.tdata .tdata.* .gnu.linkonce.td.*)
  163. /* All data end */
  164. __tdata_end = .;
  165. } > RAM AT> FLASH
  166. PROVIDE(__data_end__ = .);
  167. /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */
  168. __etext = LOADADDR(.data);
  169. .tbss (NOLOAD) : {
  170. . = ALIGN(4);
  171. __bss_start__ = .;
  172. __tls_base = .;
  173. *(.tbss .tbss.* .gnu.linkonce.tb.*)
  174. *(.tcommon)
  175. __tls_end = .;
  176. } > RAM
  177. .bss (NOLOAD) : {
  178. . = ALIGN(4);
  179. __tbss_end = .;
  180. *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
  181. *(COMMON)
  182. PROVIDE(__global_pointer$ = . + 2K);
  183. *(.sbss*)
  184. . = ALIGN(4);
  185. __bss_end__ = .;
  186. } > RAM
  187. .heap (NOLOAD):
  188. {
  189. __end__ = .;
  190. end = __end__;
  191. KEEP(*(.heap*))
  192. /* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however
  193. to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */
  194. . = ORIGIN(RAM) + LENGTH(RAM);
  195. __HeapLimit = .;
  196. } > RAM
  197. /* Start and end symbols must be word-aligned */
  198. .scratch_x : {
  199. __scratch_x_start__ = .;
  200. *(.scratch_x.*)
  201. . = ALIGN(4);
  202. __scratch_x_end__ = .;
  203. } > SCRATCH_X AT > FLASH
  204. __scratch_x_source__ = LOADADDR(.scratch_x);
  205. .scratch_y : {
  206. __scratch_y_start__ = .;
  207. *(.scratch_y.*)
  208. . = ALIGN(4);
  209. __scratch_y_end__ = .;
  210. } > SCRATCH_Y AT > FLASH
  211. __scratch_y_source__ = LOADADDR(.scratch_y);
  212. /* .stack*_dummy section doesn't contains any symbols. It is only
  213. * used for linker to calculate size of stack sections, and assign
  214. * values to stack symbols later
  215. *
  216. * stack1 section may be empty/missing if platform_launch_core1 is not used */
  217. /* by default we put core 0 stack at the end of scratch Y, so that if core 1
  218. * stack is not used then all of SCRATCH_X is free.
  219. */
  220. .stack1_dummy (NOLOAD):
  221. {
  222. *(.stack1*)
  223. } > SCRATCH_X
  224. .stack_dummy (NOLOAD):
  225. {
  226. KEEP(*(.stack*))
  227. } > SCRATCH_Y
  228. .flash_end : {
  229. KEEP(*(.embedded_end_block*))
  230. PROVIDE(__flash_binary_end = .);
  231. } > FLASH =0xaa
  232. .psram (NOLOAD) : {
  233. __psram_start__ = .;
  234. *(.psram*)
  235. . = ALIGN(4096);
  236. __psram_heap_start__ = .;
  237. } > PSRAM
  238. /* stack limit is poorly named, but historically is maximum heap ptr */
  239. __StackLimit = ORIGIN(RAM) + LENGTH(RAM);
  240. __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
  241. __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
  242. __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
  243. __StackBottom = __StackTop - SIZEOF(.stack_dummy);
  244. PROVIDE(__stack = __StackTop);
  245. /* picolibc and LLVM */
  246. PROVIDE (__heap_start = __end__);
  247. PROVIDE (__heap_end = __HeapLimit);
  248. PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
  249. PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1));
  250. PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
  251. /* TLSF */
  252. PROVIDE (__psram_start = __psram_start__);
  253. PROVIDE (__psram_heap_start = __psram_heap_start__);
  254. /* llvm-libc */
  255. PROVIDE (_end = __end__);
  256. PROVIDE (__llvm_libc_heap_limit = __HeapLimit);
  257. /* Check if data + heap + stack exceeds RAM limit */
  258. ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
  259. ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary")
  260. ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary")
  261. /* todo assert on extra code */
  262. }