diff --git a/bazel/config/BUILD.bazel b/bazel/config/BUILD.bazel index 84eac746..6b5b1f7c 100644 --- a/bazel/config/BUILD.bazel +++ b/bazel/config/BUILD.bazel @@ -217,10 +217,10 @@ string_flag( build_setting_default = "Debug", ) -# PICO_BAZEL_CONFIG: PICO_DEFAULT_LINKER_SCRIPT, [Bazel only] The library that provides a linker script to link into all binaries, default=//src/rp2_common/pico_crt0:default_linker_script, group=pico_standard_link +# PICO_BAZEL_CONFIG: PICO_DEFAULT_LINKER_SCRIPT, [Bazel only] The library that provides a linker script to link into all binaries, default=//src/rp2_common/pico_standard_link:default_linker_script, group=pico_standard_link label_flag( name = "PICO_DEFAULT_LINKER_SCRIPT", - build_setting_default = "//src/rp2_common/pico_crt0:default_linker_script", + build_setting_default = "//src/rp2_common/pico_standard_link:default_linker_script", ) # PICO_BAZEL_CONFIG: PICO_NO_TARGET_NAME, Don't define PICO_TARGET_NAME, type=bool, default=0, group=build diff --git a/bazel/util/pico_linker_scripts.bzl b/bazel/util/pico_linker_scripts.bzl new file mode 100644 index 00000000..f453b076 --- /dev/null +++ b/bazel/util/pico_linker_scripts.bzl @@ -0,0 +1,49 @@ +load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "use_cpp_toolchain") + +def _include_linker_script_dir_impl(ctx): + link_include_dir = str(ctx.label.package) + depset_direct = ["-L" + str(link_include_dir)] + if len(ctx.files.use_scripts): + for script in ctx.files.use_scripts: + depset_direct.append("-T" + str(script.path)) + + linking_inputs = cc_common.create_linker_input( + owner = ctx.label, + user_link_flags = depset( + direct = depset_direct, + ), + ) + return [ + CcInfo(linking_context = cc_common.create_linking_context(linker_inputs = depset(direct = [linking_inputs]))), + ] + +include_linker_script_dir = rule( + implementation = _include_linker_script_dir_impl, + attrs = { + "use_scripts": attr.label_list(allow_files = [".ld"]), + }, + toolchains = use_cpp_toolchain(), + fragments = ["cpp"], +) + +def _use_linker_script_file_impl(ctx): + link_file = ctx.file.script.path + + linking_inputs = cc_common.create_linker_input( + owner = ctx.label, + user_link_flags = depset( + direct = ["-T" + str(link_file)], + ), + ) + return [ + CcInfo(linking_context = cc_common.create_linking_context(linker_inputs = depset(direct = [linking_inputs]))), + ] + +use_linker_script_file = rule( + implementation = _use_linker_script_file_impl, + attrs = { + "script": attr.label(mandatory = True, allow_single_file = [".ld"]), + }, + toolchains = use_cpp_toolchain(), + fragments = ["cpp"], +) diff --git a/src/cmake/rp2_common.cmake b/src/cmake/rp2_common.cmake index 273839f7..f608e5c0 100644 --- a/src/cmake/rp2_common.cmake +++ b/src/cmake/rp2_common.cmake @@ -28,6 +28,7 @@ pico_add_subdirectory(common/hardware_claim) # # RP2040/RP2350 specific From standard build variants pico_add_subdirectory(${RP2_VARIANT_DIR}/pico_platform) +pico_add_subdirectory(${RP2_VARIANT_DIR}/pico_platform_link) pico_add_subdirectory(${RP2_VARIANT_DIR}/hardware_regs) pico_add_subdirectory(${RP2_VARIANT_DIR}/hardware_structs) pico_add_subdirectory(${RP2_VARIANT_DIR}/boot_stage2) diff --git a/src/rp2_common/pico_crt0/rp2040/BUILD.bazel b/src/rp2040/pico_platform_link/BUILD.bazel similarity index 60% rename from src/rp2_common/pico_crt0/rp2040/BUILD.bazel rename to src/rp2040/pico_platform_link/BUILD.bazel index 44912f0c..0a355624 100644 --- a/src/rp2_common/pico_crt0/rp2040/BUILD.bazel +++ b/src/rp2040/pico_platform_link/BUILD.bazel @@ -2,6 +2,8 @@ load("@rules_cc//cc:cc_library.bzl", "cc_library") package(default_visibility = ["//visibility:public"]) +load("//bazel/util:pico_linker_scripts.bzl", "use_linker_script_file") + exports_files( [ "memmap_blocked_ram.ld", @@ -11,23 +13,36 @@ exports_files( ], ) -# It's possible to set linker scripts globally or on a per-binary basis. -# -# Setting globally: -# * Set --@pico-sdk//bazel/config:PICO_DEFAULT_LINKER_SCRIPT to point to your -# desired linker script. -# -# Setting per-binary: -# * Set --@pico-sdk//bazel/config:PICO_DEFAULT_LINKER_SCRIPT=@pico-sdk//bazel:empty_cc_lib -# * Manually add your desired linker script to each cc_binary. +use_linker_script_file( + name = "memmap_default_args", + script = "memmap_default.ld", +) + +use_linker_script_file( + name = "memmap_blocked_ram_args", + script = "memmap_blocked_ram.ld", +) + +use_linker_script_file( + name = "memmap_copy_to_ram_args", + script = "memmap_copy_to_ram.ld", +) + +use_linker_script_file( + name = "memmap_no_flash_args", + script = "memmap_no_flash.ld", +) + cc_library( name = "default_linker_script", - linkopts = ["-T$(location memmap_default.ld)"], target_compatible_with = ["//bazel/constraint:rp2040"], deps = [ - "memmap_default.ld", "//src/rp2_common/pico_crt0:no_warn_rwx_flag", + "//src/rp2040/pico_platform_link/platform_scripts:rp2040_linker_scripts", + "//src/rp2_common/pico_standard_link/standard_scripts:rp2_linker_scripts", "//src/rp2_common/pico_standard_link:default_flash_region", + "memmap_default.ld", + "memmap_default_args", ], ) @@ -35,12 +50,14 @@ cc_library( cc_library( name = "blocked_ram_linker_script", defines = ["PICO_USE_BLOCKED_RAM=1"], - linkopts = ["-T$(location memmap_blocked_ram.ld)"], target_compatible_with = ["//bazel/constraint:rp2040"], deps = [ - "memmap_blocked_ram.ld", "//src/rp2_common/pico_crt0:no_warn_rwx_flag", + "//src/rp2040/pico_platform_link/platform_scripts:rp2040_linker_scripts", + "//src/rp2_common/pico_standard_link/standard_scripts:rp2_linker_scripts", "//src/rp2_common/pico_standard_link:default_flash_region", + "memmap_blocked_ram.ld", + "memmap_blocked_ram_args", ], ) @@ -48,12 +65,14 @@ cc_library( cc_library( name = "copy_to_ram_linker_script", defines = ["PICO_COPY_TO_RAM=1"], - linkopts = ["-T$(location memmap_copy_to_ram.ld)"], target_compatible_with = ["//bazel/constraint:rp2040"], deps = [ - "memmap_copy_to_ram.ld", "//src/rp2_common/pico_crt0:no_warn_rwx_flag", + "//src/rp2040/pico_platform_link/platform_scripts:rp2040_linker_scripts", + "//src/rp2_common/pico_standard_link/standard_scripts:rp2_linker_scripts", "//src/rp2_common/pico_standard_link:default_flash_region", + "memmap_copy_to_ram.ld", + "memmap_copy_to_ram_args", ], ) @@ -61,10 +80,12 @@ cc_library( cc_library( name = "no_flash_linker_script", defines = ["PICO_NO_FLASH=1"], - linkopts = ["-T$(location memmap_no_flash.ld)"], target_compatible_with = ["//bazel/constraint:rp2040"], deps = [ - "memmap_no_flash.ld", "//src/rp2_common/pico_crt0:no_warn_rwx_flag", + "//src/rp2040/pico_platform_link/platform_scripts:rp2040_linker_scripts", + "//src/rp2_common/pico_standard_link/standard_scripts:rp2_linker_scripts", + "memmap_no_flash.ld", + "memmap_no_flash_args", ], ) diff --git a/src/rp2040/pico_platform_link/CMakeLists.txt b/src/rp2040/pico_platform_link/CMakeLists.txt new file mode 100644 index 00000000..af6943eb --- /dev/null +++ b/src/rp2040/pico_platform_link/CMakeLists.txt @@ -0,0 +1,6 @@ +pico_register_common_scope_var(PICO_LINKER_SCRIPT_PATH) +if (NOT PICO_LINKER_SCRIPT_PATH) + set(PICO_LINKER_SCRIPT_PATH ${CMAKE_CURRENT_LIST_DIR}) +endif() + +pico_promote_common_scope_vars() \ No newline at end of file diff --git a/src/rp2040/pico_platform_link/memmap_blocked_ram.ld b/src/rp2040/pico_platform_link/memmap_blocked_ram.ld new file mode 100644 index 00000000..a4a52895 --- /dev/null +++ b/src/rp2040/pico_platform_link/memmap_blocked_ram.ld @@ -0,0 +1,4 @@ +/* Use blocked ram */ +RAM_ORIGIN = 0x21000000; + +INCLUDE "memmap_default.ld" diff --git a/src/rp2040/pico_platform_link/memmap_copy_to_ram.ld b/src/rp2040/pico_platform_link/memmap_copy_to_ram.ld new file mode 100644 index 00000000..cd51ceea --- /dev/null +++ b/src/rp2040/pico_platform_link/memmap_copy_to_ram.ld @@ -0,0 +1 @@ +INCLUDE "memmap_copy_to_ram.ld" diff --git a/src/rp2040/pico_platform_link/memmap_default.ld b/src/rp2040/pico_platform_link/memmap_default.ld new file mode 100644 index 00000000..c256a907 --- /dev/null +++ b/src/rp2040/pico_platform_link/memmap_default.ld @@ -0,0 +1 @@ +INCLUDE "memmap_default.ld" diff --git a/src/rp2040/pico_platform_link/memmap_no_flash.ld b/src/rp2040/pico_platform_link/memmap_no_flash.ld new file mode 100644 index 00000000..3e5be9e0 --- /dev/null +++ b/src/rp2040/pico_platform_link/memmap_no_flash.ld @@ -0,0 +1 @@ +INCLUDE "memmap_no_flash.ld" diff --git a/src/rp2040/pico_platform_link/platform_scripts/BUILD.bazel b/src/rp2040/pico_platform_link/platform_scripts/BUILD.bazel new file mode 100644 index 00000000..337252e6 --- /dev/null +++ b/src/rp2040/pico_platform_link/platform_scripts/BUILD.bazel @@ -0,0 +1,33 @@ +load("@rules_cc//cc:cc_library.bzl", "cc_library") + +package(default_visibility = ["//visibility:public"]) + +load("//bazel/util:pico_linker_scripts.bzl", "include_linker_script_dir") + +exports_files( + [ + "default_locations.ld", + "section_copy_to_ram_text.ld", + "section_default_text.ld", + "section_no_flash_text.ld", + "section_platform_end.ld", + ] +) + +include_linker_script_dir( + name = "rp2040_linker_script_args", + use_scripts = ["default_locations.ld"], +) + +cc_library( + name = "rp2040_linker_scripts", + target_compatible_with = ["//bazel/constraint:rp2040"], + deps = [ + "default_locations.ld", + "section_copy_to_ram_text.ld", + "section_default_text.ld", + "section_no_flash_text.ld", + "section_platform_end.ld", + "rp2040_linker_script_args", + ], +) \ No newline at end of file diff --git a/src/rp2040/pico_platform_link/platform_scripts/default_locations.ld b/src/rp2040/pico_platform_link/platform_scripts/default_locations.ld new file mode 100644 index 00000000..03144ea0 --- /dev/null +++ b/src/rp2040/pico_platform_link/platform_scripts/default_locations.ld @@ -0,0 +1,8 @@ +RAM_ORIGIN_DEFAULT = 0x20000000; +RAM_LENGTH_DEFAULT = 256k; +SCRATCH_X_ORIGIN_DEFAULT = 0x20040000; +SCRATCH_X_LENGTH_DEFAULT = 4k; +SCRATCH_Y_ORIGIN_DEFAULT = 0x20041000; +SCRATCH_Y_LENGTH_DEFAULT = 4k; +XIP_RAM_ORIGIN_DEFAULT = 0x15000000; +XIP_RAM_LENGTH_DEFAULT = 16k; diff --git a/src/rp2040/pico_platform_link/platform_scripts/section_copy_to_ram_text.ld b/src/rp2040/pico_platform_link/platform_scripts/section_copy_to_ram_text.ld new file mode 100644 index 00000000..77a45941 --- /dev/null +++ b/src/rp2040/pico_platform_link/platform_scripts/section_copy_to_ram_text.ld @@ -0,0 +1,101 @@ +SECTIONS +{ + /* Second stage bootloader is prepended to the image. It must be 256 bytes big + and checksummed. It is usually built by the boot_stage2 target + in the Raspberry Pi Pico SDK + */ + + .flash_begin : { + __flash_binary_start = .; + } > FLASH + + .boot2 : { + __boot2_start__ = .; + KEEP (*(.boot2)) + __boot2_end__ = .; + } > FLASH + + ASSERT(__boot2_end__ - __boot2_start__ == 256, + "ERROR: Pico second stage bootloader must be 256 bytes in size") + + /* The second stage will always enter the image at the start of .text. + The debugger will use the ELF entry point, which is the _entry_point + symbol if present, otherwise defaults to start of .text. + This can be used to transfer control back to the bootrom on debugger + launches only, to perform proper flash setup. + */ + + .flashtext : { + __logical_binary_start = .; + KEEP (*(.vectors)) + KEEP (*(.binary_info_header)) + __binary_info_header_end = .; + KEEP (*(.embedded_block)) + __embedded_block_end = .; + KEEP (*(.reset)) + } + + .rodata : { + /* segments not marked as .flashdata are instead pulled into .data (in RAM) to avoid accidental flash accesses */ + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) + . = ALIGN(4); + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* Machine inspectable binary information */ + . = ALIGN(4); + __binary_info_start = .; + .binary_info : + { + KEEP(*(.binary_info.keep.*)) + *(.binary_info.*) + } > FLASH + __binary_info_end = .; + . = ALIGN(4); + + /* Vector table goes first in RAM, to avoid large alignment hole */ + .ram_vector_table (NOLOAD): { + *(.ram_vector_table) + } > RAM + + .uninitialized_data (NOLOAD): { + . = ALIGN(4); + *(.uninitialized_data*) + } > RAM + + .text : { + __ram_text_start__ = .; + *(.init) + *(.text*) + *(.fini) + /* Pull all c'tors into .text */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + /* Followed by destructors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.eh_frame*) + . = ALIGN(4); + __ram_text_end__ = .; + } > RAM AT> FLASH + __ram_text_source__ = LOADADDR(.text); + . = ALIGN(4); +} diff --git a/src/rp2040/pico_platform_link/platform_scripts/section_default_text.ld b/src/rp2040/pico_platform_link/platform_scripts/section_default_text.ld new file mode 100644 index 00000000..7aa5c939 --- /dev/null +++ b/src/rp2040/pico_platform_link/platform_scripts/section_default_text.ld @@ -0,0 +1,109 @@ +SECTIONS +{ + /* Second stage bootloader is prepended to the image. It must be 256 bytes big + and checksummed. It is usually built by the boot_stage2 target + in the Raspberry Pi Pico SDK + */ + + .flash_begin : { + __flash_binary_start = .; + } > FLASH + + .boot2 : { + __boot2_start__ = .; + KEEP (*(.boot2)) + __boot2_end__ = .; + } > FLASH + + ASSERT(__boot2_end__ - __boot2_start__ == 256, + "ERROR: Pico second stage bootloader must be 256 bytes in size") + + /* The second stage will always enter the image at the start of .text. + The debugger will use the ELF entry point, which is the _entry_point + symbol if present, otherwise defaults to start of .text. + This can be used to transfer control back to the bootrom on debugger + launches only, to perform proper flash setup. + */ + + .text : { + __logical_binary_start = .; + KEEP (*(.vectors)) + KEEP (*(.binary_info_header)) + __binary_info_header_end = .; + KEEP (*(.embedded_block)) + __embedded_block_end = .; + KEEP (*(.reset)) + /* TODO revisit this now memset/memcpy/float in ROM */ + /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from + * FLASH ... we will include any thing excluded here in .data below by default */ + *(.init) + *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) + *(.fini) + /* Pull all c'tors into .text */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + /* Followed by destructors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(SORT(.preinit_array.*))) + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.eh_frame*) + . = ALIGN(4); + } > FLASH + + .rodata : { + *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*) + . = ALIGN(4); + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) + . = ALIGN(4); + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* Machine inspectable binary information */ + . = ALIGN(4); + __binary_info_start = .; + .binary_info : + { + KEEP(*(.binary_info.keep.*)) + *(.binary_info.*) + } > FLASH + __binary_info_end = .; + . = ALIGN(4); +} diff --git a/src/rp2040/pico_platform_link/platform_scripts/section_no_flash_text.ld b/src/rp2040/pico_platform_link/platform_scripts/section_no_flash_text.ld new file mode 100644 index 00000000..b4ad44ba --- /dev/null +++ b/src/rp2040/pico_platform_link/platform_scripts/section_no_flash_text.ld @@ -0,0 +1,71 @@ +SECTIONS +{ + /* Note in NO_FLASH builds the entry point for both the bootrom, and debugger + entry (ELF entry point), are *first* in the image, and the vector table + follows immediately afterward. This is because the bootrom enters RAM + binaries directly at their lowest address (preferring main RAM over XIP + cache-as-SRAM if both are used). + */ + + .text : { + __logical_binary_start = .; + __reset_start = .; + KEEP (*(.reset)) + __reset_end = .; + KEEP (*(.binary_info_header)) + __binary_info_header_end = .; + KEEP (*(.embedded_block)) + __embedded_block_end = .; + . = ALIGN(256); + KEEP (*(.vectors)) + *(.text*) + . = ALIGN(4); + *(.init) + *(.fini) + /* Pull all c'tors into .text */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + /* Followed by destructors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.eh_frame*) + } > RAM + + .rodata : { + . = ALIGN(4); + *(.rodata*) + . = ALIGN(4); + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) + . = ALIGN(4); + } > RAM + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > RAM + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > RAM + __exidx_end = .; + + /* Machine inspectable binary information */ + . = ALIGN(4); + __binary_info_start = .; + .binary_info : + { + KEEP(*(.binary_info.keep.*)) + *(.binary_info.*) + } > RAM + __binary_info_end = .; + . = ALIGN(4); +} diff --git a/src/rp2040/pico_platform_link/platform_scripts/section_platform_end.ld b/src/rp2040/pico_platform_link/platform_scripts/section_platform_end.ld new file mode 100644 index 00000000..2d0165aa --- /dev/null +++ b/src/rp2040/pico_platform_link/platform_scripts/section_platform_end.ld @@ -0,0 +1,50 @@ +/* Based on GCC ARM embedded samples. + Defines the following symbols for use by code: + __exidx_start + __exidx_end + __etext + __data_start__ + __preinit_array_start + __preinit_array_end + __init_array_start + __init_array_end + __fini_array_start + __fini_array_end + __data_end__ + __bss_start__ + __bss_end__ + __end__ + end + __HeapLimit + __StackLimit + __StackTop + __stack (== StackTop) +*/ + +SECTIONS +{ + /* stack limit is poorly named, but historically is maximum heap ptr */ + __StackLimit = ORIGIN(RAM) + LENGTH(RAM); + __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); + __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); + __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); + __StackBottom = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* picolibc and LLVM */ + PROVIDE (__heap_start = __end__); + PROVIDE (__heap_end = __HeapLimit); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + + /* llvm-libc */ + PROVIDE (_end = __end__); + PROVIDE (__llvm_libc_heap_limit = __HeapLimit); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") + + ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary") + /* todo assert on extra code */ +} diff --git a/src/rp2_common/pico_crt0/rp2350/BUILD.bazel b/src/rp2350/pico_platform_link/BUILD.bazel similarity index 56% rename from src/rp2_common/pico_crt0/rp2350/BUILD.bazel rename to src/rp2350/pico_platform_link/BUILD.bazel index b0f1ca7d..d3aae916 100644 --- a/src/rp2_common/pico_crt0/rp2350/BUILD.bazel +++ b/src/rp2350/pico_platform_link/BUILD.bazel @@ -2,6 +2,8 @@ load("@rules_cc//cc:cc_library.bzl", "cc_library") package(default_visibility = ["//visibility:public"]) +load("//bazel/util:pico_linker_scripts.bzl", "use_linker_script_file") + exports_files( [ "memmap_copy_to_ram.ld", @@ -10,23 +12,36 @@ exports_files( ], ) -# It's possible to set linker scripts globally or on a per-binary basis. -# -# Setting globally: -# * Set --@pico-sdk//bazel/config:PICO_DEFAULT_LINKER_SCRIPT to point to your -# desired linker script. -# -# Setting per-binary: -# * Set --@pico-sdk//bazel/config:PICO_DEFAULT_LINKER_SCRIPT=@pico-sdk//bazel:empty_cc_lib -# * Manually add your desired linker script to each cc_binary. +use_linker_script_file( + name = "memmap_default_args", + script = "memmap_default.ld", +) + +use_linker_script_file( + name = "memmap_blocked_ram_args", + script = "memmap_blocked_ram.ld", +) + +use_linker_script_file( + name = "memmap_copy_to_ram_args", + script = "memmap_copy_to_ram.ld", +) + +use_linker_script_file( + name = "memmap_no_flash_args", + script = "memmap_no_flash.ld", +) + cc_library( name = "default_linker_script", - linkopts = ["-T$(location memmap_default.ld)"], target_compatible_with = ["//bazel/constraint:rp2350"], deps = [ - "memmap_default.ld", "//src/rp2_common/pico_crt0:no_warn_rwx_flag", + "//src/rp2350/pico_platform_link/platform_scripts:rp2350_linker_scripts", + "//src/rp2_common/pico_standard_link/standard_scripts:rp2_linker_scripts", "//src/rp2_common/pico_standard_link:default_flash_region", + "memmap_default.ld", + "memmap_default_args", ], ) @@ -34,12 +49,14 @@ cc_library( cc_library( name = "copy_to_ram_linker_script", defines = ["PICO_COPY_TO_RAM=1"], - linkopts = ["-T$(location memmap_copy_to_ram.ld)"], target_compatible_with = ["//bazel/constraint:rp2350"], deps = [ - "memmap_copy_to_ram.ld", "//src/rp2_common/pico_crt0:no_warn_rwx_flag", + "//src/rp2350/pico_platform_link/platform_scripts:rp2350_linker_scripts", + "//src/rp2_common/pico_standard_link/standard_scripts:rp2_linker_scripts", "//src/rp2_common/pico_standard_link:default_flash_region", + "memmap_copy_to_ram.ld", + "memmap_copy_to_ram_args", ], ) @@ -47,10 +64,12 @@ cc_library( cc_library( name = "no_flash_linker_script", defines = ["PICO_NO_FLASH=1"], - linkopts = ["-T$(location memmap_no_flash.ld)"], target_compatible_with = ["//bazel/constraint:rp2350"], deps = [ - "memmap_no_flash.ld", "//src/rp2_common/pico_crt0:no_warn_rwx_flag", + "//src/rp2350/pico_platform_link/platform_scripts:rp2350_linker_scripts", + "//src/rp2_common/pico_standard_link/standard_scripts:rp2_linker_scripts", + "memmap_no_flash.ld", + "memmap_no_flash_args", ], ) diff --git a/src/rp2350/pico_platform_link/CMakeLists.txt b/src/rp2350/pico_platform_link/CMakeLists.txt new file mode 100644 index 00000000..af6943eb --- /dev/null +++ b/src/rp2350/pico_platform_link/CMakeLists.txt @@ -0,0 +1,6 @@ +pico_register_common_scope_var(PICO_LINKER_SCRIPT_PATH) +if (NOT PICO_LINKER_SCRIPT_PATH) + set(PICO_LINKER_SCRIPT_PATH ${CMAKE_CURRENT_LIST_DIR}) +endif() + +pico_promote_common_scope_vars() \ No newline at end of file diff --git a/src/rp2350/pico_platform_link/memmap_copy_to_ram.ld b/src/rp2350/pico_platform_link/memmap_copy_to_ram.ld new file mode 100644 index 00000000..cd51ceea --- /dev/null +++ b/src/rp2350/pico_platform_link/memmap_copy_to_ram.ld @@ -0,0 +1 @@ +INCLUDE "memmap_copy_to_ram.ld" diff --git a/src/rp2350/pico_platform_link/memmap_default.ld b/src/rp2350/pico_platform_link/memmap_default.ld new file mode 100644 index 00000000..c256a907 --- /dev/null +++ b/src/rp2350/pico_platform_link/memmap_default.ld @@ -0,0 +1 @@ +INCLUDE "memmap_default.ld" diff --git a/src/rp2350/pico_platform_link/memmap_no_flash.ld b/src/rp2350/pico_platform_link/memmap_no_flash.ld new file mode 100644 index 00000000..3e5be9e0 --- /dev/null +++ b/src/rp2350/pico_platform_link/memmap_no_flash.ld @@ -0,0 +1 @@ +INCLUDE "memmap_no_flash.ld" diff --git a/src/rp2350/pico_platform_link/platform_scripts/BUILD.bazel b/src/rp2350/pico_platform_link/platform_scripts/BUILD.bazel new file mode 100644 index 00000000..5b234a01 --- /dev/null +++ b/src/rp2350/pico_platform_link/platform_scripts/BUILD.bazel @@ -0,0 +1,27 @@ +load("@rules_cc//cc:cc_library.bzl", "cc_library") + +package(default_visibility = ["//visibility:public"]) + +load("//bazel/util:pico_linker_scripts.bzl", "include_linker_script_dir") + +exports_files( + [ + "default_locations.ld", + "section_platform_end.ld", + ] +) + +include_linker_script_dir( + name = "rp2350_linker_script_args", + use_scripts = ["default_locations.ld"], +) + +cc_library( + name = "rp2350_linker_scripts", + target_compatible_with = ["//bazel/constraint:rp2350"], + deps = [ + "default_locations.ld", + "section_platform_end.ld", + "rp2350_linker_script_args", + ], +) \ No newline at end of file diff --git a/src/rp2350/pico_platform_link/platform_scripts/default_locations.ld b/src/rp2350/pico_platform_link/platform_scripts/default_locations.ld new file mode 100644 index 00000000..15ddc737 --- /dev/null +++ b/src/rp2350/pico_platform_link/platform_scripts/default_locations.ld @@ -0,0 +1,8 @@ +RAM_ORIGIN_DEFAULT = 0x20000000; +RAM_LENGTH_DEFAULT = 512k; +SCRATCH_X_ORIGIN_DEFAULT = 0x20080000; +SCRATCH_X_LENGTH_DEFAULT = 4k; +SCRATCH_Y_ORIGIN_DEFAULT = 0x20081000; +SCRATCH_Y_LENGTH_DEFAULT = 4k; +XIP_RAM_ORIGIN_DEFAULT = 0x13FFC000; +XIP_RAM_LENGTH_DEFAULT = 16k; diff --git a/src/rp2350/pico_platform_link/platform_scripts/section_platform_end.ld b/src/rp2350/pico_platform_link/platform_scripts/section_platform_end.ld new file mode 100644 index 00000000..43cc19ec --- /dev/null +++ b/src/rp2350/pico_platform_link/platform_scripts/section_platform_end.ld @@ -0,0 +1,7 @@ +SECTIONS +{ + ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary") + ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary") + + /* todo assert on extra code */ +} diff --git a/src/rp2_common/pico_crt0/BUILD.bazel b/src/rp2_common/pico_crt0/BUILD.bazel index b47b9c6c..99c9244b 100644 --- a/src/rp2_common/pico_crt0/BUILD.bazel +++ b/src/rp2_common/pico_crt0/BUILD.bazel @@ -3,48 +3,13 @@ load("//bazel:defs.bzl", "compatible_with_rp2") package(default_visibility = ["//visibility:public"]) -alias( - name = "default_linker_script", - actual = select({ - "//bazel/constraint:rp2040": "//src/rp2_common/pico_crt0/rp2040:default_linker_script", - "//bazel/constraint:rp2350": "//src/rp2_common/pico_crt0/rp2350:default_linker_script", - "//conditions:default": "//bazel:incompatible_cc_lib", - }), -) - -alias( - name = "blocked_ram_linker_script", - actual = select({ - "//bazel/constraint:rp2040": "//src/rp2_common/pico_crt0/rp2040:blocked_ram_linker_script", - "//conditions:default": "//bazel:incompatible_cc_lib", - }), -) - -alias( - name = "copy_to_ram_linker_script", - actual = select({ - "//bazel/constraint:rp2040": "//src/rp2_common/pico_crt0/rp2040:copy_to_ram_linker_script", - "//bazel/constraint:rp2350": "//src/rp2_common/pico_crt0/rp2350:copy_to_ram_linker_script", - "//conditions:default": "//bazel:incompatible_cc_lib", - }), -) - -alias( - name = "no_flash_linker_script", - actual = select({ - "//bazel/constraint:rp2040": "//src/rp2_common/pico_crt0/rp2040:no_flash_linker_script", - "//bazel/constraint:rp2350": "//src/rp2_common/pico_crt0/rp2350:no_flash_linker_script", - "//conditions:default": "//bazel:incompatible_cc_lib", - }), -) - cc_library( name = "no_warn_rwx_flag", linkopts = select({ "//bazel/constraint:pico_toolchain_gcc_enabled": ["-Wl,--no-warn-rwx-segments"], "//conditions:default": [], }), - visibility = [":__subpackages__"], + visibility = ["//src:__subpackages__"], ) cc_library( diff --git a/src/rp2_common/pico_crt0/CMakeLists.txt b/src/rp2_common/pico_crt0/CMakeLists.txt index bd415693..1bbbac74 100644 --- a/src/rp2_common/pico_crt0/CMakeLists.txt +++ b/src/rp2_common/pico_crt0/CMakeLists.txt @@ -11,9 +11,4 @@ if (NOT TARGET pico_crt0) target_link_libraries(pico_crt0 INTERFACE boot_picobin_headers pico_bootrom_headers) endif() -pico_register_common_scope_var(PICO_LINKER_SCRIPT_PATH) -if (NOT PICO_LINKER_SCRIPT_PATH) - set(PICO_LINKER_SCRIPT_PATH ${CMAKE_CURRENT_LIST_DIR}/${PICO_CHIP}) -endif() - pico_promote_common_scope_vars() \ No newline at end of file diff --git a/src/rp2_common/pico_crt0/rp2040/memmap_blocked_ram.ld b/src/rp2_common/pico_crt0/rp2040/memmap_blocked_ram.ld deleted file mode 100644 index 6f500056..00000000 --- a/src/rp2_common/pico_crt0/rp2040/memmap_blocked_ram.ld +++ /dev/null @@ -1,286 +0,0 @@ -/* Based on GCC ARM embedded samples. - Defines the following symbols for use by code: - __exidx_start - __exidx_end - __etext - __data_start__ - __preinit_array_start - __preinit_array_end - __init_array_start - __init_array_end - __fini_array_start - __fini_array_end - __data_end__ - __bss_start__ - __bss_end__ - __end__ - end - __HeapLimit - __StackLimit - __StackTop - __stack (== StackTop) -*/ - -MEMORY -{ - INCLUDE "pico_flash_region.ld" - RAM(rwx) : ORIGIN = 0x21000000, LENGTH = 256k - SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k - SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k -} - -ENTRY(_entry_point) - -SECTIONS -{ - /* Second stage bootloader is prepended to the image. It must be 256 bytes big - and checksummed. It is usually built by the boot_stage2 target - in the Raspberry Pi Pico SDK - */ - - .flash_begin : { - __flash_binary_start = .; - } > FLASH - - .boot2 : { - __boot2_start__ = .; - KEEP (*(.boot2)) - __boot2_end__ = .; - } > FLASH - - ASSERT(__boot2_end__ - __boot2_start__ == 256, - "ERROR: Pico second stage bootloader must be 256 bytes in size") - - /* The second stage will always enter the image at the start of .text. - The debugger will use the ELF entry point, which is the _entry_point - symbol if present, otherwise defaults to start of .text. - This can be used to transfer control back to the bootrom on debugger - launches only, to perform proper flash setup. - */ - - .text : { - __logical_binary_start = .; - KEEP (*(.vectors)) - KEEP (*(.binary_info_header)) - __binary_info_header_end = .; - KEEP (*(.embedded_block)) - __embedded_block_end = .; - KEEP (*(.reset)) - /* TODO revisit this now memset/memcpy/float in ROM */ - /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from - * FLASH ... we will include any thing excluded here in .data below by default */ - *(.init) - *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) - *(.fini) - /* Pull all c'tors into .text */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - /* Followed by destructors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(SORT(.preinit_array.*))) - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - *(SORT(.fini_array.*)) - *(.fini_array) - PROVIDE_HIDDEN (__fini_array_end = .); - - *(.eh_frame*) - . = ALIGN(4); - } > FLASH - - .rodata : { - *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*) - . = ALIGN(4); - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) - . = ALIGN(4); - } > FLASH - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > FLASH - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > FLASH - __exidx_end = .; - - /* Machine inspectable binary information */ - . = ALIGN(4); - __binary_info_start = .; - .binary_info : - { - KEEP(*(.binary_info.keep.*)) - *(.binary_info.*) - } > FLASH - __binary_info_end = .; - . = ALIGN(4); - - .ram_vector_table (NOLOAD): { - *(.ram_vector_table) - } > RAM - - .uninitialized_data (NOLOAD): { - . = ALIGN(4); - *(.uninitialized_data*) - } > RAM - - .data : { - __data_start__ = .; - *(vtable) - - *(.time_critical*) - - /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */ - *(.text*) - . = ALIGN(4); - *(.rodata*) - . = ALIGN(4); - - *(.data*) - - . = ALIGN(4); - *(.after_data.*) - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__mutex_array_start = .); - KEEP(*(SORT(.mutex_array.*))) - KEEP(*(.mutex_array)) - PROVIDE_HIDDEN (__mutex_array_end = .); - - . = ALIGN(4); - *(.jcr) - . = ALIGN(4); - } > RAM AT> FLASH - - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; - } > RAM AT> FLASH - PROVIDE(__data_end__ = .); - - /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ - __etext = LOADADDR(.data); - - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - - .bss (NOLOAD) : { - . = ALIGN(4); - __tbss_end = .; - - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .heap (NOLOAD): - { - __end__ = .; - end = __end__; - KEEP(*(.heap*)) - } > RAM - /* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however - to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */ - __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); - - /* Start and end symbols must be word-aligned */ - .scratch_x : { - __scratch_x_start__ = .; - *(.scratch_x.*) - . = ALIGN(4); - __scratch_x_end__ = .; - } > SCRATCH_X AT > FLASH - __scratch_x_source__ = LOADADDR(.scratch_x); - - .scratch_y : { - __scratch_y_start__ = .; - *(.scratch_y.*) - . = ALIGN(4); - __scratch_y_end__ = .; - } > SCRATCH_Y AT > FLASH - __scratch_y_source__ = LOADADDR(.scratch_y); - - /* .stack*_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later - * - * stack1 section may be empty/missing if platform_launch_core1 is not used */ - - /* by default we put core 0 stack at the end of scratch Y, so that if core 1 - * stack is not used then all of SCRATCH_X is free. - */ - .stack1_dummy (NOLOAD): - { - *(.stack1*) - } > SCRATCH_X - .stack_dummy (NOLOAD): - { - KEEP(*(.stack*)) - } > SCRATCH_Y - - .flash_end : { - KEEP(*(.embedded_end_block*)) - PROVIDE(__flash_binary_end = .); - } > FLASH - - /* stack limit is poorly named, but historically is maximum heap ptr */ - __StackLimit = ORIGIN(RAM) + LENGTH(RAM); - __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); - __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); - __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); - __StackBottom = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* picolibc and LLVM */ - PROVIDE (__heap_start = __end__); - PROVIDE (__heap_end = __HeapLimit); - PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); - PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); - PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); - - /* llvm-libc */ - PROVIDE (_end = __end__); - PROVIDE (__llvm_libc_heap_limit = __HeapLimit); - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") - - ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary") - /* todo assert on extra code */ -} - diff --git a/src/rp2_common/pico_crt0/rp2040/memmap_copy_to_ram.ld b/src/rp2_common/pico_crt0/rp2040/memmap_copy_to_ram.ld deleted file mode 100644 index 842ebfd3..00000000 --- a/src/rp2_common/pico_crt0/rp2040/memmap_copy_to_ram.ld +++ /dev/null @@ -1,287 +0,0 @@ -/* Based on GCC ARM embedded samples. - Defines the following symbols for use by code: - __exidx_start - __exidx_end - __etext - __data_start__ - __preinit_array_start - __preinit_array_end - __init_array_start - __init_array_end - __fini_array_start - __fini_array_end - __data_end__ - __bss_start__ - __bss_end__ - __end__ - end - __HeapLimit - __StackLimit - __StackTop - __stack (== StackTop) -*/ - -MEMORY -{ - INCLUDE "pico_flash_region.ld" - RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k - SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k - SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k -} - -ENTRY(_entry_point) - -SECTIONS -{ - /* Second stage bootloader is prepended to the image. It must be 256 bytes big - and checksummed. It is usually built by the boot_stage2 target - in the Raspberry Pi Pico SDK - */ - - .flash_begin : { - __flash_binary_start = .; - } > FLASH - - .boot2 : { - __boot2_start__ = .; - KEEP (*(.boot2)) - __boot2_end__ = .; - } > FLASH - - ASSERT(__boot2_end__ - __boot2_start__ == 256, - "ERROR: Pico second stage bootloader must be 256 bytes in size") - - /* The second stage will always enter the image at the start of .text. - The debugger will use the ELF entry point, which is the _entry_point - symbol if present, otherwise defaults to start of .text. - This can be used to transfer control back to the bootrom on debugger - launches only, to perform proper flash setup. - */ - - .flashtext : { - __logical_binary_start = .; - KEEP (*(.vectors)) - KEEP (*(.binary_info_header)) - __binary_info_header_end = .; - KEEP (*(.embedded_block)) - __embedded_block_end = .; - KEEP (*(.reset)) - } - - .rodata : { - /* segments not marked as .flashdata are instead pulled into .data (in RAM) to avoid accidental flash accesses */ - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) - . = ALIGN(4); - } > FLASH - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > FLASH - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > FLASH - __exidx_end = .; - - /* Machine inspectable binary information */ - . = ALIGN(4); - __binary_info_start = .; - .binary_info : - { - KEEP(*(.binary_info.keep.*)) - *(.binary_info.*) - } > FLASH - __binary_info_end = .; - . = ALIGN(4); - - /* Vector table goes first in RAM, to avoid large alignment hole */ - .ram_vector_table (NOLOAD): { - *(.ram_vector_table) - } > RAM - - .uninitialized_data (NOLOAD): { - . = ALIGN(4); - *(.uninitialized_data*) - } > RAM - - .text : { - __ram_text_start__ = .; - *(.init) - *(.text*) - *(.fini) - /* Pull all c'tors into .text */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - /* Followed by destructors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - *(.eh_frame*) - . = ALIGN(4); - __ram_text_end__ = .; - } > RAM AT> FLASH - __ram_text_source__ = LOADADDR(.text); - . = ALIGN(4); - - .data : { - __data_start__ = .; - *(vtable) - - *(.time_critical*) - - . = ALIGN(4); - *(.rodata*) - . = ALIGN(4); - - *(.data*) - - . = ALIGN(4); - *(.after_data.*) - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__mutex_array_start = .); - KEEP(*(SORT(.mutex_array.*))) - KEEP(*(.mutex_array)) - PROVIDE_HIDDEN (__mutex_array_end = .); - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(SORT(.preinit_array.*))) - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - *(SORT(.fini_array.*)) - *(.fini_array) - PROVIDE_HIDDEN (__fini_array_end = .); - - *(.jcr) - . = ALIGN(4); - } > RAM AT> FLASH - - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; - } > RAM AT> FLASH - PROVIDE(__data_end__ = .); - - /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ - __etext = LOADADDR(.data); - - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - - .bss : { - . = ALIGN(4); - __tbss_end = .; - - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .heap (NOLOAD): - { - __end__ = .; - end = __end__; - KEEP(*(.heap*)) - } > RAM - /* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however - to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */ - __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); - - /* Start and end symbols must be word-aligned */ - .scratch_x : { - __scratch_x_start__ = .; - *(.scratch_x.*) - . = ALIGN(4); - __scratch_x_end__ = .; - } > SCRATCH_X AT > FLASH - __scratch_x_source__ = LOADADDR(.scratch_x); - - .scratch_y : { - __scratch_y_start__ = .; - *(.scratch_y.*) - . = ALIGN(4); - __scratch_y_end__ = .; - } > SCRATCH_Y AT > FLASH - __scratch_y_source__ = LOADADDR(.scratch_y); - - /* .stack*_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later - * - * stack1 section may be empty/missing if platform_launch_core1 is not used */ - - /* by default we put core 0 stack at the end of scratch Y, so that if core 1 - * stack is not used then all of SCRATCH_X is free. - */ - .stack1_dummy (NOLOAD): - { - *(.stack1*) - } > SCRATCH_X - .stack_dummy (NOLOAD): - { - KEEP(*(.stack*)) - } > SCRATCH_Y - - .flash_end : { - KEEP(*(.embedded_end_block*)) - PROVIDE(__flash_binary_end = .); - } > FLASH - - /* stack limit is poorly named, but historically is maximum heap ptr */ - __StackLimit = ORIGIN(RAM) + LENGTH(RAM); - __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); - __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); - __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); - __StackBottom = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* picolibc and LLVM */ - PROVIDE (__heap_start = __end__); - PROVIDE (__heap_end = __HeapLimit); - PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); - PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); - PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); - - /* llvm-libc */ - PROVIDE (_end = __end__); - PROVIDE (__llvm_libc_heap_limit = __HeapLimit); - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") - - ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary") - /* todo assert on extra code */ -} - diff --git a/src/rp2_common/pico_crt0/rp2040/memmap_default.ld b/src/rp2_common/pico_crt0/rp2040/memmap_default.ld deleted file mode 100644 index 51254012..00000000 --- a/src/rp2_common/pico_crt0/rp2040/memmap_default.ld +++ /dev/null @@ -1,286 +0,0 @@ -/* Based on GCC ARM embedded samples. - Defines the following symbols for use by code: - __exidx_start - __exidx_end - __etext - __data_start__ - __preinit_array_start - __preinit_array_end - __init_array_start - __init_array_end - __fini_array_start - __fini_array_end - __data_end__ - __bss_start__ - __bss_end__ - __end__ - end - __HeapLimit - __StackLimit - __StackTop - __stack (== StackTop) -*/ - -MEMORY -{ - INCLUDE "pico_flash_region.ld" - RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k - SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k - SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k -} - -ENTRY(_entry_point) - -SECTIONS -{ - /* Second stage bootloader is prepended to the image. It must be 256 bytes big - and checksummed. It is usually built by the boot_stage2 target - in the Raspberry Pi Pico SDK - */ - - .flash_begin : { - __flash_binary_start = .; - } > FLASH - - .boot2 : { - __boot2_start__ = .; - KEEP (*(.boot2)) - __boot2_end__ = .; - } > FLASH - - ASSERT(__boot2_end__ - __boot2_start__ == 256, - "ERROR: Pico second stage bootloader must be 256 bytes in size") - - /* The second stage will always enter the image at the start of .text. - The debugger will use the ELF entry point, which is the _entry_point - symbol if present, otherwise defaults to start of .text. - This can be used to transfer control back to the bootrom on debugger - launches only, to perform proper flash setup. - */ - - .text : { - __logical_binary_start = .; - KEEP (*(.vectors)) - KEEP (*(.binary_info_header)) - __binary_info_header_end = .; - KEEP (*(.embedded_block)) - __embedded_block_end = .; - KEEP (*(.reset)) - /* TODO revisit this now memset/memcpy/float in ROM */ - /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from - * FLASH ... we will include any thing excluded here in .data below by default */ - *(.init) - *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) - *(.fini) - /* Pull all c'tors into .text */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - /* Followed by destructors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(SORT(.preinit_array.*))) - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - *(SORT(.fini_array.*)) - *(.fini_array) - PROVIDE_HIDDEN (__fini_array_end = .); - - *(.eh_frame*) - . = ALIGN(4); - } > FLASH - - .rodata : { - *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*) - . = ALIGN(4); - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) - . = ALIGN(4); - } > FLASH - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > FLASH - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > FLASH - __exidx_end = .; - - /* Machine inspectable binary information */ - . = ALIGN(4); - __binary_info_start = .; - .binary_info : - { - KEEP(*(.binary_info.keep.*)) - *(.binary_info.*) - } > FLASH - __binary_info_end = .; - . = ALIGN(4); - - .ram_vector_table (NOLOAD): { - *(.ram_vector_table) - } > RAM - - .uninitialized_data (NOLOAD): { - . = ALIGN(4); - *(.uninitialized_data*) - } > RAM - - .data : { - __data_start__ = .; - *(vtable) - - *(.time_critical*) - - /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */ - *(.text*) - . = ALIGN(4); - *(.rodata*) - . = ALIGN(4); - - *(.data*) - - . = ALIGN(4); - *(.after_data.*) - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__mutex_array_start = .); - KEEP(*(SORT(.mutex_array.*))) - KEEP(*(.mutex_array)) - PROVIDE_HIDDEN (__mutex_array_end = .); - - . = ALIGN(4); - *(.jcr) - . = ALIGN(4); - } > RAM AT> FLASH - - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; - } > RAM AT> FLASH - PROVIDE(__data_end__ = .); - - /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ - __etext = LOADADDR(.data); - - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - - .bss (NOLOAD) : { - . = ALIGN(4); - __tbss_end = .; - - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .heap (NOLOAD): - { - __end__ = .; - end = __end__; - KEEP(*(.heap*)) - } > RAM - /* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however - to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */ - __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); - - /* Start and end symbols must be word-aligned */ - .scratch_x : { - __scratch_x_start__ = .; - *(.scratch_x.*) - . = ALIGN(4); - __scratch_x_end__ = .; - } > SCRATCH_X AT > FLASH - __scratch_x_source__ = LOADADDR(.scratch_x); - - .scratch_y : { - __scratch_y_start__ = .; - *(.scratch_y.*) - . = ALIGN(4); - __scratch_y_end__ = .; - } > SCRATCH_Y AT > FLASH - __scratch_y_source__ = LOADADDR(.scratch_y); - - /* .stack*_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later - * - * stack1 section may be empty/missing if platform_launch_core1 is not used */ - - /* by default we put core 0 stack at the end of scratch Y, so that if core 1 - * stack is not used then all of SCRATCH_X is free. - */ - .stack1_dummy (NOLOAD): - { - *(.stack1*) - } > SCRATCH_X - .stack_dummy (NOLOAD): - { - KEEP(*(.stack*)) - } > SCRATCH_Y - - .flash_end : { - KEEP(*(.embedded_end_block*)) - PROVIDE(__flash_binary_end = .); - } > FLASH - - /* stack limit is poorly named, but historically is maximum heap ptr */ - __StackLimit = ORIGIN(RAM) + LENGTH(RAM); - __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); - __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); - __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); - __StackBottom = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* picolibc and LLVM */ - PROVIDE (__heap_start = __end__); - PROVIDE (__heap_end = __HeapLimit); - PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); - PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); - PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); - - /* llvm-libc */ - PROVIDE (_end = __end__); - PROVIDE (__llvm_libc_heap_limit = __HeapLimit); - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") - - ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary") - /* todo assert on extra code */ -} - diff --git a/src/rp2_common/pico_crt0/rp2040/memmap_no_flash.ld b/src/rp2_common/pico_crt0/rp2040/memmap_no_flash.ld deleted file mode 100644 index dbf006a8..00000000 --- a/src/rp2_common/pico_crt0/rp2040/memmap_no_flash.ld +++ /dev/null @@ -1,249 +0,0 @@ -/* Based on GCC ARM embedded samples. - Defines the following symbols for use by code: - __exidx_start - __exidx_end - __etext - __data_start__ - __preinit_array_start - __preinit_array_end - __init_array_start - __init_array_end - __fini_array_start - __fini_array_end - __data_end__ - __bss_start__ - __bss_end__ - __end__ - end - __HeapLimit - __StackLimit - __StackTop - __stack (== StackTop) -*/ - -MEMORY -{ - RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k - SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k - SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k -} - -ENTRY(_entry_point) - -SECTIONS -{ - /* Note in NO_FLASH builds the entry point for both the bootrom, and debugger - entry (ELF entry point), are *first* in the image, and the vector table - follows immediately afterward. This is because the bootrom enters RAM - binaries directly at their lowest address (preferring main RAM over XIP - cache-as-SRAM if both are used). - */ - - .text : { - __logical_binary_start = .; - __reset_start = .; - KEEP (*(.reset)) - __reset_end = .; - KEEP (*(.binary_info_header)) - __binary_info_header_end = .; - KEEP (*(.embedded_block)) - __embedded_block_end = .; - . = ALIGN(256); - KEEP (*(.vectors)) - *(.time_critical*) - *(.text*) - . = ALIGN(4); - *(.init) - *(.fini) - /* Pull all c'tors into .text */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - /* Followed by destructors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - *(.eh_frame*) - } > RAM - - .rodata : { - . = ALIGN(4); - *(.rodata*) - . = ALIGN(4); - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) - . = ALIGN(4); - } > RAM - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > RAM - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > RAM - __exidx_end = .; - - /* Machine inspectable binary information */ - . = ALIGN(4); - __binary_info_start = .; - .binary_info : - { - KEEP(*(.binary_info.keep.*)) - *(.binary_info.*) - } > RAM - __binary_info_end = .; - . = ALIGN(4); - - .data : { - __data_start__ = .; - *(vtable) - *(.data*) - - . = ALIGN(4); - *(.after_data.*) - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__mutex_array_start = .); - KEEP(*(SORT(.mutex_array.*))) - KEEP(*(.mutex_array)) - PROVIDE_HIDDEN (__mutex_array_end = .); - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(SORT(.preinit_array.*))) - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - *(SORT(.fini_array.*)) - *(.fini_array) - PROVIDE_HIDDEN (__fini_array_end = .); - - *(.jcr) - . = ALIGN(4); - } > RAM - - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; - } > RAM - PROVIDE(__data_end__ = .); - - .uninitialized_data (NOLOAD): { - . = ALIGN(4); - *(.uninitialized_data*) - } > RAM - /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ - __etext = LOADADDR(.data); - - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - - .bss (NOLOAD) : { - . = ALIGN(4); - __tbss_end = .; - - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .heap (NOLOAD): - { - __end__ = .; - end = __end__; - KEEP(*(.heap*)) - } > RAM - /* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however - to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */ - __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); - - /* Start and end symbols must be word-aligned */ - .scratch_x : { - __scratch_x_start__ = .; - *(.scratch_x.*) - . = ALIGN(4); - __scratch_x_end__ = .; - } > SCRATCH_X - __scratch_x_source__ = LOADADDR(.scratch_x); - - .scratch_y : { - __scratch_y_start__ = .; - *(.scratch_y.*) - . = ALIGN(4); - __scratch_y_end__ = .; - } > SCRATCH_Y - __scratch_y_source__ = LOADADDR(.scratch_y); - - /* .stack*_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later - * - * stack1 section may be empty/missing if platform_launch_core1 is not used */ - - /* by default we put core 0 stack at the end of scratch Y, so that if core 1 - * stack is not used then all of SCRATCH_X is free. - */ - .stack1_dummy (NOLOAD): - { - *(.stack1*) - } > SCRATCH_X - .stack_dummy (NOLOAD): - { - KEEP(*(.stack*)) - } > SCRATCH_Y - - /* stack limit is poorly named, but historically is maximum heap ptr */ - __StackLimit = ORIGIN(RAM) + LENGTH(RAM); - __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); - __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); - __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); - __StackBottom = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* picolibc and LLVM */ - PROVIDE (__heap_start = __end__); - PROVIDE (__heap_end = __HeapLimit); - PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); - PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); - PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); - - /* llvm-libc */ - PROVIDE (_end = __end__); - PROVIDE (__llvm_libc_heap_limit = __HeapLimit); - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") - - ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary") - /* todo assert on extra code */ -} - diff --git a/src/rp2_common/pico_crt0/rp2350/memmap_copy_to_ram.ld b/src/rp2_common/pico_crt0/rp2350/memmap_copy_to_ram.ld deleted file mode 100644 index 44c69f3b..00000000 --- a/src/rp2_common/pico_crt0/rp2350/memmap_copy_to_ram.ld +++ /dev/null @@ -1,309 +0,0 @@ -/* Based on GCC ARM embedded samples. - Defines the following symbols for use by code: - __exidx_start - __exidx_end - __etext - __data_start__ - __preinit_array_start - __preinit_array_end - __init_array_start - __init_array_end - __fini_array_start - __fini_array_end - __data_end__ - __bss_start__ - __bss_end__ - __end__ - end - __HeapLimit - __StackLimit - __StackTop - __stack (== StackTop) -*/ - -MEMORY -{ - INCLUDE "pico_flash_region.ld" - RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 512k - SCRATCH_X(rwx) : ORIGIN = 0x20080000, LENGTH = 4k - SCRATCH_Y(rwx) : ORIGIN = 0x20081000, LENGTH = 4k -} - -ENTRY(_entry_point) - -SECTIONS -{ - /* On Arm, the bootrom expects a VT at the start of the - image by default; on RISC-V, the default is to enter the image at its - lowest address, so an IMAGE_DEF item is required to specify the - nondefault entry point. */ - - .flash_begin : { - __flash_binary_start = .; - } > FLASH - - /* The bootrom will enter the image at the point indicated in your - IMAGE_DEF, which is usually the reset handler of your vector table. - - The debugger will use the ELF entry point, which is the _entry_point - symbol, and in our case is *different from the bootrom's entry point.* - This is used to go back through the bootrom on debugger launches only, - to perform the same initial flash setup that would be performed on a - cold boot. - */ - - .flashtext : { - __logical_binary_start = .; - KEEP (*(.vectors)) - KEEP (*(.binary_info_header)) - __binary_info_header_end = .; - KEEP (*(.embedded_block)) - __embedded_block_end = .; - KEEP (*(.reset)) - . = ALIGN(4); - } > FLASH - - /* Note the boot2 section is optional, and should be discarded if there is - no reference to it *inside* the binary, as it is not called by the - bootrom. (The bootrom performs a simple best-effort XIP setup and - leaves it to the binary to do anything more sophisticated.) However - there is still a size limit of 256 bytes, to ensure the boot2 can be - stored in boot RAM. - - Really this is a "XIP setup function" -- the name boot2 is historic and - refers to its dual-purpose on RP2040, where it also handled vectoring - from the bootrom into the user image. - */ - - .boot2 : { - __boot2_start__ = .; - *(.boot2) - __boot2_end__ = .; - } > FLASH - - ASSERT(__boot2_end__ - __boot2_start__ <= 256, - "ERROR: Pico second stage bootloader must be no more than 256 bytes in size") - - .rodata : { - /* segments not marked as .flashdata are instead pulled into .data (in RAM) to avoid accidental flash accesses */ - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) - . = ALIGN(4); - } > FLASH - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > FLASH - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > FLASH - __exidx_end = .; - - /* Machine inspectable binary information */ - . = ALIGN(4); - __binary_info_start = .; - .binary_info : - { - KEEP(*(.binary_info.keep.*)) - *(.binary_info.*) - } > FLASH - __binary_info_end = .; - . = ALIGN(4); - - /* Vector table goes first in RAM, to avoid large alignment hole */ - .ram_vector_table (NOLOAD): { - *(.ram_vector_table) - } > RAM - - .uninitialized_data (NOLOAD): { - . = ALIGN(4); - *(.uninitialized_data*) - } > RAM - - .text : { - __ram_text_start__ = .; - *(.init) - *(.text*) - *(.fini) - /* Pull all c'tors into .text */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - /* Followed by destructors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - *(.eh_frame*) - . = ALIGN(4); - __ram_text_end__ = .; - } > RAM AT> FLASH - __ram_text_source__ = LOADADDR(.text); - . = ALIGN(4); - - .data : { - __data_start__ = .; - *(vtable) - - *(.time_critical*) - - . = ALIGN(4); - *(.rodata*) - *(.srodata*) - . = ALIGN(4); - - *(.data*) - *(.sdata*) - - . = ALIGN(4); - *(.after_data.*) - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__mutex_array_start = .); - KEEP(*(SORT(.mutex_array.*))) - KEEP(*(.mutex_array)) - PROVIDE_HIDDEN (__mutex_array_end = .); - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(SORT(.preinit_array.*))) - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - *(SORT(.fini_array.*)) - *(.fini_array) - PROVIDE_HIDDEN (__fini_array_end = .); - - *(.jcr) - . = ALIGN(4); - } > RAM AT> FLASH - - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; - } > RAM AT> FLASH - PROVIDE(__data_end__ = .); - - /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ - __etext = LOADADDR(.data); - - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - - .bss : { - . = ALIGN(4); - __tbss_end = .; - - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) - *(COMMON) - PROVIDE(__global_pointer$ = . + 2K); - *(.sbss*) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .heap (NOLOAD): - { - __end__ = .; - end = __end__; - KEEP(*(.heap*)) - } > RAM - /* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however - to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */ - __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); - - /* Start and end symbols must be word-aligned */ - .scratch_x : { - __scratch_x_start__ = .; - *(.scratch_x.*) - . = ALIGN(4); - __scratch_x_end__ = .; - } > SCRATCH_X AT > FLASH - __scratch_x_source__ = LOADADDR(.scratch_x); - - .scratch_y : { - __scratch_y_start__ = .; - *(.scratch_y.*) - . = ALIGN(4); - __scratch_y_end__ = .; - } > SCRATCH_Y AT > FLASH - __scratch_y_source__ = LOADADDR(.scratch_y); - - /* .stack*_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later - * - * stack1 section may be empty/missing if platform_launch_core1 is not used */ - - /* by default we put core 0 stack at the end of scratch Y, so that if core 1 - * stack is not used then all of SCRATCH_X is free. - */ - .stack1_dummy (NOLOAD): - { - *(.stack1*) - } > SCRATCH_X - .stack_dummy (NOLOAD): - { - KEEP(*(.stack*)) - } > SCRATCH_Y - - .flash_end : { - KEEP(*(.embedded_end_block*)) - PROVIDE(__flash_binary_end = .); - } > FLASH =0xaa - - /* stack limit is poorly named, but historically is maximum heap ptr */ - __StackLimit = ORIGIN(RAM) + LENGTH(RAM); - __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); - __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); - __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); - __StackBottom = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* picolibc and LLVM */ - PROVIDE (__heap_start = __end__); - PROVIDE (__heap_end = __HeapLimit); - PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); - PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); - PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); - - /* llvm-libc */ - PROVIDE (_end = __end__); - PROVIDE (__llvm_libc_heap_limit = __HeapLimit); - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") - - ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary") - ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary") - - /* todo assert on extra code */ -} - diff --git a/src/rp2_common/pico_crt0/rp2350/memmap_default.ld b/src/rp2_common/pico_crt0/rp2350/memmap_default.ld deleted file mode 100644 index bce316d1..00000000 --- a/src/rp2_common/pico_crt0/rp2350/memmap_default.ld +++ /dev/null @@ -1,302 +0,0 @@ -/* Based on GCC ARM embedded samples. - Defines the following symbols for use by code: - __exidx_start - __exidx_end - __etext - __data_start__ - __preinit_array_start - __preinit_array_end - __init_array_start - __init_array_end - __fini_array_start - __fini_array_end - __data_end__ - __bss_start__ - __bss_end__ - __end__ - end - __HeapLimit - __StackLimit - __StackTop - __stack (== StackTop) -*/ - -MEMORY -{ - INCLUDE "pico_flash_region.ld" - RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 512k - SCRATCH_X(rwx) : ORIGIN = 0x20080000, LENGTH = 4k - SCRATCH_Y(rwx) : ORIGIN = 0x20081000, LENGTH = 4k -} - -ENTRY(_entry_point) - -SECTIONS -{ - .flash_begin : { - __flash_binary_start = .; - } > FLASH - - /* The bootrom will enter the image at the point indicated in your - IMAGE_DEF, which is usually the reset handler of your vector table. - - The debugger will use the ELF entry point, which is the _entry_point - symbol, and in our case is *different from the bootrom's entry point.* - This is used to go back through the bootrom on debugger launches only, - to perform the same initial flash setup that would be performed on a - cold boot. - */ - - .text : { - __logical_binary_start = .; - KEEP (*(.vectors)) - KEEP (*(.binary_info_header)) - __binary_info_header_end = .; - KEEP (*(.embedded_block)) - __embedded_block_end = .; - KEEP (*(.reset)) - /* TODO revisit this now memset/memcpy/float in ROM */ - /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from - * FLASH ... we will include any thing excluded here in .data below by default */ - *(.init) - *libgcc.a:cmse_nonsecure_call.o - *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) - *(.fini) - /* Pull all c'tors into .text */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - /* Followed by destructors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(SORT(.preinit_array.*))) - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - *(SORT(.fini_array.*)) - *(.fini_array) - PROVIDE_HIDDEN (__fini_array_end = .); - - *(.eh_frame*) - . = ALIGN(4); - } > FLASH - - /* Note the boot2 section is optional, and should be discarded if there is - no reference to it *inside* the binary, as it is not called by the - bootrom. (The bootrom performs a simple best-effort XIP setup and - leaves it to the binary to do anything more sophisticated.) However - there is still a size limit of 256 bytes, to ensure the boot2 can be - stored in boot RAM. - - Really this is a "XIP setup function" -- the name boot2 is historic and - refers to its dual-purpose on RP2040, where it also handled vectoring - from the bootrom into the user image. - */ - - .boot2 : { - __boot2_start__ = .; - *(.boot2) - __boot2_end__ = .; - } > FLASH - - ASSERT(__boot2_end__ - __boot2_start__ <= 256, - "ERROR: Pico second stage bootloader must be no more than 256 bytes in size") - - .rodata : { - *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*) - *(.srodata*) - . = ALIGN(4); - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) - . = ALIGN(4); - } > FLASH - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > FLASH - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > FLASH - __exidx_end = .; - - /* Machine inspectable binary information */ - . = ALIGN(4); - __binary_info_start = .; - .binary_info : - { - KEEP(*(.binary_info.keep.*)) - *(.binary_info.*) - } > FLASH - __binary_info_end = .; - . = ALIGN(4); - - .ram_vector_table (NOLOAD): { - *(.ram_vector_table) - } > RAM - - .uninitialized_data (NOLOAD): { - . = ALIGN(4); - *(.uninitialized_data*) - } > RAM - - .data : { - __data_start__ = .; - *(vtable) - - *(.time_critical*) - - /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */ - *(.text*) - . = ALIGN(4); - *(.rodata*) - . = ALIGN(4); - - *(.data*) - *(.sdata*) - - . = ALIGN(4); - *(.after_data.*) - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__mutex_array_start = .); - KEEP(*(SORT(.mutex_array.*))) - KEEP(*(.mutex_array)) - PROVIDE_HIDDEN (__mutex_array_end = .); - - *(.jcr) - . = ALIGN(4); - } > RAM AT> FLASH - - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; - } > RAM AT> FLASH - PROVIDE(__data_end__ = .); - - /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ - __etext = LOADADDR(.data); - - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - - .bss (NOLOAD) : { - . = ALIGN(4); - __tbss_end = .; - - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) - *(COMMON) - PROVIDE(__global_pointer$ = . + 2K); - *(.sbss*) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .heap (NOLOAD): - { - __end__ = .; - end = __end__; - KEEP(*(.heap*)) - } > RAM - /* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however - to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */ - __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); - - /* Start and end symbols must be word-aligned */ - .scratch_x : { - __scratch_x_start__ = .; - *(.scratch_x.*) - . = ALIGN(4); - __scratch_x_end__ = .; - } > SCRATCH_X AT > FLASH - __scratch_x_source__ = LOADADDR(.scratch_x); - - .scratch_y : { - __scratch_y_start__ = .; - *(.scratch_y.*) - . = ALIGN(4); - __scratch_y_end__ = .; - } > SCRATCH_Y AT > FLASH - __scratch_y_source__ = LOADADDR(.scratch_y); - - /* .stack*_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later - * - * stack1 section may be empty/missing if platform_launch_core1 is not used */ - - /* by default we put core 0 stack at the end of scratch Y, so that if core 1 - * stack is not used then all of SCRATCH_X is free. - */ - .stack1_dummy (NOLOAD): - { - *(.stack1*) - } > SCRATCH_X - .stack_dummy (NOLOAD): - { - KEEP(*(.stack*)) - } > SCRATCH_Y - - .flash_end : { - KEEP(*(.embedded_end_block*)) - PROVIDE(__flash_binary_end = .); - } > FLASH =0xaa - - /* stack limit is poorly named, but historically is maximum heap ptr */ - __StackLimit = ORIGIN(RAM) + LENGTH(RAM); - __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); - __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); - __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); - __StackBottom = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* picolibc and LLVM */ - PROVIDE (__heap_start = __end__); - PROVIDE (__heap_end = __HeapLimit); - PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); - PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); - PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); - - /* llvm-libc */ - PROVIDE (_end = __end__); - PROVIDE (__llvm_libc_heap_limit = __HeapLimit); - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") - - ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary") - ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary") - - /* todo assert on extra code */ -} - diff --git a/src/rp2_common/pico_crt0/rp2350/memmap_no_flash.ld b/src/rp2_common/pico_crt0/rp2350/memmap_no_flash.ld deleted file mode 100644 index 5bedf6d2..00000000 --- a/src/rp2_common/pico_crt0/rp2350/memmap_no_flash.ld +++ /dev/null @@ -1,256 +0,0 @@ -/* Based on GCC ARM embedded samples. - Defines the following symbols for use by code: - __exidx_start - __exidx_end - __etext - __data_start__ - __preinit_array_start - __preinit_array_end - __init_array_start - __init_array_end - __fini_array_start - __fini_array_end - __data_end__ - __bss_start__ - __bss_end__ - __end__ - end - __HeapLimit - __StackLimit - __StackTop - __stack (== StackTop) -*/ - -MEMORY -{ - RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 512k - SCRATCH_X(rwx) : ORIGIN = 0x20080000, LENGTH = 4k - SCRATCH_Y(rwx) : ORIGIN = 0x20081000, LENGTH = 4k -} - -ENTRY(_entry_point) - -SECTIONS -{ - /* Note unlike RP2040, we start the image with a vector table even for - NO_FLASH builds. On Arm, the bootrom expects a VT at the start of the - image by default; on RISC-V, the default is to enter the image at its - lowest address, so an IMAGE_DEF item is required to specify the - nondefault entry point. */ - - .text : { - __logical_binary_start = .; - /* Vectors require 512-byte alignment on v8-M when >48 IRQs are used, - so we would waste RAM if the vector table were not at the - start. */ - KEEP (*(.vectors)) - KEEP (*(.binary_info_header)) - __binary_info_header_end = .; - KEEP (*(.embedded_block)) - __embedded_block_end = .; - __reset_start = .; - KEEP (*(.reset)) - __reset_end = .; - *(.time_critical*) - *(.text*) - . = ALIGN(4); - *(.init) - *(.fini) - /* Pull all c'tors into .text */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - /* Followed by destructors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - *(.eh_frame*) - } > RAM - - .rodata : { - . = ALIGN(4); - *(.rodata*) - *(.srodata*) - . = ALIGN(4); - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) - . = ALIGN(4); - } > RAM - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > RAM - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > RAM - __exidx_end = .; - - /* Machine inspectable binary information */ - . = ALIGN(4); - __binary_info_start = .; - .binary_info : - { - KEEP(*(.binary_info.keep.*)) - *(.binary_info.*) - } > RAM - __binary_info_end = .; - . = ALIGN(4); - - .data : { - __data_start__ = .; - *(vtable) - *(.data*) - *(.sdata*) - - . = ALIGN(4); - *(.after_data.*) - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__mutex_array_start = .); - KEEP(*(SORT(.mutex_array.*))) - KEEP(*(.mutex_array)) - PROVIDE_HIDDEN (__mutex_array_end = .); - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(SORT(.preinit_array.*))) - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - *(SORT(.fini_array.*)) - *(.fini_array) - PROVIDE_HIDDEN (__fini_array_end = .); - - *(.jcr) - . = ALIGN(4); - } > RAM - - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; - } > RAM - PROVIDE(__data_end__ = .); - - .uninitialized_data (NOLOAD): { - . = ALIGN(4); - *(.uninitialized_data*) - } > RAM - /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ - __etext = LOADADDR(.data); - - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - - .bss (NOLOAD) : { - . = ALIGN(4); - __tbss_end = .; - - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) - *(COMMON) - PROVIDE(__global_pointer$ = . + 2K); - *(.sbss*) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .heap (NOLOAD): - { - __end__ = .; - end = __end__; - KEEP(*(.heap*)) - } > RAM - /* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however - to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */ - __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); - - /* Start and end symbols must be word-aligned */ - .scratch_x : { - __scratch_x_start__ = .; - *(.scratch_x.*) - . = ALIGN(4); - __scratch_x_end__ = .; - } > SCRATCH_X - __scratch_x_source__ = LOADADDR(.scratch_x); - - .scratch_y : { - __scratch_y_start__ = .; - *(.scratch_y.*) - . = ALIGN(4); - __scratch_y_end__ = .; - } > SCRATCH_Y - __scratch_y_source__ = LOADADDR(.scratch_y); - - /* .stack*_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later - * - * stack1 section may be empty/missing if platform_launch_core1 is not used */ - - /* by default we put core 0 stack at the end of scratch Y, so that if core 1 - * stack is not used then all of SCRATCH_X is free. - */ - .stack1_dummy (NOLOAD): - { - *(.stack1*) - } > SCRATCH_X - .stack_dummy (NOLOAD): - { - KEEP(*(.stack*)) - } > SCRATCH_Y - - /* stack limit is poorly named, but historically is maximum heap ptr */ - __StackLimit = ORIGIN(RAM) + LENGTH(RAM); - __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); - __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); - __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); - __StackBottom = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* picolibc and LLVM */ - PROVIDE (__heap_start = __end__); - PROVIDE (__heap_end = __HeapLimit); - PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); - PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); - PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); - - /* llvm-libc */ - PROVIDE (_end = __end__); - PROVIDE (__llvm_libc_heap_limit = __HeapLimit); - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") - - ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary") - ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary") - - /* todo assert on extra code */ -} - diff --git a/src/rp2_common/pico_standard_link/BUILD.bazel b/src/rp2_common/pico_standard_link/BUILD.bazel index 4c8ff249..924358d5 100644 --- a/src/rp2_common/pico_standard_link/BUILD.bazel +++ b/src/rp2_common/pico_standard_link/BUILD.bazel @@ -18,6 +18,50 @@ generated_pico_flash_region( }), ) +# It's possible to set linker scripts globally or on a per-binary basis. +# +# Setting globally: +# * Set --@pico-sdk//bazel/config:PICO_DEFAULT_LINKER_SCRIPT to point to your +# desired linker script (eg @pico-sdk//src/pico_standard_link:no_flash_linker_script) +# +# Setting per-binary: +# * Set --@pico-sdk//bazel/config:PICO_DEFAULT_LINKER_SCRIPT=@pico-sdk//bazel:empty_cc_lib +# * Manually add your desired linker script to each cc_binary. +alias( + name = "default_linker_script", + actual = select({ + "//bazel/constraint:rp2040": "//src/rp2040/pico_platform_link:default_linker_script", + "//bazel/constraint:rp2350": "//src/rp2350/pico_platform_link:default_linker_script", + "//conditions:default": "//bazel:incompatible_cc_lib", + }), +) + +alias( + name = "blocked_ram_linker_script", + actual = select({ + "//bazel/constraint:rp2040": "//src/rp2040/pico_platform_link:blocked_ram_linker_script", + "//conditions:default": "//bazel:incompatible_cc_lib", + }), +) + +alias( + name = "copy_to_ram_linker_script", + actual = select({ + "//bazel/constraint:rp2040": "//src/rp2040/pico_platform_link:copy_to_ram_linker_script", + "//bazel/constraint:rp2350": "//src/rp2350/pico_platform_link:copy_to_ram_linker_script", + "//conditions:default": "//bazel:incompatible_cc_lib", + }), +) + +alias( + name = "no_flash_linker_script", + actual = select({ + "//bazel/constraint:rp2040": "//src/rp2040/pico_platform_link:no_flash_linker_script", + "//bazel/constraint:rp2350": "//src/rp2350/pico_platform_link:no_flash_linker_script", + "//conditions:default": "//bazel:incompatible_cc_lib", + }), +) + cc_library( name = "pico_standard_link", target_compatible_with = compatible_with_rp2(), diff --git a/src/rp2_common/pico_standard_link/CMakeLists.txt b/src/rp2_common/pico_standard_link/CMakeLists.txt index c16968bb..d1ae1cd2 100644 --- a/src/rp2_common/pico_standard_link/CMakeLists.txt +++ b/src/rp2_common/pico_standard_link/CMakeLists.txt @@ -70,6 +70,36 @@ if (NOT TARGET pico_standard_link) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_LINKER_SCRIPT ${LDSCRIPT}) endfunction() + # pico_set_linker_script_var(TARGET NAME VALUE) + # \brief\ Set the linker script for the target + # + # \param\ NAME Name of variable to set + # \param\ VALUE Value of variable to set + function(pico_set_linker_script_var TARGET NAME VALUE) + set_property(TARGET ${TARGET} APPEND PROPERTY PICO_TARGET_LINKER_SCRIPT_VARS "--defsym=${NAME}=${VALUE}") + endfunction() + + # pico_add_linker_script_override_path(TARGET PATH) + # \brief\ Add an override linker script path to the target + # + # This can be used to override default linker script files with custom versions. + # + # For example, to use custom files in ${CMAKE_CURRENT_LIST_DIR}/extra_scripts instead of the default ones, + # call pico_add_linker_script_override_path(TARGET ${CMAKE_CURRENT_LIST_DIR}/extra_scripts). This will + # include the custom files first, overriding the default ones. + # + # Must be called before target_link_libraries, otherwise it will not override the default linker scripts. + # + # \param\ TARGET The target to add the linker script override path to + # \param\ PATH The path containing the overriding linker scripts + function(pico_add_linker_script_override_path TARGET PATH) + get_target_property(OUT ${TARGET} LINK_LIBRARIES) + if (OUT) + message(WARNING "pico_add_linker_script_override_path does not work when called after target_link_libraries") + endif() + target_link_options(${TARGET} PRIVATE "LINKER:-L${PATH}") + endfunction() + # pico_set_binary_type(TARGET TYPE) # \brief\ Set the binary type for the target # @@ -124,9 +154,19 @@ if (NOT TARGET pico_standard_link) #math(EXPR PICO_FLASH_SIZE_BYTES_STRING "${PICO_FLASH_SIZE_BYTES}" OUTPUT_FORMAT HEXADECIMAL) set(PICO_FLASH_SIZE_BYTES_STRING "${PICO_FLASH_SIZE_BYTES}") configure_file(${CMAKE_CURRENT_LIST_DIR}/pico_flash_region.template.ld ${CMAKE_BINARY_DIR}/pico_flash_region.ld) - # add include path for linker scripts + # add include path for linker scripts to find it target_link_options(pico_standard_link INTERFACE "LINKER:-L${CMAKE_BINARY_DIR}") + # add include path for main linker script sections + target_link_options(pico_standard_link INTERFACE "LINKER:-L${PICO_LINKER_SCRIPT_PATH}/platform_scripts") + target_link_options(pico_standard_link INTERFACE "LINKER:-L${CMAKE_CURRENT_LIST_DIR}/standard_scripts") + + # add default locations script, so they can be referenced by pico_set_linker_script_var variables + target_link_options(pico_standard_link INTERFACE "LINKER:--script=${PICO_LINKER_SCRIPT_PATH}/platform_scripts/default_locations.ld") + + # add variables set by pico_set_linker_script_var function + target_link_options(pico_standard_link INTERFACE "LINKER:$,,>") + # LINKER script will be PICO_TARGET_LINKER_SCRIPT if set on target, or ${CMAKE_CURRENT_LIST_DIR}/memmap_foo.ld # if PICO_TARGET_BINARY_TYPE is set to foo on the target, otherwise ${CMAKE_CURRENT_LIST_DIR}/memmap_${PICO_DEFAULT_BINARY_TYPE).ld set(_LINKER_SCRIPT_EXPRESSION "$>,$,${PICO_LINKER_SCRIPT_PATH}/memmap_$,>,${PICO_DEFAULT_BINARY_TYPE},$>.ld>") diff --git a/src/rp2_common/pico_standard_link/standard_scripts/BUILD.bazel b/src/rp2_common/pico_standard_link/standard_scripts/BUILD.bazel new file mode 100644 index 00000000..04a1af5d --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/BUILD.bazel @@ -0,0 +1,68 @@ +load("@rules_cc//cc:cc_library.bzl", "cc_library") +load("//bazel:defs.bzl", "compatible_with_rp2") +load("//bazel/util:pico_linker_scripts.bzl", "include_linker_script_dir") + +package(default_visibility = ["//visibility:public"]) + +exports_files( + [ + "memory_aliases_default.ld", + "memory_aliases_no_flash.ld", + "memory_flash.ld", + "memory_ram.ld", + "memory_scratch.ld", + "memory_xip_ram.ld", + "section_copy_to_ram_data.ld", + "section_copy_to_ram_text.ld", + "section_default_data.ld", + "section_default_text.ld", + "section_end.ld", + "section_flash_end.ld", + "section_heap.ld", + "section_no_flash_data.ld", + "section_no_flash_text.ld", + "sections_copy_to_ram.ld", + "section_scratch.ld", + "sections_default.ld", + "sections_no_flash.ld", + "set_memory_locations.ld", + "memmap_default.ld", + "memmap_no_flash.ld", + "memmap_copy_to_ram.ld", + ] +) + +include_linker_script_dir( + name = "rp2_linker_script_args", +) + +cc_library( + name = "rp2_linker_scripts", + target_compatible_with = compatible_with_rp2(), + deps = [ + "rp2_linker_script_args", + "memory_aliases_default.ld", + "memory_aliases_no_flash.ld", + "memory_flash.ld", + "memory_ram.ld", + "memory_scratch.ld", + "memory_xip_ram.ld", + "section_copy_to_ram_data.ld", + "section_copy_to_ram_text.ld", + "section_default_data.ld", + "section_default_text.ld", + "section_end.ld", + "section_flash_end.ld", + "section_heap.ld", + "section_no_flash_data.ld", + "section_no_flash_text.ld", + "sections_copy_to_ram.ld", + "section_scratch.ld", + "sections_default.ld", + "sections_no_flash.ld", + "set_memory_locations.ld", + "memmap_default.ld", + "memmap_no_flash.ld", + "memmap_copy_to_ram.ld", + ], +) \ No newline at end of file diff --git a/src/rp2_common/pico_standard_link/standard_scripts/memmap_copy_to_ram.ld b/src/rp2_common/pico_standard_link/standard_scripts/memmap_copy_to_ram.ld new file mode 100644 index 00000000..eb2c5ffd --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/memmap_copy_to_ram.ld @@ -0,0 +1,16 @@ +/* Include platform memory locations */ +INCLUDE "set_memory_locations.ld" + +/* Include memory regions used */ +INCLUDE "memory_flash.ld" +INCLUDE "memory_ram.ld" +INCLUDE "memory_scratch.ld" + +/* Include aliases for storage memory regions */ +INCLUDE "memory_aliases_default.ld" + +/* Define entry point symbol */ +ENTRY(_entry_point) + +/* Include default sections */ +INCLUDE "sections_copy_to_ram.ld" diff --git a/src/rp2_common/pico_standard_link/standard_scripts/memmap_default.ld b/src/rp2_common/pico_standard_link/standard_scripts/memmap_default.ld new file mode 100644 index 00000000..04acbefb --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/memmap_default.ld @@ -0,0 +1,16 @@ +/* Include platform memory locations */ +INCLUDE "set_memory_locations.ld" + +/* Include memory regions used */ +INCLUDE "memory_flash.ld" +INCLUDE "memory_ram.ld" +INCLUDE "memory_scratch.ld" + +/* Include aliases for storage memory regions */ +INCLUDE "memory_aliases_default.ld" + +/* Define entry point symbol */ +ENTRY(_entry_point) + +/* Include default sections */ +INCLUDE "sections_default.ld" diff --git a/src/rp2_common/pico_standard_link/standard_scripts/memmap_no_flash.ld b/src/rp2_common/pico_standard_link/standard_scripts/memmap_no_flash.ld new file mode 100644 index 00000000..958915a7 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/memmap_no_flash.ld @@ -0,0 +1,15 @@ +/* Include platform memory locations */ +INCLUDE "set_memory_locations.ld" + +/* Include memory regions used */ +INCLUDE "memory_ram.ld" +INCLUDE "memory_scratch.ld" + +/* Include aliases for no_flash storage memory regions (alias to themselves) */ +INCLUDE "memory_aliases_no_flash.ld" + +/* Define entry point symbol */ +ENTRY(_entry_point) + +/* Include no_flash sections */ +INCLUDE "sections_no_flash.ld" diff --git a/src/rp2_common/pico_standard_link/standard_scripts/memory_aliases_default.ld b/src/rp2_common/pico_standard_link/standard_scripts/memory_aliases_default.ld new file mode 100644 index 00000000..7c56254b --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/memory_aliases_default.ld @@ -0,0 +1,3 @@ +REGION_ALIAS("RAM_STORE", FLASH); +REGION_ALIAS("SCRATCH_X_STORE", FLASH); +REGION_ALIAS("SCRATCH_Y_STORE", FLASH); diff --git a/src/rp2_common/pico_standard_link/standard_scripts/memory_aliases_no_flash.ld b/src/rp2_common/pico_standard_link/standard_scripts/memory_aliases_no_flash.ld new file mode 100644 index 00000000..063b5b6f --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/memory_aliases_no_flash.ld @@ -0,0 +1,3 @@ +REGION_ALIAS("RAM_STORE", RAM); +REGION_ALIAS("SCRATCH_X_STORE", SCRATCH_X); +REGION_ALIAS("SCRATCH_Y_STORE", SCRATCH_Y); diff --git a/src/rp2_common/pico_standard_link/standard_scripts/memory_flash.ld b/src/rp2_common/pico_standard_link/standard_scripts/memory_flash.ld new file mode 100644 index 00000000..669fe00e --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/memory_flash.ld @@ -0,0 +1,4 @@ +MEMORY +{ + INCLUDE "pico_flash_region.ld" +} diff --git a/src/rp2_common/pico_standard_link/standard_scripts/memory_ram.ld b/src/rp2_common/pico_standard_link/standard_scripts/memory_ram.ld new file mode 100644 index 00000000..2b8a88a0 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/memory_ram.ld @@ -0,0 +1,4 @@ +MEMORY +{ + RAM(rwx) : ORIGIN = RAM_ORIGIN, LENGTH = RAM_LENGTH +} diff --git a/src/rp2_common/pico_standard_link/standard_scripts/memory_scratch.ld b/src/rp2_common/pico_standard_link/standard_scripts/memory_scratch.ld new file mode 100644 index 00000000..7ba5d217 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/memory_scratch.ld @@ -0,0 +1,5 @@ +MEMORY +{ + SCRATCH_X(rwx) : ORIGIN = SCRATCH_X_ORIGIN, LENGTH = SCRATCH_X_LENGTH + SCRATCH_Y(rwx) : ORIGIN = SCRATCH_Y_ORIGIN, LENGTH = SCRATCH_Y_LENGTH +} diff --git a/src/rp2_common/pico_standard_link/standard_scripts/memory_xip_ram.ld b/src/rp2_common/pico_standard_link/standard_scripts/memory_xip_ram.ld new file mode 100644 index 00000000..636e9013 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/memory_xip_ram.ld @@ -0,0 +1,4 @@ +MEMORY +{ + XIP_RAM(rwx) : ORIGIN = XIP_RAM_ORIGIN, LENGTH = XIP_RAM_LENGTH +} diff --git a/src/rp2_common/pico_standard_link/standard_scripts/section_copy_to_ram_data.ld b/src/rp2_common/pico_standard_link/standard_scripts/section_copy_to_ram_data.ld new file mode 100644 index 00000000..19082589 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/section_copy_to_ram_data.ld @@ -0,0 +1,83 @@ +SECTIONS +{ + .data : { + __data_start__ = .; + *(vtable) + + *(.time_critical*) + + . = ALIGN(4); + *(.rodata*) + *(.srodata*) + . = ALIGN(4); + + *(.data*) + *(.sdata*) + + . = ALIGN(4); + *(.after_data.*) + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__mutex_array_start = .); + KEEP(*(SORT(.mutex_array.*))) + KEEP(*(.mutex_array)) + PROVIDE_HIDDEN (__mutex_array_end = .); + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(SORT(.preinit_array.*))) + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.jcr) + . = ALIGN(4); + } > RAM AT> FLASH + + .tdata : { + . = ALIGN(4); + *(.tdata .tdata.* .gnu.linkonce.td.*) + /* All data end */ + __tdata_end = .; + } > RAM AT> FLASH + PROVIDE(__data_end__ = .); + + /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ + __etext = LOADADDR(.data); + + .tbss (NOLOAD) : { + . = ALIGN(4); + __bss_start__ = .; + __tls_base = .; + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + + __tls_end = .; + } > RAM + + .bss : { + . = ALIGN(4); + __tbss_end = .; + + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) + *(COMMON) + PROVIDE(__global_pointer$ = . + 2K); + *(.sbss*) + . = ALIGN(4); + __bss_end__ = .; + } > RAM +} diff --git a/src/rp2_common/pico_standard_link/standard_scripts/section_copy_to_ram_text.ld b/src/rp2_common/pico_standard_link/standard_scripts/section_copy_to_ram_text.ld new file mode 100644 index 00000000..d35f7209 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/section_copy_to_ram_text.ld @@ -0,0 +1,117 @@ +SECTIONS +{ + /* On Arm, the bootrom expects a VT at the start of the + image by default; on RISC-V, the default is to enter the image at its + lowest address, so an IMAGE_DEF item is required to specify the + nondefault entry point. */ + + .flash_begin : { + __flash_binary_start = .; + } > FLASH + + /* The bootrom will enter the image at the point indicated in your + IMAGE_DEF, which is usually the reset handler of your vector table. + + The debugger will use the ELF entry point, which is the _entry_point + symbol, and in our case is *different from the bootrom's entry point.* + This is used to go back through the bootrom on debugger launches only, + to perform the same initial flash setup that would be performed on a + cold boot. + */ + + .flashtext : { + __logical_binary_start = .; + KEEP (*(.vectors)) + KEEP (*(.binary_info_header)) + __binary_info_header_end = .; + KEEP (*(.embedded_block)) + __embedded_block_end = .; + KEEP (*(.reset)) + . = ALIGN(4); + } > FLASH + + /* Note the boot2 section is optional, and should be discarded if there is + no reference to it *inside* the binary, as it is not called by the + bootrom. (The bootrom performs a simple best-effort XIP setup and + leaves it to the binary to do anything more sophisticated.) However + there is still a size limit of 256 bytes, to ensure the boot2 can be + stored in boot RAM. + + Really this is a "XIP setup function" -- the name boot2 is historic and + refers to its dual-purpose on RP2040, where it also handled vectoring + from the bootrom into the user image. + */ + + .boot2 : { + __boot2_start__ = .; + *(.boot2) + __boot2_end__ = .; + } > FLASH + + ASSERT(__boot2_end__ - __boot2_start__ <= 256, + "ERROR: Pico second stage bootloader must be no more than 256 bytes in size") + + .rodata : { + /* segments not marked as .flashdata are instead pulled into .data (in RAM) to avoid accidental flash accesses */ + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) + . = ALIGN(4); + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* Machine inspectable binary information */ + . = ALIGN(4); + __binary_info_start = .; + .binary_info : + { + KEEP(*(.binary_info.keep.*)) + *(.binary_info.*) + } > FLASH + __binary_info_end = .; + . = ALIGN(4); + + /* Vector table goes first in RAM, to avoid large alignment hole */ + .ram_vector_table (NOLOAD): { + *(.ram_vector_table) + } > RAM + + .uninitialized_data (NOLOAD): { + . = ALIGN(4); + *(.uninitialized_data*) + } > RAM + + .text : { + __ram_text_start__ = .; + *(.init) + *(.text*) + *(.fini) + /* Pull all c'tors into .text */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + /* Followed by destructors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.eh_frame*) + . = ALIGN(4); + __ram_text_end__ = .; + } > RAM AT> FLASH + __ram_text_source__ = LOADADDR(.text); + . = ALIGN(4); +} diff --git a/src/rp2_common/pico_standard_link/standard_scripts/section_default_data.ld b/src/rp2_common/pico_standard_link/standard_scripts/section_default_data.ld new file mode 100644 index 00000000..9ffa5d16 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/section_default_data.ld @@ -0,0 +1,72 @@ +SECTIONS +{ + .ram_vector_table (NOLOAD): { + *(.ram_vector_table) + } > RAM + + .uninitialized_data (NOLOAD): { + . = ALIGN(4); + *(.uninitialized_data*) + } > RAM + + .data : { + __data_start__ = .; + *(vtable) + + *(.time_critical*) + + /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */ + *(.text*) + . = ALIGN(4); + *(.rodata*) + . = ALIGN(4); + + *(.data*) + *(.sdata*) + + . = ALIGN(4); + *(.after_data.*) + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__mutex_array_start = .); + KEEP(*(SORT(.mutex_array.*))) + KEEP(*(.mutex_array)) + PROVIDE_HIDDEN (__mutex_array_end = .); + + *(.jcr) + . = ALIGN(4); + } > RAM AT> FLASH + + .tdata : { + . = ALIGN(4); + *(.tdata .tdata.* .gnu.linkonce.td.*) + /* All data end */ + __tdata_end = .; + } > RAM AT> FLASH + PROVIDE(__data_end__ = .); + + /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ + __etext = LOADADDR(.data); + + .tbss (NOLOAD) : { + . = ALIGN(4); + __bss_start__ = .; + __tls_base = .; + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + + __tls_end = .; + } > RAM + + .bss (NOLOAD) : { + . = ALIGN(4); + __tbss_end = .; + + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) + *(COMMON) + PROVIDE(__global_pointer$ = . + 2K); + *(.sbss*) + . = ALIGN(4); + __bss_end__ = .; + } > RAM +} diff --git a/src/rp2_common/pico_standard_link/standard_scripts/section_default_text.ld b/src/rp2_common/pico_standard_link/standard_scripts/section_default_text.ld new file mode 100644 index 00000000..fdd96332 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/section_default_text.ld @@ -0,0 +1,121 @@ +SECTIONS +{ + .flash_begin : { + __flash_binary_start = .; + } > FLASH + + /* The bootrom will enter the image at the point indicated in your + IMAGE_DEF, which is usually the reset handler of your vector table. + + The debugger will use the ELF entry point, which is the _entry_point + symbol, and in our case is *different from the bootrom's entry point.* + This is used to go back through the bootrom on debugger launches only, + to perform the same initial flash setup that would be performed on a + cold boot. + */ + + .text : { + __logical_binary_start = .; + KEEP (*(.vectors)) + KEEP (*(.binary_info_header)) + __binary_info_header_end = .; + KEEP (*(.embedded_block)) + __embedded_block_end = .; + KEEP (*(.reset)) + /* TODO revisit this now memset/memcpy/float in ROM */ + /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from + * FLASH ... we will include any thing excluded here in .data below by default */ + *(.init) + *libgcc.a:cmse_nonsecure_call.o + *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) + *(.fini) + /* Pull all c'tors into .text */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + /* Followed by destructors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(SORT(.preinit_array.*))) + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.eh_frame*) + . = ALIGN(4); + } > FLASH + + /* Note the boot2 section is optional, and should be discarded if there is + no reference to it *inside* the binary, as it is not called by the + bootrom. (The bootrom performs a simple best-effort XIP setup and + leaves it to the binary to do anything more sophisticated.) However + there is still a size limit of 256 bytes, to ensure the boot2 can be + stored in boot RAM. + + Really this is a "XIP setup function" -- the name boot2 is historic and + refers to its dual-purpose on RP2040, where it also handled vectoring + from the bootrom into the user image. + */ + + .boot2 : { + __boot2_start__ = .; + *(.boot2) + __boot2_end__ = .; + } > FLASH + + ASSERT(__boot2_end__ - __boot2_start__ <= 256, + "ERROR: Pico second stage bootloader must be no more than 256 bytes in size") + + .rodata : { + *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*) + *(.srodata*) + . = ALIGN(4); + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) + . = ALIGN(4); + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* Machine inspectable binary information */ + . = ALIGN(4); + __binary_info_start = .; + .binary_info : + { + KEEP(*(.binary_info.keep.*)) + *(.binary_info.*) + } > FLASH + __binary_info_end = .; + . = ALIGN(4); +} diff --git a/src/rp2_common/pico_standard_link/standard_scripts/section_end.ld b/src/rp2_common/pico_standard_link/standard_scripts/section_end.ld new file mode 100644 index 00000000..53d32817 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/section_end.ld @@ -0,0 +1,49 @@ +/* Based on GCC ARM embedded samples. + Defines the following symbols for use by code: + __exidx_start + __exidx_end + __etext + __data_start__ + __preinit_array_start + __preinit_array_end + __init_array_start + __init_array_end + __fini_array_start + __fini_array_end + __data_end__ + __bss_start__ + __bss_end__ + __end__ + end + __HeapLimit + __StackLimit + __StackTop + __stack (== StackTop) +*/ + +SECTIONS +{ + /* stack limit is poorly named, but historically is maximum heap ptr */ + __StackLimit = ORIGIN(RAM) + LENGTH(RAM); + __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); + __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); + __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); + __StackBottom = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* picolibc and LLVM */ + PROVIDE (__heap_start = __end__); + PROVIDE (__heap_end = __HeapLimit); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + + /* llvm-libc */ + PROVIDE (_end = __end__); + PROVIDE (__llvm_libc_heap_limit = __HeapLimit); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") + + /* todo assert on extra code */ +} diff --git a/src/rp2_common/pico_standard_link/standard_scripts/section_flash_end.ld b/src/rp2_common/pico_standard_link/standard_scripts/section_flash_end.ld new file mode 100644 index 00000000..8591406f --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/section_flash_end.ld @@ -0,0 +1,7 @@ +SECTIONS +{ + .flash_end : { + KEEP(*(.embedded_end_block*)) + PROVIDE(__flash_binary_end = .); + } > FLASH =0xaa +} diff --git a/src/rp2_common/pico_standard_link/standard_scripts/section_heap.ld b/src/rp2_common/pico_standard_link/standard_scripts/section_heap.ld new file mode 100644 index 00000000..1cc9e0de --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/section_heap.ld @@ -0,0 +1,12 @@ +SECTIONS +{ + .heap DEFINED(HEAP_LOC) ? HEAP_LOC : . (NOLOAD): + { + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + } > RAM + /* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however + to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */ + __HeapLimit = DEFINED(HEAP_LIMIT) ? HEAP_LIMIT : ORIGIN(RAM) + LENGTH(RAM); +} diff --git a/src/rp2_common/pico_standard_link/standard_scripts/section_no_flash_data.ld b/src/rp2_common/pico_standard_link/standard_scripts/section_no_flash_data.ld new file mode 100644 index 00000000..5658d8a4 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/section_no_flash_data.ld @@ -0,0 +1,82 @@ +SECTIONS +{ + .data : { + __data_start__ = .; + *(vtable) + + *(.time_critical*) + + *(.data*) + *(.sdata*) + + . = ALIGN(4); + *(.after_data.*) + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__mutex_array_start = .); + KEEP(*(SORT(.mutex_array.*))) + KEEP(*(.mutex_array)) + PROVIDE_HIDDEN (__mutex_array_end = .); + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(SORT(.preinit_array.*))) + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.jcr) + . = ALIGN(4); + } > RAM + + .tdata : { + . = ALIGN(4); + *(.tdata .tdata.* .gnu.linkonce.td.*) + /* All data end */ + __tdata_end = .; + } > RAM + PROVIDE(__data_end__ = .); + + .uninitialized_data (NOLOAD): { + . = ALIGN(4); + *(.uninitialized_data*) + } > RAM + /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ + __etext = LOADADDR(.data); + + .tbss (NOLOAD) : { + . = ALIGN(4); + __bss_start__ = .; + __tls_base = .; + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + + __tls_end = .; + } > RAM + + .bss (NOLOAD) : { + . = ALIGN(4); + __tbss_end = .; + + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) + *(COMMON) + PROVIDE(__global_pointer$ = . + 2K); + *(.sbss*) + . = ALIGN(4); + __bss_end__ = .; + } > RAM +} diff --git a/src/rp2_common/pico_standard_link/standard_scripts/section_no_flash_text.ld b/src/rp2_common/pico_standard_link/standard_scripts/section_no_flash_text.ld new file mode 100644 index 00000000..833d8c42 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/section_no_flash_text.ld @@ -0,0 +1,73 @@ +SECTIONS +{ + /* Note unlike RP2040, we start the image with a vector table even for + NO_FLASH builds. On Arm, the bootrom expects a VT at the start of the + image by default; on RISC-V, the default is to enter the image at its + lowest address, so an IMAGE_DEF item is required to specify the + nondefault entry point. */ + + .text : { + __logical_binary_start = .; + /* Vectors require 512-byte alignment on v8-M when >48 IRQs are used, + so we would waste RAM if the vector table were not at the + start. */ + KEEP (*(.vectors)) + KEEP (*(.binary_info_header)) + __binary_info_header_end = .; + KEEP (*(.embedded_block)) + __embedded_block_end = .; + __reset_start = .; + KEEP (*(.reset)) + __reset_end = .; + *(.text*) + . = ALIGN(4); + *(.init) + *(.fini) + /* Pull all c'tors into .text */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + /* Followed by destructors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.eh_frame*) + } > RAM + + .rodata : { + . = ALIGN(4); + *(.rodata*) + *(.srodata*) + . = ALIGN(4); + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) + . = ALIGN(4); + } > RAM + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > RAM + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > RAM + __exidx_end = .; + + /* Machine inspectable binary information */ + . = ALIGN(4); + __binary_info_start = .; + .binary_info : + { + KEEP(*(.binary_info.keep.*)) + *(.binary_info.*) + } > RAM + __binary_info_end = .; + . = ALIGN(4); +} diff --git a/src/rp2_common/pico_standard_link/standard_scripts/section_scratch.ld b/src/rp2_common/pico_standard_link/standard_scripts/section_scratch.ld new file mode 100644 index 00000000..f61c3963 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/section_scratch.ld @@ -0,0 +1,37 @@ +SECTIONS +{ + /* Start and end symbols must be word-aligned */ + .scratch_x : { + __scratch_x_start__ = .; + *(.scratch_x.*) + . = ALIGN(4); + __scratch_x_end__ = .; + } > SCRATCH_X AT> SCRATCH_X_STORE + __scratch_x_source__ = LOADADDR(.scratch_x); + + .scratch_y : { + __scratch_y_start__ = .; + *(.scratch_y.*) + . = ALIGN(4); + __scratch_y_end__ = .; + } > SCRATCH_Y AT> SCRATCH_Y_STORE + __scratch_y_source__ = LOADADDR(.scratch_y); + + /* .stack*_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later + * + * stack1 section may be empty/missing if platform_launch_core1 is not used */ + + /* by default we put core 0 stack at the end of scratch Y, so that if core 1 + * stack is not used then all of SCRATCH_X is free. + */ + .stack1_dummy (NOLOAD): + { + *(.stack1*) + } > SCRATCH_X + .stack_dummy (NOLOAD): + { + KEEP(*(.stack*)) + } > SCRATCH_Y +} diff --git a/src/rp2_common/pico_standard_link/standard_scripts/sections_copy_to_ram.ld b/src/rp2_common/pico_standard_link/standard_scripts/sections_copy_to_ram.ld new file mode 100644 index 00000000..fe7caf54 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/sections_copy_to_ram.ld @@ -0,0 +1,7 @@ +INCLUDE "section_copy_to_ram_text.ld" +INCLUDE "section_copy_to_ram_data.ld" +INCLUDE "section_heap.ld" +INCLUDE "section_scratch.ld" +INCLUDE "section_flash_end.ld" +INCLUDE "section_end.ld" +INCLUDE "section_platform_end.ld" diff --git a/src/rp2_common/pico_standard_link/standard_scripts/sections_default.ld b/src/rp2_common/pico_standard_link/standard_scripts/sections_default.ld new file mode 100644 index 00000000..f22558a9 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/sections_default.ld @@ -0,0 +1,7 @@ +INCLUDE "section_default_text.ld" +INCLUDE "section_default_data.ld" +INCLUDE "section_heap.ld" +INCLUDE "section_scratch.ld" +INCLUDE "section_flash_end.ld" +INCLUDE "section_end.ld" +INCLUDE "section_platform_end.ld" diff --git a/src/rp2_common/pico_standard_link/standard_scripts/sections_no_flash.ld b/src/rp2_common/pico_standard_link/standard_scripts/sections_no_flash.ld new file mode 100644 index 00000000..77bad234 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/sections_no_flash.ld @@ -0,0 +1,6 @@ +INCLUDE "section_no_flash_text.ld" +INCLUDE "section_no_flash_data.ld" +INCLUDE "section_heap.ld" +INCLUDE "section_scratch.ld" +INCLUDE "section_end.ld" +INCLUDE "section_platform_end.ld" diff --git a/src/rp2_common/pico_standard_link/standard_scripts/set_memory_locations.ld b/src/rp2_common/pico_standard_link/standard_scripts/set_memory_locations.ld new file mode 100644 index 00000000..a9110eb5 --- /dev/null +++ b/src/rp2_common/pico_standard_link/standard_scripts/set_memory_locations.ld @@ -0,0 +1,8 @@ +RAM_ORIGIN = DEFINED(RAM_ORIGIN) ? RAM_ORIGIN : RAM_ORIGIN_DEFAULT; +RAM_LENGTH = DEFINED(RAM_LENGTH) ? RAM_LENGTH : RAM_LENGTH_DEFAULT; +SCRATCH_X_ORIGIN = DEFINED(SCRATCH_X_ORIGIN) ? SCRATCH_X_ORIGIN : SCRATCH_X_ORIGIN_DEFAULT; +SCRATCH_X_LENGTH = DEFINED(SCRATCH_X_LENGTH) ? SCRATCH_X_LENGTH : SCRATCH_X_LENGTH_DEFAULT; +SCRATCH_Y_ORIGIN = DEFINED(SCRATCH_Y_ORIGIN) ? SCRATCH_Y_ORIGIN : SCRATCH_Y_ORIGIN_DEFAULT; +SCRATCH_Y_LENGTH = DEFINED(SCRATCH_Y_LENGTH) ? SCRATCH_Y_LENGTH : SCRATCH_Y_LENGTH_DEFAULT; +XIP_RAM_ORIGIN = DEFINED(XIP_RAM_ORIGIN) ? XIP_RAM_ORIGIN : XIP_RAM_ORIGIN_DEFAULT; +XIP_RAM_LENGTH = DEFINED(XIP_RAM_LENGTH) ? XIP_RAM_LENGTH : XIP_RAM_LENGTH_DEFAULT; diff --git a/test/kitchen_sink/CMakeLists.txt b/test/kitchen_sink/CMakeLists.txt index 1d6110f4..245e2690 100644 --- a/test/kitchen_sink/CMakeLists.txt +++ b/test/kitchen_sink/CMakeLists.txt @@ -214,6 +214,30 @@ if (NOT KITCHEN_SINK_NO_BINARY_TYPE_VARIANTS) pico_add_extra_outputs(kitchen_sink_blocked_ram) target_compile_definitions(kitchen_sink_blocked_ram PRIVATE KITCHEN_SINK_ID="blocked-ram binary") endif() + + add_executable(kitchen_sink_ram_custom ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) + # Have ram start from 0x20020000 length 128k, and heap start from 0x20030000 + pico_set_linker_script_var(kitchen_sink_ram_custom RAM_ORIGIN 0x20020000) + pico_set_linker_script_var(kitchen_sink_ram_custom RAM_LENGTH 128k) + pico_set_linker_script_var(kitchen_sink_ram_custom HEAP_LOC 0x20030000) + target_link_libraries(kitchen_sink_ram_custom kitchen_sink_libs kitchen_sink_options) + pico_add_extra_outputs(kitchen_sink_ram_custom) + target_compile_definitions(kitchen_sink_ram_custom PRIVATE KITCHEN_SINK_ID="custom ram binary") + + add_executable(kitchen_sink_ram_section ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) + pico_add_linker_script_override_path(kitchen_sink_ram_section ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink_ram_section_scripts) + target_link_libraries(kitchen_sink_ram_section kitchen_sink_libs kitchen_sink_options) + pico_add_extra_outputs(kitchen_sink_ram_section) + target_compile_definitions(kitchen_sink_ram_section PRIVATE KITCHEN_SINK_ID="ram section binary" EXTRA_DATA_SECTION=1) + + if (NOT PICO_C_COMPILER_IS_CLANG) + # Clang does not support overlay sections + add_executable(kitchen_sink_simple_overlay ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink.c) + pico_add_linker_script_override_path(kitchen_sink_simple_overlay ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink_simple_overlay_scripts) + target_link_libraries(kitchen_sink_simple_overlay kitchen_sink_libs kitchen_sink_options) + pico_add_extra_outputs(kitchen_sink_simple_overlay) + target_compile_definitions(kitchen_sink_simple_overlay PRIVATE KITCHEN_SINK_ID="simple overlay binary" EXTRA_DATA_SECTION=2) + endif() endif() add_executable(kitchen_sink_cpp ${CMAKE_CURRENT_LIST_DIR}/kitchen_sink_cpp.cpp) diff --git a/test/kitchen_sink/kitchen_sink.c b/test/kitchen_sink/kitchen_sink.c index 7bc2bcd1..6a3a5fbe 100644 --- a/test/kitchen_sink/kitchen_sink.c +++ b/test/kitchen_sink/kitchen_sink.c @@ -85,6 +85,42 @@ int main(void) { hard_assert(recursive_mutex_try_enter(&recursive_mutex, NULL)); hard_assert(recursive_mutex_try_enter(&recursive_mutex, NULL)); printf("%f\n", foox(1.3f, 2.6f)); +#ifdef EXTRA_DATA_SECTION +#if EXTRA_DATA_SECTION > 1 + extern uint32_t __overlays_start__; + uint32_t stored_words; + + static int overlay_first __attribute__((section(".overlay_first"))) = 12345678; + printf("overlay_first before load = %d\n", overlay_first); + static int overlay_second_one __attribute__((section(".overlay_second"))) = 34567890; + static int overlay_second_two __attribute__((section(".overlay_second"))) = 56789012; + printf("overlay_second before load = %d, %d\n", overlay_second_one, overlay_second_two); + + extern uint32_t __load_start_overlay_second; + extern uint32_t __load_stop_overlay_second; + stored_words = (uint32_t)(&__load_stop_overlay_second - &__load_start_overlay_second); + memcpy(&__overlays_start__, &__load_start_overlay_second, 4 * stored_words); + printf("overlay_second after load = %d, %d\n", overlay_second_one, overlay_second_two); + + extern uint32_t __load_start_overlay_first; + extern uint32_t __load_stop_overlay_first; + stored_words = (uint32_t)(&__load_stop_overlay_first - &__load_start_overlay_first); + memcpy(&__overlays_start__, &__load_start_overlay_first, 4 * stored_words); + printf("overlay_first after load = %d\n", overlay_first); + printf("overlay_second after overlay_first load = %d, %d\n", overlay_second_one, overlay_second_two); +#else + static int extra_data __attribute__((section(".extra_data"))) = 12345678; + printf("extra_data before load = %d\n", extra_data); + + extern uint32_t __extra_data_source__; + extern uint32_t __extra_data_start__; + extern uint32_t __extra_data_end__; + uint32_t stored_words = (uint32_t)(&__extra_data_end__ - &__extra_data_start__); + memcpy(&__extra_data_start__, &__extra_data_source__, 4 * stored_words); + + printf("extra_data after load = %d\n", extra_data); +#endif +#endif #ifndef __riscv // this should compile as we are Cortex M0+ pico_default_asm ("SVC #3"); diff --git a/test/kitchen_sink/kitchen_sink_ram_section_scripts/sections_default.ld b/test/kitchen_sink/kitchen_sink_ram_section_scripts/sections_default.ld new file mode 100644 index 00000000..9ffef1a2 --- /dev/null +++ b/test/kitchen_sink/kitchen_sink_ram_section_scripts/sections_default.ld @@ -0,0 +1,19 @@ +INCLUDE "section_default_text.ld" +INCLUDE "section_default_data.ld" + +SECTIONS +{ + .extra_data : { + __extra_data_start__ = .; + *(.extra_data*) + . = ALIGN(4); + __extra_data_end__ = .; + } > RAM AT> RAM_STORE + __extra_data_source__ = LOADADDR(.extra_data); +} + +INCLUDE "section_heap.ld" +INCLUDE "section_scratch.ld" +INCLUDE "section_flash_end.ld" +INCLUDE "section_end.ld" +INCLUDE "section_platform_end.ld" \ No newline at end of file diff --git a/test/kitchen_sink/kitchen_sink_simple_overlay_scripts/sections_default.ld b/test/kitchen_sink/kitchen_sink_simple_overlay_scripts/sections_default.ld new file mode 100644 index 00000000..9a69c883 --- /dev/null +++ b/test/kitchen_sink/kitchen_sink_simple_overlay_scripts/sections_default.ld @@ -0,0 +1,24 @@ +INCLUDE "section_default_text.ld" +INCLUDE "section_default_data.ld" + +SECTIONS +{ + PROVIDE(__overlays_start__ = .); + OVERLAY : { + .overlay_first { + KEEP (*(.first*)) + . = ALIGN(4); + } + .overlay_second { + KEEP (*(.second*)) + . = ALIGN(4); + } + } > RAM AT> RAM_STORE + PROVIDE(__overlays_end__ = .); +} + +INCLUDE "section_heap.ld" +INCLUDE "section_scratch.ld" +INCLUDE "section_flash_end.ld" +INCLUDE "section_end.ld" +INCLUDE "section_platform_end.ld"