rp23xx_btldr.ld 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  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. /* Discard code that is not used in bootloader mode to
  44. * reduce the flash usage.
  45. */
  46. /DISCARD/ : {
  47. *scanf*(*)
  48. *strtod*(*)
  49. *libipv4.a:*(*)
  50. *liblwip*.a:*(*)
  51. *libBlueSCSI_audio_RP2MCU.a:*(*)
  52. *libAdafruit*.a:*(*)
  53. *libWire.a:*(*)
  54. *libSPI.a:*(*)
  55. *libBlueSCSI_UI_RP2MCU.a:*(*)
  56. *libBlueSCSI_platform_RP2MCU.a:BlueSCSI_platform_network.cpp.o*(*)
  57. *libFrameworkArduino.a:cyw43_wrappers.cpp.o*(*)
  58. /* gt */
  59. *BlueSCSI_tape.cpp.o*(*)
  60. *BlueSCSI_mode.cpp.o*(*)
  61. *BlueSCSI_blink.cpp.o*(*)
  62. *BlueSCSI_buffer_control.cpp.o*(*)
  63. *uiDiskUtils.cpp.o*(*)
  64. *SDNavigator.cpp.o*(*)
  65. }
  66. .text : {
  67. cyw43_digitalWrite = 0;
  68. cyw43_digitalRead = 0;
  69. cyw43_pinMode = 0;
  70. init_cyw43_wifi = bootloader_main;
  71. setPendingImageLoad = 0;
  72. platform_poll = 0;
  73. __logical_binary_start = .;
  74. KEEP (*(.btldr_vectors))
  75. KEEP (*(.binary_info_header))
  76. __binary_info_header_end = .;
  77. . = ALIGN(256);
  78. __real_vectors_start = .;
  79. KEEP (*(.vectors))
  80. KEEP (*(.embedded_block))
  81. __embedded_block_end = .;
  82. KEEP (*(.reset))
  83. /* TODO revisit this now memset/memcpy/float in ROM */
  84. /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from
  85. * FLASH ... we will include any thing excluded here in .data below by default */
  86. *(.init)
  87. *libgcc.a:cmse_nonsecure_call.o
  88. *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*)
  89. *(.fini)
  90. /* Pull all c'tors into .text */
  91. *crtbegin.o(.ctors)
  92. *crtbegin?.o(.ctors)
  93. *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
  94. *(SORT(.ctors.*))
  95. *(.ctors)
  96. /* Followed by destructors */
  97. *crtbegin.o(.dtors)
  98. *crtbegin?.o(.dtors)
  99. *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
  100. *(SORT(.dtors.*))
  101. *(.dtors)
  102. . = ALIGN(4);
  103. /* preinit data */
  104. PROVIDE_HIDDEN (__preinit_array_start = .);
  105. KEEP(*(SORT(.preinit_array.*)))
  106. KEEP(*(.preinit_array))
  107. PROVIDE_HIDDEN (__preinit_array_end = .);
  108. . = ALIGN(4);
  109. /* init data */
  110. PROVIDE_HIDDEN (__init_array_start = .);
  111. KEEP(*(SORT(.init_array.*)))
  112. KEEP(*(.init_array))
  113. PROVIDE_HIDDEN (__init_array_end = .);
  114. . = ALIGN(4);
  115. /* finit data */
  116. PROVIDE_HIDDEN (__fini_array_start = .);
  117. *(SORT(.fini_array.*))
  118. *(.fini_array)
  119. PROVIDE_HIDDEN (__fini_array_end = .);
  120. *(.eh_frame*)
  121. . = ALIGN(4);
  122. } > FLASH
  123. /* Note the boot2 section is optional, and should be discarded if there is
  124. no reference to it *inside* the binary, as it is not called by the
  125. bootrom. (The bootrom performs a simple best-effort XIP setup and
  126. leaves it to the binary to do anything more sophisticated.) However
  127. there is still a size limit of 256 bytes, to ensure the boot2 can be
  128. stored in boot RAM.
  129. Really this is a "XIP setup function" -- the name boot2 is historic and
  130. refers to its dual-purpose on RP2040, where it also handled vectoring
  131. from the bootrom into the user image.
  132. */
  133. .rodata : {
  134. *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*)
  135. *(.srodata*)
  136. . = ALIGN(4);
  137. *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
  138. . = ALIGN(4);
  139. } > FLASH
  140. .ARM.extab :
  141. {
  142. *(.ARM.extab* .gnu.linkonce.armextab.*)
  143. } > FLASH
  144. __exidx_start = .;
  145. .ARM.exidx :
  146. {
  147. *(.ARM.exidx* .gnu.linkonce.armexidx.*)
  148. } > FLASH
  149. __exidx_end = .;
  150. /* Machine inspectable binary information */
  151. . = ALIGN(4);
  152. __binary_info_start = .;
  153. .binary_info :
  154. {
  155. KEEP(*(.binary_info.keep.*))
  156. *(.binary_info.*)
  157. } > FLASH
  158. __binary_info_end = .;
  159. . = ALIGN(4);
  160. .ram_vector_table (NOLOAD): {
  161. *(.ram_vector_table)
  162. } > RAM
  163. .uninitialized_data (NOLOAD): {
  164. . = ALIGN(4);
  165. *(.uninitialized_data*)
  166. } > RAM
  167. .data : {
  168. __data_start__ = .;
  169. *(vtable)
  170. *(.time_critical*)
  171. /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */
  172. *(.text*)
  173. . = ALIGN(4);
  174. *(.rodata*)
  175. . = ALIGN(4);
  176. *(.data*)
  177. *(.sdata*)
  178. . = ALIGN(4);
  179. *(.after_data.*)
  180. . = ALIGN(4);
  181. /* preinit data */
  182. PROVIDE_HIDDEN (__mutex_array_start = .);
  183. KEEP(*(SORT(.mutex_array.*)))
  184. KEEP(*(.mutex_array))
  185. PROVIDE_HIDDEN (__mutex_array_end = .);
  186. *(.jcr)
  187. . = ALIGN(4);
  188. } > RAM AT> FLASH
  189. .tdata : {
  190. . = ALIGN(4);
  191. *(.tdata .tdata.* .gnu.linkonce.td.*)
  192. /* All data end */
  193. __tdata_end = .;
  194. } > RAM AT> FLASH
  195. PROVIDE(__data_end__ = .);
  196. /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */
  197. __etext = LOADADDR(.data);
  198. .tbss (NOLOAD) : {
  199. . = ALIGN(4);
  200. __bss_start__ = .;
  201. __tls_base = .;
  202. *(.tbss .tbss.* .gnu.linkonce.tb.*)
  203. *(.tcommon)
  204. __tls_end = .;
  205. } > RAM
  206. .bss (NOLOAD) : {
  207. . = ALIGN(4);
  208. __tbss_end = .;
  209. *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
  210. *(COMMON)
  211. PROVIDE(__global_pointer$ = . + 2K);
  212. *(.sbss*)
  213. . = ALIGN(4);
  214. __bss_end__ = .;
  215. } > RAM
  216. .heap (NOLOAD):
  217. {
  218. __end__ = .;
  219. end = __end__;
  220. KEEP(*(.heap*))
  221. /* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however
  222. to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */
  223. . = ORIGIN(RAM) + LENGTH(RAM);
  224. __HeapLimit = .;
  225. } > RAM
  226. /* Start and end symbols must be word-aligned */
  227. .scratch_x : {
  228. __scratch_x_start__ = .;
  229. *(.scratch_x.*)
  230. . = ALIGN(4);
  231. __scratch_x_end__ = .;
  232. } > SCRATCH_X AT > FLASH
  233. __scratch_x_source__ = LOADADDR(.scratch_x);
  234. .scratch_y : {
  235. __scratch_y_start__ = .;
  236. *(.scratch_y.*)
  237. . = ALIGN(4);
  238. __scratch_y_end__ = .;
  239. } > SCRATCH_Y AT > FLASH
  240. __scratch_y_source__ = LOADADDR(.scratch_y);
  241. /* .stack*_dummy section doesn't contains any symbols. It is only
  242. * used for linker to calculate size of stack sections, and assign
  243. * values to stack symbols later
  244. *
  245. * stack1 section may be empty/missing if platform_launch_core1 is not used */
  246. /* by default we put core 0 stack at the end of scratch Y, so that if core 1
  247. * stack is not used then all of SCRATCH_X is free.
  248. */
  249. .stack1_dummy (NOLOAD):
  250. {
  251. *(.stack1*)
  252. } > SCRATCH_X
  253. .stack_dummy (NOLOAD):
  254. {
  255. KEEP(*(.stack*))
  256. } > SCRATCH_Y
  257. .flash_end : {
  258. KEEP(*(.embedded_end_block*))
  259. PROVIDE(__flash_binary_end = .);
  260. } > FLASH =0xaa
  261. .psram (NOLOAD) : {
  262. __psram_start__ = .;
  263. *(.psram*)
  264. . = ALIGN(4096);
  265. __psram_heap_start__ = .;
  266. } > PSRAM
  267. /* stack limit is poorly named, but historically is maximum heap ptr */
  268. __StackLimit = ORIGIN(RAM) + LENGTH(RAM);
  269. __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
  270. __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
  271. __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
  272. __StackBottom = __StackTop - SIZEOF(.stack_dummy);
  273. PROVIDE(__stack = __StackTop);
  274. /* picolibc and LLVM */
  275. PROVIDE (__heap_start = __end__);
  276. PROVIDE (__heap_end = __HeapLimit);
  277. PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
  278. PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1));
  279. PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
  280. /* TLSF */
  281. PROVIDE (__psram_start = __psram_start__);
  282. PROVIDE (__psram_heap_start = __psram_heap_start__);
  283. /* llvm-libc */
  284. PROVIDE (_end = __end__);
  285. PROVIDE (__llvm_libc_heap_limit = __HeapLimit);
  286. /* Check if data + heap + stack exceeds RAM limit */
  287. ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
  288. ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary")
  289. ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary")
  290. /* todo assert on extra code */
  291. }