linker.ld 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. /*
  2. * Copyright (c) 2013-2014 Wind River Systems, Inc.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief Linker command/script file
  9. *
  10. * Linker script for the Cortex-M platforms.
  11. */
  12. #include <autoconf.h>
  13. #include <linker/sections.h>
  14. #include <devicetree.h>
  15. #include <linker/linker-defs.h>
  16. #include <linker/linker-tool.h>
  17. #ifdef CONFIG_SECTION_OVERLAY
  18. #include <section_overlay.h>
  19. #endif
  20. /* physical address of RAM */
  21. #define ROMABLE_REGION FLASH
  22. #define RAMABLE_REGION PSRAM
  23. #define ROM_ADDR (CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET)
  24. #define ROM_SIZE (CONFIG_FLASH_SIZE*1K - CONFIG_FLASH_LOAD_OFFSET)
  25. #ifndef CONFIG_SENSOR_RAM_SIZE
  26. #define CONFIG_SENSOR_RAM_SIZE 0
  27. #endif
  28. #ifndef CONFIG_SENSOR_RAM_CODE_SIZE
  29. #define CONFIG_SENSOR_RAM_CODE_SIZE 0
  30. #endif
  31. #define RAM_SIZE (CONFIG_SRAM_SIZE * 1K - CONFIG_SENSOR_RAM_CODE_SIZE * 1K - CONFIG_SENSOR_RAM_SIZE * 1K)
  32. #define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
  33. /* Set alignment to CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
  34. * to make linker section alignment comply with MPU granularity.
  35. */
  36. #if defined(CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE)
  37. _region_min_align = CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE;
  38. #else
  39. /* If building without MPU support, use default 4-byte alignment. */
  40. _region_min_align = 4;
  41. #endif
  42. #define MPU_ALIGN(region_size) . = ALIGN(_region_min_align)
  43. MEMORY
  44. {
  45. FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE
  46. SRAM (wx) : ORIGIN = CONFIG_SRAM_BASE_ADDRESS, LENGTH = RAM_SIZE
  47. PSRAM (wx) : ORIGIN = CONFIG_PSRAM_BASE_ADDRESS, LENGTH = CONFIG_PSRAM_SIZE * 1K
  48. SHARE_RAM (wx) : ORIGIN = 0x2FF1A600, LENGTH = 0x5900
  49. DSP_SRAM (wx) : ORIGIN = 0x30044000, LENGTH = 0x14000
  50. /* Used by and documented in include/linker/intlist.ld */
  51. IDT_LIST (wx) : ORIGIN = (RAM_ADDR + RAM_SIZE), LENGTH = 2K
  52. }
  53. ENTRY(CONFIG_KERNEL_ENTRY)
  54. SECTIONS
  55. {
  56. #include <linker/rel-sections.ld>
  57. /*
  58. * .plt and .iplt are here according to 'arm-zephyr-elf-ld --verbose',
  59. * before text section.
  60. */
  61. /DISCARD/ :
  62. {
  63. *(.plt)
  64. }
  65. /DISCARD/ :
  66. {
  67. *(.iplt)
  68. }
  69. GROUP_START(ROMABLE_REGION)
  70. __rom_region_start = ROM_ADDR;
  71. SECTION_PROLOGUE(rom_start,,)
  72. {
  73. /* Located in generated directory. This file is populated by calling
  74. * zephyr_linker_sources(ROM_START ...). This typically contains the vector
  75. * table and debug information.
  76. */
  77. #include <snippets-rom-start.ld>
  78. } GROUP_LINK_IN(ROMABLE_REGION)
  79. SECTION_PROLOGUE(img_head,(ROM_ADDR+0x200),) AT (ROM_ADDR+0x200)
  80. {
  81. KEEP(*(.img_head*))
  82. } GROUP_LINK_IN(ROMABLE_REGION)
  83. #ifdef CONFIG_HR_ROM_BASE
  84. SECTION_PROLOGUE(hr_rom,CONFIG_HR_ROM_BASE,) AT (CONFIG_HR_ROM_BASE)
  85. {
  86. . = ALIGN(4);
  87. KEEP(*(.hr_rom))
  88. } GROUP_LINK_IN(ROMABLE_REGION)
  89. #endif
  90. #ifdef CONFIG_SENSOR_ROM_BASE
  91. SECTION_PROLOGUE(sensor_rom,CONFIG_SENSOR_ROM_BASE,) AT (CONFIG_SENSOR_ROM_BASE)
  92. {
  93. . = ALIGN(4);
  94. KEEP(*(.sensor_rom))
  95. } GROUP_LINK_IN(ROMABLE_REGION)
  96. #endif
  97. #ifdef CONFIG_SENSOR_SLEEP_ROM_BASE
  98. SECTION_PROLOGUE(sensor_sleep_rom,,) AT (CONFIG_SENSOR_SLEEP_ROM_BASE)
  99. {
  100. . = ALIGN(4);
  101. KEEP(*(.sensor_sleep_rom))
  102. } GROUP_LINK_IN(ROMABLE_REGION)
  103. #endif
  104. SECTION_PROLOGUE(_ACTIONS_RODATA_SECTION_NAME,,)
  105. {
  106. . = ALIGN(4);
  107. __app_entry_table = .;
  108. KEEP(*(.app_entry))
  109. __app_entry_end = .;
  110. . = ALIGN(4);
  111. __service_entry_table = .;
  112. KEEP(*(.service_entry))
  113. __service_entry_end = .;
  114. . = ALIGN(4);
  115. __view_entry_table = .;
  116. KEEP(*(.view_entry))
  117. __view_entry_end = .;
  118. } GROUP_LINK_IN(ROMABLE_REGION)
  119. SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
  120. {
  121. __text_region_start = .;
  122. #include <linker/kobject-text.ld>
  123. *(.text)
  124. *(".text.*")
  125. *(.gnu.linkonce.t.*)
  126. /*
  127. * These are here according to 'arm-zephyr-elf-ld --verbose',
  128. * after .gnu.linkonce.t.*
  129. */
  130. *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
  131. } GROUP_LINK_IN(ROMABLE_REGION)
  132. __text_region_end = .;
  133. /*#if defined (CONFIG_CPLUSPLUS)*/
  134. SECTION_PROLOGUE(.ARM.extab,,)
  135. {
  136. /*
  137. * .ARM.extab section containing exception unwinding information.
  138. */
  139. *(.ARM.extab* .gnu.linkonce.armextab.*)
  140. } GROUP_LINK_IN(ROMABLE_REGION)
  141. /*#endif*/
  142. SECTION_PROLOGUE(.ARM.exidx,,)
  143. {
  144. /*
  145. * This section, related to stack and exception unwinding, is placed
  146. * explicitly to prevent it from being shared between multiple regions.
  147. * It must be defined for gcc to support 64-bit math and avoid
  148. * section overlap.
  149. */
  150. __start_unwind_idx = .;
  151. __exidx_start = .;
  152. #if defined (__GCC_LINKER_CMD__)
  153. *(.ARM.exidx* gnu.linkonce.armexidx.*)
  154. #endif
  155. __exidx_end = .;
  156. __stop_unwind_idx = .;
  157. } GROUP_LINK_IN(ROMABLE_REGION)
  158. __rodata_region_start = .;
  159. #include <linker/common-rom.ld>
  160. #include <linker/thread-local-storage.ld>
  161. SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
  162. {
  163. *(.rodata)
  164. *(".rodata.*")
  165. *(.gnu.linkonce.r.*)
  166. /* Located in generated directory. This file is populated by the
  167. * zephyr_linker_sources() Cmake function.
  168. */
  169. #include <snippets-rodata.ld>
  170. #ifdef CONFIG_SECTION_OVERLAY
  171. . = ALIGN(4);
  172. __overlay_table = .;
  173. LONG(OVERLAY_TABLE_MAGIC)
  174. /* overlay items count */
  175. LONG(7)
  176. /* for a1_wav_p.a */
  177. LONG(OVERLAY_ID_LIBAPWAV)
  178. LONG(0);
  179. LONG(0);
  180. LONG(0);
  181. LONG(ABSOLUTE(ADDR(.overlay.data.apwav)));
  182. LONG(SIZEOF(.overlay.data.apwav));
  183. LONG(LOADADDR(.overlay.data.apwav));
  184. LONG(ABSOLUTE(ADDR(.overlay.bss.apwav)));
  185. LONG(SIZEOF(.overlay.bss.apwav));
  186. /* for a1_mp3_p.a */
  187. LONG(OVERLAY_ID_LIBAPMP3)
  188. LONG(0);
  189. LONG(0);
  190. LONG(0);
  191. LONG(ABSOLUTE(ADDR(.overlay.data.apmp3)));
  192. LONG(SIZEOF(.overlay.data.apmp3));
  193. LONG(LOADADDR(.overlay.data.apmp3));
  194. LONG(ABSOLUTE(ADDR(.overlay.bss.apmp3)));
  195. LONG(SIZEOF(.overlay.bss.apmp3));
  196. /* for a1_ape_p.a */
  197. LONG(OVERLAY_ID_LIBAPAPE)
  198. LONG(0);
  199. LONG(0);
  200. LONG(0);
  201. LONG(ABSOLUTE(ADDR(.overlay.data.apape)));
  202. LONG(SIZEOF(.overlay.data.apape));
  203. LONG(LOADADDR(.overlay.data.apape));
  204. LONG(ABSOLUTE(ADDR(.overlay.bss.apape)));
  205. LONG(SIZEOF(.overlay.bss.apape));
  206. /* for a1_w13_p.a */
  207. LONG(OVERLAY_ID_LIBAPWMA)
  208. LONG(0);
  209. LONG(0);
  210. LONG(0);
  211. LONG(ABSOLUTE(ADDR(.overlay.data.apwma)));
  212. LONG(SIZEOF(.overlay.data.apwma));
  213. LONG(LOADADDR(.overlay.data.apwma));
  214. LONG(ABSOLUTE(ADDR(.overlay.bss.apwma)));
  215. LONG(SIZEOF(.overlay.bss.apwma));
  216. /* for a1_fla_p.a */
  217. LONG(OVERLAY_ID_LIBADFLA)
  218. LONG(0);
  219. LONG(0);
  220. LONG(0);
  221. LONG(ABSOLUTE(ADDR(.overlay.data.apfla)));
  222. LONG(SIZEOF(.overlay.data.apfla));
  223. LONG(LOADADDR(.overlay.data.apfla));
  224. LONG(ABSOLUTE(ADDR(.overlay.bss.apfla)));
  225. LONG(SIZEOF(.overlay.bss.apfla));
  226. /* for a1_a23_p.a */
  227. LONG(OVERLAY_ID_LIBAPAAC)
  228. LONG(0);
  229. LONG(0);
  230. LONG(0);
  231. LONG(ABSOLUTE(ADDR(.overlay.data.apaac)));
  232. LONG(SIZEOF(.overlay.data.apaac));
  233. LONG(LOADADDR(.overlay.data.apaac));
  234. LONG(ABSOLUTE(ADDR(.overlay.bss.apaac)));
  235. LONG(SIZEOF(.overlay.bss.apaac));
  236. . = ALIGN(4);
  237. #endif
  238. #include <linker/kobject-rom.ld>
  239. /*
  240. * For XIP images, in order to avoid the situation when __data_rom_start
  241. * is 32-bit aligned, but the actual data is placed right after rodata
  242. * section, which may not end exactly at 32-bit border, pad rodata
  243. * section, so __data_rom_start points at data and it is 32-bit aligned.
  244. *
  245. * On non-XIP images this may enlarge image size up to 3 bytes. This
  246. * generally is not an issue, since modern ROM and FLASH memory is
  247. * usually 4k aligned.
  248. */
  249. . = ALIGN(4);
  250. } GROUP_LINK_IN(ROMABLE_REGION)
  251. #include <linker/cplusplus-rom.ld>
  252. __rodata_region_end = .;
  253. MPU_ALIGN(__rodata_region_end -__rom_region_start);
  254. __rom_region_end = .;
  255. __rom_region_size = __rom_region_end - __rom_region_start;
  256. GROUP_END(ROMABLE_REGION)
  257. /*
  258. * These are here according to 'arm-zephyr-elf-ld --verbose',
  259. * before data section.
  260. */
  261. /DISCARD/ : {
  262. *(.got.plt)
  263. *(.igot.plt)
  264. *(.got)
  265. *(.igot)
  266. }
  267. . = RAM_ADDR;
  268. /* Align the start of image SRAM with the
  269. * minimum granularity required by MPU.
  270. */
  271. . = ALIGN(_region_min_align);
  272. _image_ram_start = .;
  273. /* ================================= sram data =================================*/
  274. _sram_data_start = .;
  275. SECTION_DATA_PROLOGUE(_SRAM_CODE_SECTION_NAME,,)
  276. {
  277. . = ALIGN(4);
  278. _sram_func_start = .;
  279. *(.sleepfunc)
  280. *(".sleepfunc.*")
  281. *(.defunc)
  282. *(.lvglfunc)
  283. _sram_func_end = .;
  284. }GROUP_DATA_LINK_IN(SRAM, ROMABLE_REGION)
  285. _sram_func_ram_size = _sram_func_end - _sram_func_start;
  286. _sram_func_rom_start = LOADADDR(_SRAM_CODE_SECTION_NAME);
  287. SECTION_DATA_PROLOGUE(_SRAM_DATA_SECTION_NAME,,)
  288. {
  289. . = ALIGN(4);
  290. *(.sleep.data*)
  291. }GROUP_DATA_LINK_IN(SRAM, ROMABLE_REGION)
  292. _sram_data_end = .;
  293. _sram_data_ram_size = _sram_data_end - _sram_data_start;
  294. _sram_data_rom_start = LOADADDR(_SRAM_CODE_SECTION_NAME);
  295. /* ================================= psram data =================================*/
  296. OVERLAY : NOCROSSREFS
  297. {
  298. .overlay.data.apfla {
  299. *a1_fla_p.a:*(.data .data.*)
  300. }
  301. .overlay.data.apwma {
  302. *a1_w13_p.a:*(.data .data.*)
  303. }
  304. .overlay.data.apape {
  305. *a1_ape_p.a:*(.data .data.*)
  306. }
  307. .overlay.data.apmp3 {
  308. *a1_mp3_p.a:*(.data .data.*)
  309. }
  310. .overlay.data.apwav {
  311. *a1_wav_p.a:*(.data .data.*)
  312. }
  313. .overlay.data.apaac {
  314. *a1_a13_p.a:*(.data .data.*)
  315. }
  316. } GROUP_DATA_LINK_IN(PSRAM, ROMABLE_REGION)
  317. /* Located in generated directory. This file is populated by the
  318. * zephyr_linker_sources() Cmake function.
  319. */
  320. #include <snippets-ram-sections.ld>
  321. SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
  322. {
  323. __data_region_start = .;
  324. __data_start = .;
  325. *(.data)
  326. *(".data.*")
  327. *(".kernel.*")
  328. /* Located in generated directory. This file is populated by the
  329. * zephyr_linker_sources() Cmake function.
  330. */
  331. #include <snippets-rwdata.ld>
  332. __data_end = .;
  333. } GROUP_DATA_LINK_IN(PSRAM, ROMABLE_REGION)
  334. __data_size = __data_end - __data_start;
  335. __data_load_start = LOADADDR(_DATA_SECTION_NAME);
  336. __data_region_load_start = LOADADDR(_DATA_SECTION_NAME);
  337. #include <linker/common-ram.ld>
  338. #include <linker/kobject-data.ld>
  339. #include <linker/cplusplus-ram.ld>
  340. __data_region_end = .;
  341. /* ================================= sram bss =================================*/
  342. __sram_bss_start = .;
  343. SECTION_PROLOGUE(_SRAM_BSS_SECTION_NAME,(NOLOAD),)
  344. {
  345. } GROUP_LINK_IN(SRAM)
  346. __sram_bss_end = .;
  347. /* ================================= psram bss ================================= */
  348. OVERLAY : NOCROSSREFS
  349. {
  350. .overlay.bss.apfla {
  351. *a1_fla_p.a:*(.bss .bss.* .scommon COMMON)
  352. }
  353. .overlay.bss.apwma {
  354. *a1_w13_p.a:*(.bss .bss.* .scommon COMMON)
  355. }
  356. .overlay.bss.apape {
  357. *a1_ape_p.a:*(.bss .bss.* .scommon COMMON)
  358. }
  359. .overlay.bss.apmp3 {
  360. *a1_mp3_p.a:*(.bss .bss.* .scommon COMMON)
  361. }
  362. .overlay.bss.apwav {
  363. *a1_wav_p.a:*(.bss .bss.* .scommon COMMON)
  364. }
  365. .overlay.bss.apaac {
  366. *a1_a13_p.a:*(.bss .bss.* .scommon COMMON)
  367. }
  368. } GROUP_LINK_IN(PSRAM)
  369. __psram_bss_start = .;
  370. __bss_start = .;
  371. SECTION_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
  372. {
  373. /*
  374. * For performance, BSS section is assumed to be 4 byte aligned and
  375. * a multiple of 4 bytes
  376. */
  377. . = ALIGN(4);
  378. *(.bss)
  379. *(.bss.*)
  380. *(.scommon)
  381. *(COMMON)
  382. /*
  383. * As memory is cleared in words only, it is simpler to ensure the BSS
  384. * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
  385. */
  386. } GROUP_LINK_IN(PSRAM)
  387. SECTION_PROLOGUE(_PSRAM_BSS_SECTION_NAME,(NOLOAD),)
  388. {
  389. /*
  390. * For performance, BSS section is assumed to be 4 byte aligned and
  391. * a multiple of 4 bytes
  392. */
  393. . = ALIGN(4);
  394. *(".kernel_bss.*")
  395. *(.bthost_bss*)
  396. *(.btsrv_bss*)
  397. } GROUP_LINK_IN(PSRAM)
  398. __bss_end = ALIGN(4);
  399. __psram_bss_end = ALIGN(4);
  400. /* ================================= sram noinit ================================= */
  401. SECTION_PROLOGUE(_SRAM_NOINIT_SECTION_NAME,(NOLOAD),)
  402. {
  403. . = ALIGN(512);
  404. __kernel_ram_start = .;
  405. *(.srm_irq_vector*)
  406. *(.interrupt.noinit.stack*)
  407. *(.main.noinit.stack*)
  408. *(.uisrv.noinit.stack*)
  409. *(.lvgl.noinit.gpu*)
  410. *(.spinand.bss.BLK_ARRAY*)
  411. *(.spinand.bss.PAGE_CACHE_BUF*)
  412. *(.system.bss.sdfs_cache*)
  413. *(.diskio.cache.pool*)
  414. *(.jpeg.bss.temp_buffer*)
  415. *(.ram.noinit*)
  416. *(.decompress.bss.cache*)
  417. *(.lvgl.noinit.vdb*)
  418. *(.ram.noinit.stack*)
  419. *(.audio.bss.ouput_pcm*)
  420. *(.audio.bss.input_pcm*)
  421. *(.act_s2_not_save_mem*)
  422. __kernel_ram_save_end = .;
  423. }GROUP_LINK_IN(SRAM)
  424. SECTION_PROLOGUE(_SRAM_SLEEP_SHUTDOWN_SECTION_NAME,(NOLOAD),)
  425. {
  426. . = ALIGN(512);
  427. _sleep_shutdown_ram_start = .;
  428. *(.ram.noinit.sufacebuffer*)
  429. _sleep_shutdown_ram_end = .;
  430. }GROUP_LINK_IN(SRAM)
  431. #ifdef CONFIG_SIM_FLASH_ACTS
  432. SECTION_PROLOGUE(SIM_ACTLOG,(NOLOAD),)
  433. {
  434. . = ALIGN(4);
  435. __sim_flash_ram_start = .;
  436. *(.sram.noinit.actlog*)
  437. __sim_flash_ram_end = .;
  438. }GROUP_LINK_IN(SRAM)
  439. #endif
  440. /* ================================= psram noinit ================================= */
  441. SECTION_PROLOGUE(_NOINIT_SECTION_NAME,(NOLOAD),)
  442. {
  443. /*
  444. * This section is used for non-initialized objects that
  445. * will not be cleared during the boot process.
  446. */
  447. *(.noinit)
  448. *(".noinit.*")
  449. *(".kernel_noinit.*")
  450. /* Located in generated directory. This file is populated by the
  451. * zephyr_linker_sources() Cmake function.
  452. */
  453. #include <snippets-noinit.ld>
  454. #ifdef CONFIG_SOC_NOINIT_LD
  455. #include <soc-noinit.ld>
  456. #endif
  457. } GROUP_LINK_IN(PSRAM)
  458. SECTION_PROLOGUE(_PRAM_NOINIT_SECTION_NAME, (NOLOAD),SUBALIGN(64))
  459. {
  460. *(.UI_PSRAM_REGION*)
  461. *(.RES_PSRAM_REGION*)
  462. *(.BMPFONT_PSRAM_REGION*)
  463. *(.font.bss.cache*)
  464. *(.lvgl.noinit.malloc*)
  465. *(.tile.bss.cache*)
  466. *(.vglite.noinit.mem_pool*)
  467. *(.vglite.noinit.malloc*)
  468. } GROUP_LINK_IN(PSRAM)
  469. /* Define linker symbols */
  470. _image_ram_end = .;
  471. __kernel_ram_end = RAM_ADDR + RAM_SIZE;
  472. __kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
  473. SECTION_PROLOGUE(_ATT_RUNTIME_DATA_SECTION_NAME,(NOLOAD),)
  474. {
  475. /*
  476. * For att runtime data
  477. */
  478. . = ALIGN(4);
  479. KEEP(*(.attruntimedata*))
  480. }GROUP_LINK_IN(DSP_SRAM)
  481. /* ================================= share ram noinit ================================= */
  482. SECTION_DATA_PROLOGUE(_SHARE_RAM_BSS_SECTION_NAME, (NOLOAD),SUBALIGN(4))
  483. {
  484. __share_ram_start = .;
  485. *(.DSP_SHARE_RAM*)
  486. } GROUP_LINK_IN(SHARE_RAM)
  487. __share_ram_end = .;
  488. _end = .; /* end of image */
  489. /* Located in generated directory. This file is populated by the
  490. * zephyr_linker_sources() Cmake function.
  491. */
  492. #include <snippets-sections.ld>
  493. #include <linker/debug-sections.ld>
  494. /DISCARD/ : { *(.note.GNU-stack) }
  495. SECTION_PROLOGUE(.ARM.attributes, 0,)
  496. {
  497. KEEP(*(.ARM.attributes))
  498. KEEP(*(.gnu.attributes))
  499. }
  500. /* Must be last in romable region */
  501. SECTION_PROLOGUE(.last_section,(NOLOAD),)
  502. {
  503. } GROUP_LINK_IN(ROMABLE_REGION)
  504. /* To provide the image size as a const expression,
  505. * calculate this value here. */
  506. _flash_used = LOADADDR(.last_section) - __rom_region_start;
  507. }