summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Harper <peter.harper@raspberrypi.com>2024-05-22 15:49:46 +0100
committerDamien George <damien@micropython.org>2024-10-15 11:51:56 +1100
commitc90d996c9da51103a6be1b41b2c2664a730b0d8e (patch)
treefc4919b1002575867c8d420a08edc883074d4be3
parent815d6a131d81eded59d17aa854eb006ff8c19e2b (diff)
rp2: Update custom linker scripts for new pico-sdk.
Signed-off-by: Phil Howard <phil@gadgetoid.com> Signed-off-by: Damien George <damien@micropython.org>
-rw-r--r--ports/rp2/CMakeLists.txt2
-rw-r--r--ports/rp2/memmap_mp_rp2040.ld (renamed from ports/rp2/memmap_mp.ld)0
-rw-r--r--ports/rp2/memmap_mp_rp2350.ld312
3 files changed, 313 insertions, 1 deletions
diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt
index 19c7178fc..54b7e84bc 100644
--- a/ports/rp2/CMakeLists.txt
+++ b/ports/rp2/CMakeLists.txt
@@ -525,7 +525,7 @@ endif()
# a linker script modification) until we explicitly add macro calls around the function
# defs to move them into RAM.
if (PICO_ON_DEVICE AND NOT PICO_NO_FLASH AND NOT PICO_COPY_TO_RAM)
- pico_set_linker_script(${MICROPY_TARGET} ${CMAKE_CURRENT_LIST_DIR}/memmap_mp.ld)
+ pico_set_linker_script(${MICROPY_TARGET} ${CMAKE_CURRENT_LIST_DIR}/memmap_mp_${PICO_PLATFORM}.ld)
endif()
pico_add_extra_outputs(${MICROPY_TARGET})
diff --git a/ports/rp2/memmap_mp.ld b/ports/rp2/memmap_mp_rp2040.ld
index a5799cd88..a5799cd88 100644
--- a/ports/rp2/memmap_mp.ld
+++ b/ports/rp2/memmap_mp_rp2040.ld
diff --git a/ports/rp2/memmap_mp_rp2350.ld b/ports/rp2/memmap_mp_rp2350.ld
new file mode 100644
index 000000000..1e1cbbfd7
--- /dev/null
+++ b/ports/rp2/memmap_mp_rp2350.ld
@@ -0,0 +1,312 @@
+/* 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
+{
+ FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 4096k
+ 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
+ /* Change for MicroPython... exclude gc.c, parse.c, vm.c from flash */
+ *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a: *gc.c.obj *vm.c.obj *parse.c.obj) .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*))
+ /* 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 */
+ /* Change for MicroPython: don't include this, it increases reported firmware size.
+ /* . = ORIGIN(RAM) + LENGTH(RAM); */
+ __HeapLimit = .;
+ } > 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 = __bss_end__ + __micropy_c_heap_size__;
+
+ /* Define start and end of GC heap */
+ __GcHeapStart = __StackLimit; /* after the C heap (sbrk limit) */
+ __GcHeapEnd = ORIGIN(RAM) + LENGTH(RAM) - __micropy_extra_stack__;
+
+ /* Define start and end of C stack */
+ __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
+ __StackBottom = __GcHeapEnd;
+ 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 GC heap is at least 64 KB */
+ /* This is half the minimum RAM suggested for full-featured MicroPython.
+ * This value accounts for large static buffers included in user C or C++
+ * modules, which might significantly reduce the available heap but also
+ * lower demand for memory at runtime.
+ */
+ ASSERT((__GcHeapEnd - __GcHeapStart) > 64*1024, "GcHeap is too small")
+
+ 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 */
+}