rp2040-template.ld 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  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. MEMORY
  22. {
  23. FLASH(rx) : ORIGIN = 0x10000000, LENGTH = $program_size
  24. RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k /* Leave space for pico-debug */
  25. SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
  26. SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
  27. }
  28. ENTRY(_entry_point)
  29. SECTIONS
  30. {
  31. .flash_begin : {
  32. __flash_binary_start = .;
  33. } > FLASH
  34. .boot2 : {
  35. __boot2_start__ = .;
  36. KEEP (*(.boot2))
  37. __boot2_end__ = .;
  38. } > FLASH
  39. ASSERT(__boot2_end__ - __boot2_start__ == 256,
  40. "ERROR: Pico second stage bootloader must be 256 bytes in size")
  41. /* If BlueSCSI SD card bootloader is included, it goes in first 128 kB */
  42. .text.bootloader : ALIGN(16) SUBALIGN(16)
  43. {
  44. KEEP(*(.text.btldr*))
  45. . = ALIGN(131072);
  46. CHECK_BOOTLOADER_SIZE = 1 / (. <= 131072);
  47. } > FLASH
  48. .text : {
  49. __logical_binary_start = .;
  50. __real_vectors_start = .;
  51. KEEP (*(.vectors))
  52. KEEP (*(.binary_info_header))
  53. __binary_info_header_end = .;
  54. KEEP (*(.reset))
  55. KEEP (*(.init))
  56. *(.fini)
  57. *crtbegin.o(.ctors)
  58. *crtbegin?.o(.ctors)
  59. *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
  60. *(SORT(.ctors.*))
  61. *(.ctors)
  62. *crtbegin.o(.dtors)
  63. *crtbegin?.o(.dtors)
  64. *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
  65. *(SORT(.dtors.*))
  66. *(.dtors)
  67. *(.eh_frame*)
  68. . = ALIGN(4);
  69. /* The rules below aim to put non-performance-critical code in flash.
  70. * The functions that are *not* listed below will go to .data in RAM.
  71. *
  72. * RP2040 has 16 kB of cache for the flash, so functions that are large
  73. * and rarely used can be put in flash, even if they are important for
  74. * performance when they are in use. By having most of the constantly
  75. * executing code in RAM already, there is less contention for cache space.
  76. */
  77. /*
  78. .pio/build/$project_name/src/BlueSCSI_initiator.cpp.o(.text .text*)
  79. .pio/build/$project_name/src/BlueSCSI_msc_initiator.cpp.o(.text .text*)
  80. .pio/build/$project_name/src/BlueSCSI_log.cpp.o(.text .text*)
  81. .pio/build/$project_name/src/BlueSCSI_log_trace.cpp.o(.text .text*)
  82. .pio/build/$project_name/src/BlueSCSI_settings.cpp.o(.text .text*)
  83. .pio/build/$project_name/src/QuirksCheck.cpp.o(.text .text*)
  84. */
  85. /* Standard library floating point etc. functions */
  86. *libm*:(.text .text*)
  87. *libc*:(.text .text*)
  88. *libgcc*:*df*(.text .text*)
  89. *USB*(.text .text*)
  90. *SPI*(.text .text*)
  91. *Spi*(.text .text*)
  92. *spi*(.text .text*)
  93. *stdc*:(.text .text*)
  94. *supc*:(.text .text*)
  95. *nosys*:(.text .text*)
  96. *libc*:*printf*(.text .text*)
  97. *libc*:*toa*(.text .text*)
  98. /* Libraries that are not performance-critical */
  99. *libminIni.a:(.text .text*)
  100. *libCUEParser.a:(.text .text*)
  101. /* C++ constructors and destructors */
  102. *(.text*_ZN*C1*)
  103. *(.text*_ZN*C2*)
  104. *(.text*_ZN*D1*)
  105. *(.text*_ZN*D2*)
  106. /* Initialization functions go to flash */
  107. *(.text*platform_init*)
  108. *(.text*platform_late_init*)
  109. *(.text*platform_enter_msc*)
  110. *(.text*zuluscsi_setup*)
  111. *(.text*audio_setup*)
  112. *(.text*init_logfile*)
  113. *(.text*find_chs_capacity*)
  114. *(.text*irq_remove_handler*)
  115. *(.text*irq_add_shared_handler*)
  116. *(.text*image_config_t*clear*)
  117. *(.text*reinitSCSI*)
  118. *(.text*print_sd_info*)
  119. *(.text*kiosk_restore_images*)
  120. *(.text*scsi_accel_rp2040_init*)
  121. *(.text*rp2040_sdio_init*)
  122. *(.text*PIOProgram*prepare*)
  123. *(.text*createImage*)
  124. *(.text*s2s_configInit*)
  125. *(.text*SdioCard*begin*)
  126. *(.text*mountSDCard*)
  127. *(.text*set_timings_from_file*)
  128. *(.text*scsiInit*)
  129. /* Logging code
  130. * Small parts of this will be executed in normal, non-debug mode,
  131. * but those can go to cache.
  132. */
  133. *ZuluSCSI_log.cpp.o(.text .text*)
  134. *ZuluSCSI_log_trace.cpp.o(.text .text*)
  135. /* ROM drive setup and FW upgrade that is done only during init */
  136. *(.text*romDriveClear*)
  137. *(.text*romDriveCheckPresent*)
  138. *(.text*zipparser*)
  139. *(.text*firmware_update*)
  140. /* BlueSCSI_disk functions that are only used during init */
  141. *BlueSCSI_settings.cpp.o(.text .text*)
  142. *QuirksCheck.cpp.o(.text .text*)
  143. *(.text*scsiDiskFilenameValid*)
  144. *(.text*scsiDiskOpenHDDImage*)
  145. *(.text*scsiDiskGetNextImageName*)
  146. *(.text*scsiDiskProgramRomDrive*)
  147. *(.text*scsiDiskLoadConfig*)
  148. *(.text*scsiDiskActivateRomDrive*)
  149. *(.text*scsiDiskSetImageConfig*)
  150. *(.text*ImageBackingStore*open*)
  151. *(.text*ImageBackingStore*ImageBackingStore*)
  152. *(.text*findHDDImages*)
  153. *(.text*scsiDiskCloseSDCardImages*)
  154. *(.text*extractFileName*)
  155. *(.text*setNameFromImage*)
  156. *(.text*getBlockSize*)
  157. /* SCSI commands that don't require high performance */
  158. *(.text*scsiToolboxCommand*)
  159. *(.text*scsi*Diagnostic*)
  160. *(.text*Inquiry*)
  161. *(.text*modeSelect*)
  162. *(.text*modeSense*)
  163. *(.text*doModeSelect*)
  164. *(.text*doModeSense*)
  165. *(.text*scsiModeCommand*)
  166. *(.text*doPerformEject*)
  167. /* CDROM/Tape/Vendor commands. Most of these are non-performance-critical, and
  168. * the important parts will fit in cache when in use. */
  169. *(.text*scsiTapeCommand*)
  170. *(.text*scsiCDRomCommand*)
  171. *(.text*scsiMOCommand*)
  172. *(.text*doReadCD*)
  173. *(.text*doReadTOC*)
  174. *(.text*doReadHeader*)
  175. *(.text*doPlayAudio*)
  176. *(.text*audio_play*)
  177. *(.text*doReadSubchannel*)
  178. *(.text*doGetConfiguration*)
  179. *(.text*cdromPerformEject*)
  180. *(.text*CueSheet*)
  181. *(.text*switchNextImage*)
  182. *(.text*findNextImageAfter*)
  183. *(.text*DiscInfo*)
  184. *(.text*TrackInfo*)
  185. *(.text*doCountFiles*)
  186. *(.text*doReadFullTOC*)
  187. *(.text*scsiVendorCommand*)
  188. *(.text*onListFiles*)
  189. /* SCSI Initiator mode code. These will fit in cache when in use. */
  190. *BlueSCSI_initiator.cpp.o(.text .text*)
  191. *BlueSCSI_msc_initiator.cpp.o(.text .text*)
  192. *scsi_accel_host*(.text .text*)
  193. *scsiHostPhy*(.text .text*)
  194. /* Filesystem functions that are not performance-critical.
  195. * Mostly used during initialization only. */
  196. *(.text*File*open*)
  197. *(.text*File*init*)
  198. *(.text*File*remove*)
  199. *(.text*File*truncate*)
  200. *(.text*File*sync*)
  201. *(.text*File*mkdir*)
  202. *(.text*File*bitmap*)
  203. *(.text*File*Name*)
  204. *(.text*File*SFN*)
  205. *(.text*File*LFN*)
  206. *(.text*File*addCluster*)
  207. *(.text*Volume*attrib*)
  208. *(.text*Volume*begin*)
  209. /* USB functions that only run in specific modes.
  210. These will fit in cache when they are in use (USB connected). */
  211. *libpico*:*(.text*msc*)
  212. *libpico*:*(.text*hidd*)
  213. *(.text*tud_msc*)
  214. /* RP2040 breakpoints in RAM code don't always work very well
  215. * because the boot routine tends to overwrite them.
  216. * Uncommenting this line puts all code in flash.
  217. * You may have to delete "firmware.elf" for the next build
  218. * to use this linker file's changes
  219. *
  220. * Alternatively, use "hbreak" in gdb to force hardware
  221. * breakpoints instead of RAM breakpoints.
  222. */
  223. /* *(.text .text*) */
  224. } > FLASH
  225. .rodata : {
  226. . = ALIGN(4);
  227. *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
  228. *(.rodata)
  229. *(.rodata*)
  230. . = ALIGN(4);
  231. } > FLASH
  232. .ARM.extab :
  233. {
  234. *(.ARM.extab* .gnu.linkonce.armextab.*)
  235. } > FLASH
  236. __exidx_start = .;
  237. .ARM.exidx :
  238. {
  239. *(.ARM.exidx* .gnu.linkonce.armexidx.*)
  240. } > FLASH
  241. __exidx_end = .;
  242. . = ALIGN(4);
  243. __binary_info_start = .;
  244. .binary_info :
  245. {
  246. KEEP(*(.binary_info.keep.*))
  247. *(.binary_info.*)
  248. } > FLASH
  249. __binary_info_end = .;
  250. . = ALIGN(4);
  251. __etext = .;
  252. .ram_vector_table (COPY): {
  253. *(.ram_vector_table)
  254. } > RAM
  255. .data : {
  256. __data_start__ = .;
  257. *(vtable)
  258. /* Time critical code will go here to avoid external flash latency */
  259. *(.time_critical*)
  260. . = ALIGN(4);
  261. *(.text)
  262. *(.text*)
  263. . = ALIGN(4);
  264. *(.data*)
  265. . = ALIGN(4);
  266. *(.after_data.*)
  267. . = ALIGN(4);
  268. PROVIDE_HIDDEN (__mutex_array_start = .);
  269. KEEP(*(SORT(.mutex_array.*)))
  270. KEEP(*(.mutex_array))
  271. PROVIDE_HIDDEN (__mutex_array_end = .);
  272. . = ALIGN(4);
  273. PROVIDE_HIDDEN (__preinit_array_start = .);
  274. KEEP(*(SORT(.preinit_array.*)))
  275. KEEP(*(.preinit_array))
  276. PROVIDE_HIDDEN (__preinit_array_end = .);
  277. . = ALIGN(4);
  278. PROVIDE_HIDDEN (__init_array_start = .);
  279. KEEP(*(SORT(.init_array.*)))
  280. KEEP(*(.init_array))
  281. PROVIDE_HIDDEN (__init_array_end = .);
  282. . = ALIGN(4);
  283. PROVIDE_HIDDEN (__fini_array_start = .);
  284. *(SORT(.fini_array.*))
  285. *(.fini_array)
  286. PROVIDE_HIDDEN (__fini_array_end = .);
  287. *(.jcr)
  288. . = ALIGN(4);
  289. __data_end__ = .;
  290. } > RAM AT> FLASH
  291. .uninitialized_data (COPY): {
  292. . = ALIGN(4);
  293. *(.uninitialized_data*)
  294. } > RAM
  295. .scratch_x : {
  296. __scratch_x_start__ = .;
  297. *(.scratch_x.*)
  298. . = ALIGN(4);
  299. __scratch_x_end__ = .;
  300. } > SCRATCH_X AT > FLASH
  301. __scratch_x_source__ = LOADADDR(.scratch_x);
  302. .scratch_y : {
  303. __scratch_y_start__ = .;
  304. *(.scratch_y.*)
  305. . = ALIGN(4);
  306. __scratch_y_end__ = .;
  307. } > SCRATCH_Y AT > FLASH
  308. __scratch_y_source__ = LOADADDR(.scratch_y);
  309. .bss : {
  310. . = ALIGN(4);
  311. __bss_start__ = .;
  312. *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
  313. *(COMMON)
  314. . = ALIGN(4);
  315. __bss_end__ = .;
  316. } > RAM
  317. .heap (COPY):
  318. {
  319. __end__ = .;
  320. PROVIDE(end = .);
  321. *(.heap*)
  322. . = ORIGIN(RAM) + LENGTH(RAM) - 0x400;
  323. __HeapLimit = .;
  324. } > RAM
  325. .stack1_dummy (COPY):
  326. {
  327. *(.stack1*)
  328. } > SCRATCH_X
  329. .stack_dummy (COPY):
  330. {
  331. *(.stack*)
  332. } > RAM
  333. .flash_end : {
  334. __flash_binary_end = .;
  335. } > FLASH
  336. __StackTop = ORIGIN(RAM) + LENGTH(RAM);
  337. __StackLimit = __StackTop - 0x400;
  338. __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
  339. __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
  340. __StackBottom = __StackTop - SIZEOF(.stack_dummy);
  341. PROVIDE(__stack = __StackTop);
  342. ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
  343. ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary")
  344. }