1set(COMMON_ZEPHYR_LINKER_DIR ${ZEPHYR_BASE}/cmake/linker_script/common) 2 3# This should be different for cortex_r or cortex_a.... 4# cut from zephyr/include/zephyr/arch/arm/cortex_m/scripts/linker.ld 5if(DEFINED CONFIG_CUSTOM_SECTION_MIN_ALIGN_SIZE) 6 set_ifndef(region_min_align ${CONFIG_CUSTOM_SECTION_MIN_ALIGN_SIZE}) 7endif() 8 9# Set alignment to CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE if not set above 10# to make linker section alignment comply with MPU granularity. 11if(DEFINED CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE) 12 set_ifndef(region_min_align ${CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE}) 13endif() 14 15# If building without MPU support, use default 4-byte alignment.. if not set above. 16set_ifndef(region_min_align 4) 17 18zephyr_linker_include_var(VAR region_min_align) 19if((NOT DEFINED CONFIG_CUSTOM_SECTION_ALIGN) AND DEFINED CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT) 20 # define MPU_ALIGN(region_size) \ 21 # . = ALIGN(_region_min_align); \ 22 # . = ALIGN( 1 << LOG2CEIL(region_size)) 23 # Handling this requires us to handle log2ceil() in iar linker since the size 24 # isn't known until then. 25 set(MPU_ALIGN_BYTES ${region_min_align}) 26 #message(WARNING "We can not handle . = ALIGN( 1 << LOG2CEIL(region_size)) ") 27else() 28 set(MPU_ALIGN_BYTES ${region_min_align}) 29endif() 30# The APP_SHARED_ALIGN and SMEM_PARTITION_ALIGN macros are defined as 31# ". = ALIGN(...)" things. 32# the cmake generator stuff needs an align-size in bytes so: 33zephyr_linker_include_var(VAR APP_SHARED_ALIGN_BYTES VALUE ${region_min_align}) 34zephyr_linker_include_var(VAR SMEM_PARTITION_ALIGN_BYTES VALUE ${MPU_ALIGN_BYTES}) 35 36# Note, the `+ 0` in formulas below avoids errors in cases where a Kconfig 37# variable is undefined and thus expands to nothing. 38math(EXPR FLASH_ADDR 39 "${CONFIG_FLASH_BASE_ADDRESS} + ${CONFIG_FLASH_LOAD_OFFSET} + 0" 40 OUTPUT_FORMAT HEXADECIMAL 41) 42 43if(CONFIG_FLASH_LOAD_SIZE GREATER 0) 44 math(EXPR FLASH_SIZE 45 "(${CONFIG_FLASH_LOAD_SIZE} + 0) - (${CONFIG_ROM_END_OFFSET} + 0)" 46 OUTPUT_FORMAT HEXADECIMAL 47 ) 48else() 49 math(EXPR FLASH_SIZE 50 "(${CONFIG_FLASH_SIZE} + 0) * 1024 - (${CONFIG_FLASH_LOAD_OFFSET} + 0) - (${CONFIG_ROM_END_OFFSET} + 0)" 51 OUTPUT_FORMAT HEXADECIMAL 52 ) 53endif() 54 55set(RAM_ADDR ${CONFIG_SRAM_BASE_ADDRESS}) 56math(EXPR RAM_SIZE "(${CONFIG_SRAM_SIZE} + 0) * 1024" OUTPUT_FORMAT HEXADECIMAL) 57math(EXPR IDT_ADDR "${RAM_ADDR} + ${RAM_SIZE}" OUTPUT_FORMAT HEXADECIMAL) 58 59# ToDo: decide on the optimal location for this. 60# linker/ld/target.cmake based on arch, or directly in arch and scatter_script.cmake can ignore 61zephyr_linker(FORMAT "elf32-littlearm") 62zephyr_linker(ENTRY ${CONFIG_KERNEL_ENTRY}) 63 64zephyr_linker_memory(NAME FLASH FLAGS rx START ${FLASH_ADDR} SIZE ${FLASH_SIZE}) 65zephyr_linker_memory(NAME RAM FLAGS wx START ${RAM_ADDR} SIZE ${RAM_SIZE}) 66zephyr_linker_memory(NAME IDT_LIST FLAGS wx START ${IDT_ADDR} SIZE 2K) 67 68dt_comp_path(paths COMPATIBLE "zephyr,memory-region") 69foreach(path IN LISTS paths) 70 zephyr_linker_dts_memory(PATH ${path}) 71endforeach() 72 73if(CONFIG_XIP) 74 zephyr_linker_group(NAME ROM_REGION LMA FLASH) 75 set(rom_start ${FLASH_ADDR}) 76 set(XIP_ALIGN_WITH_INPUT ALIGN_WITH_INPUT) 77else() 78 zephyr_linker_group(NAME ROM_REGION LMA RAM) 79 set(rom_start ${RAM_ADDR}) 80endif() 81 82zephyr_linker_group(NAME RAM_REGION VMA RAM LMA ROM_REGION) 83zephyr_linker_group(NAME TEXT_REGION GROUP ROM_REGION SYMBOL SECTION) 84zephyr_linker_group(NAME RODATA_REGION GROUP ROM_REGION) 85zephyr_linker_group(NAME DATA_REGION GROUP RAM_REGION SYMBOL SECTION) 86zephyr_linker_group(NAME NOINIT_REGION GROUP RAM_REGION SYMBOL SECTION) 87 88# should go to a relocation.cmake - from include/linker/rel-sections.ld - start 89zephyr_linker_section(NAME .rel.plt HIDDEN) 90zephyr_linker_section(NAME .rela.plt HIDDEN) 91zephyr_linker_section(NAME .rel.dyn) 92zephyr_linker_section(NAME .rela.dyn) 93# should go to a relocation.cmake - from include/linker/rel-sections.ld - end 94 95# Discard sections for GNU ld. 96zephyr_linker_section_configure(SECTION /DISCARD/ INPUT ".plt") 97zephyr_linker_section_configure(SECTION /DISCARD/ INPUT ".iplt") 98zephyr_linker_section_configure(SECTION /DISCARD/ INPUT ".got.plt") 99zephyr_linker_section_configure(SECTION /DISCARD/ INPUT ".igot.plt") 100zephyr_linker_section_configure(SECTION /DISCARD/ INPUT ".got") 101zephyr_linker_section_configure(SECTION /DISCARD/ INPUT ".igot") 102 103zephyr_linker_section(NAME .rom_start ADDRESS ${rom_start} GROUP ROM_REGION NOINPUT) 104 105zephyr_linker_section(NAME .text GROUP TEXT_REGION) 106 107zephyr_linker_section_configure(SECTION .rel.plt INPUT ".rel.iplt") 108zephyr_linker_section_configure(SECTION .rela.plt INPUT ".rela.iplt") 109 110include(${COMMON_ZEPHYR_LINKER_DIR}/kobject-text.cmake) 111 112zephyr_linker_section_configure(SECTION .text INPUT ".TEXT.*") 113zephyr_linker_section_configure(SECTION .text INPUT ".gnu.linkonce.t.*") 114 115zephyr_linker_section_configure(SECTION .text INPUT ".glue_7t") 116zephyr_linker_section_configure(SECTION .text INPUT ".glue_7") 117zephyr_linker_section_configure(SECTION .text INPUT ".vfp11_veneer") 118zephyr_linker_section_configure(SECTION .text INPUT ".v4_bx") 119 120if(CONFIG_CPP) 121 zephyr_linker_section(NAME .ARM.extab GROUP ROM_REGION) 122 zephyr_linker_section_configure(SECTION .ARM.extab INPUT ".gnu.linkonce.armextab.*") 123endif() 124 125zephyr_linker_section(NAME .ARM.exidx GROUP ROM_REGION) 126# Here the original linker would check for __GCC_LINKER_CMD__, need to check toolchain linker ? 127#if(__GCC_LINKER_CMD__) 128 zephyr_linker_section_configure(SECTION .ARM.exidx INPUT ".gnu.linkonce.armexidx.*" SYMBOLS "__exidx_start" "__exidx_end") 129#endif() 130 131 132include(${COMMON_ZEPHYR_LINKER_DIR}/common-rom.cmake) 133include(${COMMON_ZEPHYR_LINKER_DIR}/thread-local-storage.cmake) 134 135zephyr_linker_section(NAME .rodata GROUP RODATA_REGION) 136zephyr_linker_section_configure(SECTION .rodata INPUT ".gnu.linkonce.r.*") 137 138include(${COMMON_ZEPHYR_LINKER_DIR}/kobject-rom.cmake) 139 140zephyr_linker_section_configure(SECTION .rodata ALIGN 4) 141 142# ToDo - . = ALIGN(_region_min_align); 143# Symbol to add _image_ram_start = .; 144 145# This comes from ramfunc.ls, via snippets-ram-sections.ld 146zephyr_linker_section(NAME .ramfunc GROUP RAM_REGION SUBALIGN 8) 147# Todo: handle MPU_ALIGN(_ramfunc_size); 148 149if(CONFIG_USERSPACE) 150 # This is where the app_mem_partition stuff is going to be placed, once it 151 # is generated by gen_app_partitions.py. _app_smem has its own init-copy 152 # handling in z_data_copy, so put it in RAM_REGIOM rather than DATA_REGION 153 zephyr_linker_group(NAME APP_SMEM_GROUP GROUP RAM_REGION SYMBOL SECTION) 154 zephyr_linker_symbol(SYMBOL "_app_smem_size" EXPR "@__app_smem_group_size@") 155 zephyr_linker_symbol(SYMBOL "_app_smem_rom_start" EXPR "@__app_smem_group_load_start@") 156 157 158 zephyr_linker_section(NAME .bss GROUP RAM_REGION TYPE BSS) 159 zephyr_linker_section_configure(SECTION .bss INPUT COMMON) 160 zephyr_linker_section_configure(SECTION .bss INPUT ".kernel_bss.*") 161 162 #TODO: the skeletons includes <linker_sram_bss_relocate.ld> here 163 164 # As memory is cleared in words only, it is simpler to ensure the BSS 165 # section ends on a 4 byte boundary. This wastes a maximum of 3 bytes. 166 zephyr_linker_section_configure(SECTION .bss ALIGN 4) 167 168 include(${COMMON_ZEPHYR_LINKER_DIR}/common-noinit.cmake) 169endif() 170 171zephyr_linker_section(NAME .data GROUP DATA_REGION ALIGN_WITH_INPUT) 172zephyr_linker_section_configure(SECTION .data INPUT ".kernel.*") 173 174include(${COMMON_ZEPHYR_LINKER_DIR}/common-ram.cmake) 175include(${COMMON_ZEPHYR_LINKER_DIR}/kobject-data.cmake) 176 177if(NOT CONFIG_USERSPACE) 178 zephyr_linker_section(NAME .bss GROUP RAM_REGION TYPE BSS) 179 zephyr_linker_section_configure(SECTION .bss INPUT COMMON) 180 zephyr_linker_section_configure(SECTION .bss INPUT ".kernel_bss.*") 181 # As memory is cleared in words only, it is simpler to ensure the BSS 182 # section ends on a 4 byte boundary. This wastes a maximum of 3 bytes. 183 zephyr_linker_section_configure(SECTION .bss ALIGN 4) 184 185 zephyr_linker_section(NAME .noinit GROUP NOINIT_REGION TYPE NOLOAD NOINIT) 186 # This section is used for non-initialized objects that 187 # will not be cleared during the boot process. 188 zephyr_linker_section_configure(SECTION .noinit INPUT ".kernel_noinit.*") 189endif() 190 191include(${COMMON_ZEPHYR_LINKER_DIR}/ram-end.cmake) 192 193zephyr_linker_symbol(SYMBOL __ramfunc_region_start EXPR "(@__ramfunc_start@)") 194zephyr_linker_symbol(SYMBOL __kernel_ram_start EXPR "(@__bss_start@)") 195zephyr_linker_symbol(SYMBOL __kernel_ram_end EXPR "(${RAM_ADDR} + ${RAM_SIZE})") 196zephyr_linker_symbol(SYMBOL __kernel_ram_size EXPR "(@__kernel_ram_end@ - @__bss_start@)") 197zephyr_linker_symbol(SYMBOL _image_ram_start EXPR "(${RAM_ADDR})" SUBALIGN 32) # ToDo calculate 32 correctly 198zephyr_linker_symbol(SYMBOL ARM_LIB_STACKHEAP EXPR "(${RAM_ADDR} + ${RAM_SIZE})" SIZE -0x1000) 199 200set(VECTOR_ALIGN 4) 201if(CONFIG_CPU_CORTEX_M_HAS_VTOR) 202 math(EXPR VECTOR_ALIGN "4 * (16 + ${CONFIG_NUM_IRQS})") 203 if(${VECTOR_ALIGN} LESS 128) 204 set(VECTOR_ALIGN 128) 205 else() 206 pow2round(VECTOR_ALIGN) 207 endif() 208endif() 209 210zephyr_linker_section_configure( 211 SECTION .rom_start 212 INPUT ".exc_vector_table*" 213 ".gnu.linkonce.irq_vector_table*" 214 ".vectors" 215 OFFSET ${CONFIG_ROM_START_OFFSET} 216 KEEP FIRST 217 SYMBOLS _vector_start _vector_end 218 ALIGN ${VECTOR_ALIGN} 219 PRIO 50 220) 221 222dt_chosen(chosen_itcm PROPERTY "zephyr,itcm") 223if(DEFINED chosen_itcm) 224 dt_node_has_status(status_result PATH ${chosen_itcm} STATUS okay) 225 if(${status_result}) 226 zephyr_linker_group(NAME ITCM_REGION VMA ITCM LMA ROM_REGION) 227 228 zephyr_linker_section(NAME .itcm GROUP ITCM_REGION SUBALIGN 4) 229 endif() 230endif() 231 232dt_chosen(chosen_dtcm PROPERTY "zephyr,dtcm") 233if(DEFINED chosen_dtcm) 234 dt_node_has_status(status_result PATH ${chosen_dtcm} STATUS okay) 235 if(${status_result}) 236 zephyr_linker_group(NAME DTCM_REGION VMA DTCM LMA ROM_REGION) 237 238 zephyr_linker_section(NAME .dtcm_bss GROUP DTCM_REGION SUBALIGN 4 TYPE BSS) 239 zephyr_linker_section(NAME .dtcm_noinit GROUP DTCM_REGION SUBALIGN 4 TYPE NOLOAD NOINIT) 240 zephyr_linker_section(NAME .dtcm_data GROUP DTCM_REGION SUBALIGN 4) 241 endif() 242endif() 243 244zephyr_linker_section(NAME .ARM.attributes ADDRESS 0 NOINPUT) 245zephyr_linker_section_configure(SECTION .ARM.attributes INPUT ".ARM.attributes" KEEP) 246zephyr_linker_section_configure(SECTION .ARM.attributes INPUT ".gnu.attributes" KEEP) 247 248# armlink specific flags 249zephyr_linker_section_configure(SECTION .text ANY FLAGS "+RO" "+XO") 250zephyr_linker_section_configure(SECTION .data ANY FLAGS "+RW") 251zephyr_linker_section_configure(SECTION .bss ANY FLAGS "+ZI") 252 253include(${COMMON_ZEPHYR_LINKER_DIR}/debug-sections.cmake) 254 255dt_comp_path(paths COMPATIBLE "zephyr,memory-region") 256foreach(path IN LISTS paths) 257 zephyr_linker_dts_section(PATH ${path}) 258endforeach() 259 260 261# .last_section must be last in romable region 262# .last_section contains a fixed word to ensure location counter and actual 263# rom region data usage match when CONFIG_LINKER_LAST_SECTION_ID=y. 264zephyr_linker_section(NAME .last_section VMA FLASH LMA FLASH 265 NOINPUT TYPE LINKER_SCRIPT_FOOTER) 266# KEEP can not be passed to zephyr_linker_section, so: 267zephyr_linker_section_configure(SECTION .last_section INPUT ".last_section" KEEP) 268