Update linker script for split heap support

To have the flexibilty in application; to use any of the section
(data/bss/heap) without updating linker script in every use case,
following decisions are made:

1. Fixed size and small sections moved to SRAM2 (32K)
    Vectors
    Crash data
    Stack
    Remaining section - Heap memory
2. Large memory space should be used for variable sections
   Data
   BSS
   Heap - Remaining section

Heap is moved to the end of both sections as GCC allocates till 4K boundary,
if end of heap is not aligned to 4K, that chunk of memory will go unutilized

#if !defined(MBED_APP_START)
  #define MBED_APP_START 0x08000000
#endif

#if !defined(MBED_APP_SIZE)
  #define MBED_APP_SIZE 1024k
#endif

#if !defined(MBED_BOOT_STACK_SIZE)
    #define MBED_BOOT_STACK_SIZE 0x400
#endif

STACK_SIZE = MBED_BOOT_STACK_SIZE;

M_CRASH_DATA_RAM_SIZE = 0x100;

/* Linker script to configure memory regions. */
MEMORY
{
  FLASH (rx)   : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE
  SRAM2 (rwx)  : ORIGIN = 0x10000188, LENGTH = 32k - 0x188
  SRAM1 (rwx)  : ORIGIN = 0x20000000, LENGTH = 96k
}

/* Linker script to place sections and symbol values. Should be used together
 * with other linker script that defines memory regions FLASH and RAM.
 * It references following symbols, which must be defined in code:
 *   Reset_Handler : Entry of reset handler
 *
 * It defines following symbols, which code can use without definition:
 *   __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
 *   _estack
 */
ENTRY(Reset_Handler)

SECTIONS
{
    .text :
    {
        KEEP(*(.isr_vector))
        *(.text*)
        KEEP(*(.init))
        KEEP(*(.fini))

        /* .ctors */
        *crtbegin.o(.ctors)
        *crtbegin?.o(.ctors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
        *(SORT(.ctors.*))
        *(.ctors)

        /* .dtors */
        *crtbegin.o(.dtors)
        *crtbegin?.o(.dtors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
        *(SORT(.dtors.*))
        *(.dtors)

        *(.rodata*)

        KEEP(*(.eh_frame*))
    } > FLASH

    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > FLASH

    __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    __exidx_end = .;

    __etext = .;
    _sidata = .;

    .crash_data_ram :
    {
        . = ALIGN(8);
        __CRASH_DATA_RAM__ = .;
        __CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */
        KEEP(*(.keep.crash_data_ram))
        *(.m_crash_data_ram)     /* This is a user defined section */
        . += M_CRASH_DATA_RAM_SIZE;
        . = ALIGN(8);
        __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */
    } > SRAM2

     /* .stack section doesn't contains any symbols. It is only
     * used for linker to reserve space for the isr stack section
     * WARNING: .stack should come immediately after the last secure memory
     * section.  This provides stack overflow detection. */
    .stack (NOLOAD):
    {
        __StackLimit = .;
        *(.stack*);
        . += STACK_SIZE - (. - __StackLimit);
    } > SRAM2

    /* Set stack top to end of RAM, and stack limit move down by
     * size of stack_dummy section */
    __StackTop = ADDR(.stack) + SIZEOF(.stack);
    _estack = __StackTop;
    __StackLimit = ADDR(.stack);
    PROVIDE(__stack = __StackTop);

    .data : AT (__etext)
    {
        __data_start__ = .;
        _sdata = .;
        *(vtable)
        *(.data*)

        . = ALIGN(8);
        /* preinit data */
        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP(*(.preinit_array))
        PROVIDE_HIDDEN (__preinit_array_end = .);

        . = ALIGN(8);
        /* init data */
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP(*(SORT(.init_array.*)))
        KEEP(*(.init_array))
        PROVIDE_HIDDEN (__init_array_end = .);

        . = ALIGN(8);
        /* finit data */
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP(*(SORT(.fini_array.*)))
        KEEP(*(.fini_array))
        PROVIDE_HIDDEN (__fini_array_end = .);

        KEEP(*(.jcr*))
        . = ALIGN(8);
        /* All data end */
        __data_end__ = .;
        _edata = .;
    } > SRAM1

    /* Check if bss exceeds SRAM1 */
    ASSERT(__data_end__ <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), ".data is too big for SRAM1")

    .bss :
    {
        . = ALIGN(8);
        __bss_start__ = .;
        _sbss = .;
        *(.bss*)
        *(COMMON)
        . = ALIGN(8);
        __bss_end__ = .;
        _ebss = .;
    } > SRAM1

    /* Check if bss exceeds SRAM1 */
    ASSERT(__bss_end__ <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), "BSS is too big for SRAM1")

    .heap (COPY):
    {
        __end__ = .;
        __mbed_sbrk_start_0 = .;
        end = __end__;
        *(.heap*)
        . = (ORIGIN(SRAM2) + LENGTH(SRAM2));
        __mbed_krbs_start_0 = .;
        __mbed_sbrk_start = __bss_end__;
        . = (ORIGIN(SRAM1) + LENGTH(SRAM1));
        __mbed_krbs_start = .;
        __HeapLimit = .;
    } > SRAM2
}

#if !defined(MBED_APP_START)
  #define MBED_APP_START 0x08000000
#endif

#if !defined(MBED_APP_SIZE)
  #define MBED_APP_SIZE 1024k
#endif

#if !defined(MBED_BOOT_STACK_SIZE)
    #define MBED_BOOT_STACK_SIZE 0x400
#endif

STACK_SIZE = MBED_BOOT_STACK_SIZE;

M_CRASH_DATA_RAM_SIZE = 0x100;

/* Linker script to configure memory regions. */
MEMORY
{
  FLASH (rx)   : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE
  SRAM2 (rwx)  : ORIGIN = 0x10000188, LENGTH = 32k - 0x188
  SRAM1 (rwx)  : ORIGIN = 0x20000000, LENGTH = 96k
}

/* Linker script to place sections and symbol values. Should be used together
 * with other linker script that defines memory regions FLASH and RAM.
 * It references following symbols, which must be defined in code:
 *   Reset_Handler : Entry of reset handler
 *
 * It defines following symbols, which code can use without definition:
 *   __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
 *   _estack
 */
ENTRY(Reset_Handler)

SECTIONS
{
    .text :
    {
        KEEP(*(.isr_vector))
        *(.text*)
        KEEP(*(.init))
        KEEP(*(.fini))

        /* .ctors */
        *crtbegin.o(.ctors)
        *crtbegin?.o(.ctors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
        *(SORT(.ctors.*))
        *(.ctors)

        /* .dtors */
        *crtbegin.o(.dtors)
        *crtbegin?.o(.dtors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
        *(SORT(.dtors.*))
        *(.dtors)

        *(.rodata*)

        KEEP(*(.eh_frame*))
    } > FLASH

    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > FLASH

    __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    __exidx_end = .;

    __etext = .;
    _sidata = .;

    .crash_data_ram :
    {
        . = ALIGN(8);
        __CRASH_DATA_RAM__ = .;
        __CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */
        KEEP(*(.keep.crash_data_ram))
        *(.m_crash_data_ram)     /* This is a user defined section */
        . += M_CRASH_DATA_RAM_SIZE;
        . = ALIGN(8);
        __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */
    } > SRAM1

    .data : AT (__etext)
    {
        __data_start__ = .;
        _sdata = .;
        *(vtable)
        *(.data*)

        . = ALIGN(8);
        /* preinit data */
        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP(*(.preinit_array))
        PROVIDE_HIDDEN (__preinit_array_end = .);

        . = ALIGN(8);
        /* init data */
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP(*(SORT(.init_array.*)))
        KEEP(*(.init_array))
        PROVIDE_HIDDEN (__init_array_end = .);

        . = ALIGN(8);
        /* finit data */
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP(*(SORT(.fini_array.*)))
        KEEP(*(.fini_array))
        PROVIDE_HIDDEN (__fini_array_end = .);

        KEEP(*(.jcr*))
        . = ALIGN(8);
        /* All data end */
        __data_end__ = .;
        _edata = .;

    } > SRAM1

    .bss :
    {
        . = ALIGN(8);
        __bss_start__ = .;
        _sbss = .;
        *(.bss*)
        *(COMMON)
        . = ALIGN(8);
        __bss_end__ = .;
        _ebss = .;
    } > SRAM2

    .heap (COPY):
    {
        __end__ = .;
        end = __end__;
        *(.heap*)
        . += (ORIGIN(SRAM1) + LENGTH(SRAM1) - .);
        __HeapLimit = .;
    } > SRAM1
    PROVIDE(__heap_size = SIZEOF(.heap));
    PROVIDE(__mbed_sbrk_start = ADDR(.heap));
    PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap));
    /* Check if data + heap exceeds RAM1 limit */
    ASSERT((ORIGIN(SRAM1)+LENGTH(SRAM1)) >= __HeapLimit, "SRAM1 overflow")
    /* .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 */
    .stack_dummy (COPY):
    {
        *(.stack*)
        . += (ORIGIN(SRAM2) + STACK_SIZE - .);
        __mbed_sbrk_start_0 = .;
        . += (ORIGIN(SRAM2) + LENGTH(SRAM2) - .);
        __mbed_krbs_start_0 = .;
    } > SRAM2

    /* Set stack top to end of RAM, and stack limit move down by
     * size of stack_dummy section */
    __StackTop = ORIGIN(SRAM2) + LENGTH(SRAM2);
    _estack = __StackTop;
    __StackLimit = __StackTop - STACK_SIZE;
    PROVIDE(__stack = __StackTop);
    /* Check if stack exceeds RAM2 limit */
    ASSERT((ORIGIN(SRAM2)+LENGTH(SRAM2)) >= __StackLimit, "SRAM2 overflow")
    /* Check if bss exceeds __StackLimit */
    ASSERT(__bss_end__ <= __StackLimit, "BSS is too big for RAM2")
}


esp8266/esp8266.ld: Put axTLS to FlashROM.

/* GNU linker script for ESP8266 */

MEMORY
{
    dport0_0_seg : org = 0x3ff00000, len = 0x10
    dram0_0_seg :  org = 0x3ffe8000, len = 0x14000
    iram1_0_seg :  org = 0x40100000, len = 0x8000
    irom0_0_seg :  org = 0x40209000, len = 0x80000
}

/* define the top of RAM */
_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg);

PHDRS
{
    dport0_0_phdr PT_LOAD;
    dram0_0_phdr PT_LOAD;
    dram0_0_bss_phdr PT_LOAD;
    iram1_0_phdr PT_LOAD;
    irom0_0_phdr PT_LOAD;
}

ENTRY(call_user_start)
EXTERN(_DebugExceptionVector)
EXTERN(_DoubleExceptionVector)
EXTERN(_KernelExceptionVector)
EXTERN(_NMIExceptionVector)
EXTERN(_UserExceptionVector)

PROVIDE(_memmap_vecbase_reset = 0x40000000);

/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00000110;
_memmap_cacheattr_wt_base = 0x00000110;
_memmap_cacheattr_bp_base = 0x00000220;
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
_memmap_cacheattr_wb_trapnull = 0x2222211F;
_memmap_cacheattr_wba_trapnull = 0x2222211F;
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
_memmap_cacheattr_wt_trapnull = 0x2222211F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
_memmap_cacheattr_wb_allvalid = 0x22222112;
_memmap_cacheattr_wt_allvalid = 0x22222112;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);

SECTIONS
{

    .dport0.rodata : ALIGN(4)
    {
        _dport0_rodata_start = ABSOLUTE(.);
        *(.dport0.rodata)
        *(.dport.rodata)
        _dport0_rodata_end = ABSOLUTE(.);
    } >dport0_0_seg :dport0_0_phdr

    .dport0.literal : ALIGN(4)
    {
        _dport0_literal_start = ABSOLUTE(.);
        *(.dport0.literal)
        *(.dport.literal)
        _dport0_literal_end = ABSOLUTE(.);
    } >dport0_0_seg :dport0_0_phdr

    .dport0.data : ALIGN(4)
    {
        _dport0_data_start = ABSOLUTE(.);
        *(.dport0.data)
        *(.dport.data)
        _dport0_data_end = ABSOLUTE(.);
    } >dport0_0_seg :dport0_0_phdr

    .irom0.text : ALIGN(4)
    {
        _irom0_text_start = ABSOLUTE(.);
        *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)

        /* we put some specific text in this section */

        *py/argcheck.o*(.literal* .text*)
        *py/asm*.o*(.literal* .text*)
        *py/bc.o*(.literal* .text*)
        *py/binary.o*(.literal* .text*)
        *py/builtin*.o*(.literal* .text*)
        *py/compile.o*(.literal* .text*)
        *py/emit*.o*(.literal* .text*)
        *py/formatfloat.o*(.literal* .text*)
        *py/frozenmod.o*(.literal* .text*)
        *py/gc.o*(.literal* .text*)
        *py/lexer*.o*(.literal* .text*)
        *py/malloc*.o*(.literal* .text*)
        *py/map*.o*(.literal* .text*)
        *py/mod*.o*(.literal* .text*)
        *py/mpprint.o*(.literal* .text*)
        *py/mpstate.o*(.literal* .text*)
        *py/mpz.o*(.literal* .text*)
        *py/native*.o*(.literal* .text*)
        *py/nlr*.o*(.literal* .text*)
        *py/obj*.o*(.literal* .text*)
        *py/opmethods.o*(.literal* .text*)
        *py/parse*.o*(.literal* .text*)
        *py/qstr.o*(.literal* .text*)
        *py/repl.o*(.literal* .text*)
        *py/runtime.o*(.literal* .text*)
        *py/scope.o*(.literal* .text*)
        *py/sequence.o*(.literal* .text*)
        *py/showbc.o*(.literal* .text*)
        *py/smallint.o*(.literal* .text*)
        *py/stackctrl.o*(.literal* .text*)
        *py/stream.o*(.literal* .text*)
        *py/unicode.o*(.literal* .text*)
        *py/vm.o*(.literal* .text*)
        *py/vstr.o*(.literal* .text*)
        *py/warning.o*(.literal* .text*)

        *extmod/*.o*(.literal* .text*)

        *lib/fatfs/*.o*(.literal*, .text*)
        */libaxtls.a:(.literal*, .text*)
        *lib/libm/*.o*(.literal*, .text*)
        *lib/mp-readline/*.o(.literal*, .text*)
        *lib/netutils/*.o*(.literal*, .text*)
        *lib/timeutils/*.o*(.literal*, .text*)
        *lib/utils/*.o*(.literal*, .text*)

        *stmhal/pybstdio.o(.literal*, .text*)

        *gccollect.o(.literal* .text*)
        *gchelper.o(.literal* .text*)
        *lexerstr32.o(.literal* .text*)
        *utils.o(.literal* .text*)
        *modpyb.o(.literal*, .text*)
        *modpybpin.o(.literal*, .text*)
        *modpybpwm.o(.literal*, .text*)
        *modpybrtc.o(.literal*, .text*)
        *modpybadc.o(.literal*, .text*)
        *modpybuart.o(.literal*, .text*)
        *modpybi2c.o(.literal*, .text*)
        *modpybspi.o(.literal*, .text*)
        *modesp.o(.literal* .text*)
        *modnetwork.o(.literal* .text*)
        *moduos.o(.literal* .text*)
        *modutime.o(.literal* .text*)
        *modlwip.o(.literal* .text*)
        *modsocket.o(.literal* .text*)
        *modonewire.o(.literal* .text*)

        /* we put as much rodata as possible in this section */
        /* note that only rodata accessed as a machine word is allowed here */
        *py/qstr.o(.rodata.const_pool)
        *.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */
        *.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */
        *.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */
        */frozen.o(.rodata.mp_frozen_sizes) /* frozen modules */
        */frozen.o(.rodata.mp_frozen_content) /* frozen modules */

        /* for -mforce-l32 */
        build/*.o(.rodata*)

        _irom0_text_end = ABSOLUTE(.);
    } >irom0_0_seg :irom0_0_phdr

    .text : ALIGN(4)
    {
        _stext = .;
        _text_start = ABSOLUTE(.);
        *(.UserEnter.text)
        . = ALIGN(16);
        *(.DebugExceptionVector.text)
        . = ALIGN(16);
        *(.NMIExceptionVector.text)
        . = ALIGN(16);
        *(.KernelExceptionVector.text)
        LONG(0)
        LONG(0)
        LONG(0)
        LONG(0)
        . = ALIGN(16);
        *(.UserExceptionVector.text)
        LONG(0)
        LONG(0)
        LONG(0)
        LONG(0)
        . = ALIGN(16);
        *(.DoubleExceptionVector.text)
        LONG(0)
        LONG(0)
        LONG(0)
        LONG(0)
        . = ALIGN (16);
        *(.entry.text)
        *(.init.literal)
        *(.init)
        *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
        *(.fini.literal)
        *(.fini)
        *(.gnu.version)
        _text_end = ABSOLUTE(.);
        _etext = .;
    } >iram1_0_seg :iram1_0_phdr

    .lit4 : ALIGN(4)
    {
        _lit4_start = ABSOLUTE(.);
        *(*.lit4)
        *(.lit4.*)
        *(.gnu.linkonce.lit4.*)
        _lit4_end = ABSOLUTE(.);
    } >iram1_0_seg :iram1_0_phdr

    .data : ALIGN(4)
    {
        _data_start = ABSOLUTE(.);
        *(.data)
        *(.data.*)
        *(.gnu.linkonce.d.*)
        *(.data1)
        *(.sdata)
        *(.sdata.*)
        *(.gnu.linkonce.s.*)
        *(.sdata2)
        *(.sdata2.*)
        *(.gnu.linkonce.s2.*)
        *(.jcr)
        _data_end = ABSOLUTE(.);
    } >dram0_0_seg :dram0_0_phdr

    .rodata : ALIGN(4)
    {
        _rodata_start = ABSOLUTE(.);
        *(.sdk.version)
        *(.rodata)
        *(.rodata.*)
        *(.gnu.linkonce.r.*)
        *(.rodata1)
        __XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
        *(.xt_except_table)
        *(.gcc_except_table)
        *(.gnu.linkonce.e.*)
        *(.gnu.version_r)
        *(.eh_frame)
        /*  C++ constructor and destructor tables, properly ordered:  */
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*(.ctors))
        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*(.dtors))
        /*  C++ exception handlers table:  */
        __XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
        *(.xt_except_desc)
        *(.gnu.linkonce.h.*)
        __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
        *(.xt_except_desc_end)
        *(.dynamic)
        *(.gnu.version_d)
        . = ALIGN(4);        /* this table MUST be 4-byte aligned */
        _bss_table_start = ABSOLUTE(.);
        LONG(_bss_start)
        LONG(_bss_end)
        _bss_table_end = ABSOLUTE(.);
        _rodata_end = ABSOLUTE(.);
    } >dram0_0_seg :dram0_0_phdr

    .bss ALIGN(8) (NOLOAD) : ALIGN(4)
    {
        . = ALIGN (8);
        _bss_start = ABSOLUTE(.);
        *(.dynsbss)
        *(.sbss)
        *(.sbss.*)
        *(.gnu.linkonce.sb.*)
        *(.scommon)
        *(.sbss2)
        *(.sbss2.*)
        *(.gnu.linkonce.sb2.*)
        *(.dynbss)
        *(.bss)
        *(.bss.*)
        *(.gnu.linkonce.b.*)
        *(COMMON)
        . = ALIGN (8);
        _bss_end = ABSOLUTE(.);
        _heap_start = ABSOLUTE(.);
    } >dram0_0_seg :dram0_0_bss_phdr
}

/* get ROM code address */
INCLUDE "eagle.rom.addr.v6.ld"

/* GNU linker script for ESP8266 */

MEMORY
{
    dport0_0_seg : org = 0x3ff00000, len = 0x10
    dram0_0_seg :  org = 0x3ffe8000, len = 0x14000
    iram1_0_seg :  org = 0x40100000, len = 0x8000
    irom0_0_seg :  org = 0x40209000, len = 0x80000
}

/* define the top of RAM */
_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg);

PHDRS
{
    dport0_0_phdr PT_LOAD;
    dram0_0_phdr PT_LOAD;
    dram0_0_bss_phdr PT_LOAD;
    iram1_0_phdr PT_LOAD;
    irom0_0_phdr PT_LOAD;
}

ENTRY(call_user_start)
EXTERN(_DebugExceptionVector)
EXTERN(_DoubleExceptionVector)
EXTERN(_KernelExceptionVector)
EXTERN(_NMIExceptionVector)
EXTERN(_UserExceptionVector)

PROVIDE(_memmap_vecbase_reset = 0x40000000);

/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00000110;
_memmap_cacheattr_wt_base = 0x00000110;
_memmap_cacheattr_bp_base = 0x00000220;
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
_memmap_cacheattr_wb_trapnull = 0x2222211F;
_memmap_cacheattr_wba_trapnull = 0x2222211F;
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
_memmap_cacheattr_wt_trapnull = 0x2222211F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
_memmap_cacheattr_wb_allvalid = 0x22222112;
_memmap_cacheattr_wt_allvalid = 0x22222112;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);

SECTIONS
{

    .dport0.rodata : ALIGN(4)
    {
        _dport0_rodata_start = ABSOLUTE(.);
        *(.dport0.rodata)
        *(.dport.rodata)
        _dport0_rodata_end = ABSOLUTE(.);
    } >dport0_0_seg :dport0_0_phdr

    .dport0.literal : ALIGN(4)
    {
        _dport0_literal_start = ABSOLUTE(.);
        *(.dport0.literal)
        *(.dport.literal)
        _dport0_literal_end = ABSOLUTE(.);
    } >dport0_0_seg :dport0_0_phdr

    .dport0.data : ALIGN(4)
    {
        _dport0_data_start = ABSOLUTE(.);
        *(.dport0.data)
        *(.dport.data)
        _dport0_data_end = ABSOLUTE(.);
    } >dport0_0_seg :dport0_0_phdr

    .irom0.text : ALIGN(4)
    {
        _irom0_text_start = ABSOLUTE(.);
        *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)

        /* we put some specific text in this section */

        *py/argcheck.o*(.literal* .text*)
        *py/asm*.o*(.literal* .text*)
        *py/bc.o*(.literal* .text*)
        *py/binary.o*(.literal* .text*)
        *py/builtin*.o*(.literal* .text*)
        *py/compile.o*(.literal* .text*)
        *py/emit*.o*(.literal* .text*)
        *py/formatfloat.o*(.literal* .text*)
        *py/frozenmod.o*(.literal* .text*)
        *py/gc.o*(.literal* .text*)
        *py/lexer*.o*(.literal* .text*)
        *py/malloc*.o*(.literal* .text*)
        *py/map*.o*(.literal* .text*)
        *py/mod*.o*(.literal* .text*)
        *py/mpprint.o*(.literal* .text*)
        *py/mpstate.o*(.literal* .text*)
        *py/mpz.o*(.literal* .text*)
        *py/native*.o*(.literal* .text*)
        *py/nlr*.o*(.literal* .text*)
        *py/obj*.o*(.literal* .text*)
        *py/opmethods.o*(.literal* .text*)
        *py/parse*.o*(.literal* .text*)
        *py/qstr.o*(.literal* .text*)
        *py/repl.o*(.literal* .text*)
        *py/runtime.o*(.literal* .text*)
        *py/scope.o*(.literal* .text*)
        *py/sequence.o*(.literal* .text*)
        *py/showbc.o*(.literal* .text*)
        *py/smallint.o*(.literal* .text*)
        *py/stackctrl.o*(.literal* .text*)
        *py/stream.o*(.literal* .text*)
        *py/unicode.o*(.literal* .text*)
        *py/vm.o*(.literal* .text*)
        *py/vstr.o*(.literal* .text*)
        *py/warning.o*(.literal* .text*)

        *extmod/*.o*(.literal* .text*)

        *lib/fatfs/*.o*(.literal*, .text*)
        *lib/libm/*.o*(.literal*, .text*)
        *lib/mp-readline/*.o(.literal*, .text*)
        *lib/netutils/*.o*(.literal*, .text*)
        *lib/timeutils/*.o*(.literal*, .text*)
        *lib/utils/*.o*(.literal*, .text*)

        *stmhal/pybstdio.o(.literal*, .text*)

        *gccollect.o(.literal* .text*)
        *gchelper.o(.literal* .text*)
        *lexerstr32.o(.literal* .text*)
        *utils.o(.literal* .text*)
        *modpyb.o(.literal*, .text*)
        *modpybpin.o(.literal*, .text*)
        *modpybpwm.o(.literal*, .text*)
        *modpybrtc.o(.literal*, .text*)
        *modpybadc.o(.literal*, .text*)
        *modpybuart.o(.literal*, .text*)
        *modpybi2c.o(.literal*, .text*)
        *modpybspi.o(.literal*, .text*)
        *modesp.o(.literal* .text*)
        *modnetwork.o(.literal* .text*)
        *moduos.o(.literal* .text*)
        *modutime.o(.literal* .text*)
        *modlwip.o(.literal* .text*)
        *modsocket.o(.literal* .text*)
        *modonewire.o(.literal* .text*)

        /* we put as much rodata as possible in this section */
        /* note that only rodata accessed as a machine word is allowed here */
        *py/qstr.o(.rodata.const_pool)
        *.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */
        *.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */
        *.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */
        */frozen.o(.rodata.mp_frozen_sizes) /* frozen modules */
        */frozen.o(.rodata.mp_frozen_content) /* frozen modules */

        /* for -mforce-l32 */
        build/*.o(.rodata*)

        _irom0_text_end = ABSOLUTE(.);
    } >irom0_0_seg :irom0_0_phdr

    .text : ALIGN(4)
    {
        _stext = .;
        _text_start = ABSOLUTE(.);
        *(.UserEnter.text)
        . = ALIGN(16);
        *(.DebugExceptionVector.text)
        . = ALIGN(16);
        *(.NMIExceptionVector.text)
        . = ALIGN(16);
        *(.KernelExceptionVector.text)
        LONG(0)
        LONG(0)
        LONG(0)
        LONG(0)
        . = ALIGN(16);
        *(.UserExceptionVector.text)
        LONG(0)
        LONG(0)
        LONG(0)
        LONG(0)
        . = ALIGN(16);
        *(.DoubleExceptionVector.text)
        LONG(0)
        LONG(0)
        LONG(0)
        LONG(0)
        . = ALIGN (16);
        *(.entry.text)
        *(.init.literal)
        *(.init)
        *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
        *(.fini.literal)
        *(.fini)
        *(.gnu.version)
        _text_end = ABSOLUTE(.);
        _etext = .;
    } >iram1_0_seg :iram1_0_phdr

    .lit4 : ALIGN(4)
    {
        _lit4_start = ABSOLUTE(.);
        *(*.lit4)
        *(.lit4.*)
        *(.gnu.linkonce.lit4.*)
        _lit4_end = ABSOLUTE(.);
    } >iram1_0_seg :iram1_0_phdr

    .data : ALIGN(4)
    {
        _data_start = ABSOLUTE(.);
        *(.data)
        *(.data.*)
        *(.gnu.linkonce.d.*)
        *(.data1)
        *(.sdata)
        *(.sdata.*)
        *(.gnu.linkonce.s.*)
        *(.sdata2)
        *(.sdata2.*)
        *(.gnu.linkonce.s2.*)
        *(.jcr)
        _data_end = ABSOLUTE(.);
    } >dram0_0_seg :dram0_0_phdr

    .rodata : ALIGN(4)
    {
        _rodata_start = ABSOLUTE(.);
        *(.sdk.version)
        *(.rodata)
        *(.rodata.*)
        *(.gnu.linkonce.r.*)
        *(.rodata1)
        __XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
        *(.xt_except_table)
        *(.gcc_except_table)
        *(.gnu.linkonce.e.*)
        *(.gnu.version_r)
        *(.eh_frame)
        /*  C++ constructor and destructor tables, properly ordered:  */
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*(.ctors))
        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*(.dtors))
        /*  C++ exception handlers table:  */
        __XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
        *(.xt_except_desc)
        *(.gnu.linkonce.h.*)
        __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
        *(.xt_except_desc_end)
        *(.dynamic)
        *(.gnu.version_d)
        . = ALIGN(4);        /* this table MUST be 4-byte aligned */
        _bss_table_start = ABSOLUTE(.);
        LONG(_bss_start)
        LONG(_bss_end)
        _bss_table_end = ABSOLUTE(.);
        _rodata_end = ABSOLUTE(.);
    } >dram0_0_seg :dram0_0_phdr

    .bss ALIGN(8) (NOLOAD) : ALIGN(4)
    {
        . = ALIGN (8);
        _bss_start = ABSOLUTE(.);
        *(.dynsbss)
        *(.sbss)
        *(.sbss.*)
        *(.gnu.linkonce.sb.*)
        *(.scommon)
        *(.sbss2)
        *(.sbss2.*)
        *(.gnu.linkonce.sb2.*)
        *(.dynbss)
        *(.bss)
        *(.bss.*)
        *(.gnu.linkonce.b.*)
        *(COMMON)
        . = ALIGN (8);
        _bss_end = ABSOLUTE(.);
        _heap_start = ABSOLUTE(.);
    } >dram0_0_seg :dram0_0_bss_phdr
}

/* get ROM code address */
INCLUDE "eagle.rom.addr.v6.ld"


Let's use both flash banks for now.

Let's use both flash banks for now.

/* Copyright 2018 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Note: modifications to prog and appram should be reflected in
   userspace/layout.ld or Rust userspace (and tests) will fail. */
MEMORY
{
  rom (rx)     : ORIGIN = 0x00044400, LENGTH = 0x00031c00
  prog (rx)    : ORIGIN = 0x00076000, LENGTH = 0x00040000
  ram (rwx)    : ORIGIN = 0x00010000, LENGTH = 0x00004000
  appram (rwx) : ORIGIN = 0x00014000, LENGTH = 0x0000c000
}

MPU_MIN_ALIGN = 8K;

/* Copyright 2018 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Note: modifications to prog and appram should be reflected in
   userspace/layout.ld or Rust userspace (and tests) will fail. */
MEMORY
{
  rom (rx)     : ORIGIN = 0x00044400, LENGTH = 0x00031c00
  prog (rx)    : ORIGIN = 0x00076000, LENGTH = 0x00010000
  ram (rwx)    : ORIGIN = 0x00010000, LENGTH = 0x00004000
  appram (rwx) : ORIGIN = 0x00014000, LENGTH = 0x0000c000
}

MPU_MIN_ALIGN = 8K;


[build] Make the kernel linker script to set section paddrs

By setting correctly the physical address of the program headers,
now qemu can correctly load the exOS kernel this way:

   qemu-system-i386 -m 256 -kernel ./build/elf_kernel_stripped

Clearly, this is not enough since also the ramdisk has to be loaded too.

OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SEARCH_DIR("=/tmp/x86-i686--glibc--stable/usr/i686-buildroot-linux-gnu/lib32");
SEARCH_DIR("=/tmp/x86-i686--glibc--stable/usr/i686-buildroot-linux-gnu/lib");

kernel_base_va = 0xC0000000;
kernel_paddr   = 0x00100000;

SECTIONS
{
  . = SEGMENT_START("text-segment", kernel_base_va + kernel_paddr);

  .text : AT(kernel_paddr)
  {
    code = .;
    *(.text.unlikely .text.*_unlikely .text.unlikely.*)
    *(.text.exit .text.exit.*)
    *(.text.startup .text.startup.*)
    *(.text.hot .text.hot.*)
    *(.text .stub .text.* .gnu.linkonce.t.*)
    *(.rodata .rodata.* .gnu.linkonce.r.*)
    . = ALIGN(4096);
  }

  .data : AT(kernel_paddr + (data - code))
  {
    data = .;
    *(.data .data.* .gnu.linkonce.d.*)
    . = ALIGN(4096);
  }

  .bss : AT(kernel_paddr + (bss - code))
  {
    bss = .;
    *(.bss .bss.* .gnu.linkonce.b.*)
  }

  . = ALIGN(4);
  _end = .;

  /DISCARD/ : { *(.eh_frame*) }

}

OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SEARCH_DIR("=/tmp/x86-i686--glibc--stable/usr/i686-buildroot-linux-gnu/lib32");
SEARCH_DIR("=/tmp/x86-i686--glibc--stable/usr/i686-buildroot-linux-gnu/lib");

kernel_base_va = 0xC0000000;

SECTIONS
{
  . = SEGMENT_START("text-segment", kernel_base_va + 0x100000);

  .text :
  {
    *(.text.unlikely .text.*_unlikely .text.unlikely.*)
    *(.text.exit .text.exit.*)
    *(.text.startup .text.startup.*)
    *(.text.hot .text.hot.*)
    *(.text .stub .text.* .gnu.linkonce.t.*)
    *(.rodata .rodata.* .gnu.linkonce.r.*)
    . = ALIGN(4096);
  }

  .data :
  {
    *(.data .data.* .gnu.linkonce.d.*)
    . = ALIGN(4096);
  }

  .bss :
  {
   *(.bss .bss.* .gnu.linkonce.b.*)
  }

  . = ALIGN(4);
  _end = .;

  /DISCARD/ : { *(.eh_frame*) }

}


esp8266: Move more rodata to irom section.

rodata can only go in iram/irom if it's accessed only using word loads
(ie no byte or half-word access).

/* GNU linker script for ESP8266 */

MEMORY
{
    dport0_0_seg : org = 0x3ff00000, len = 0x10
    dram0_0_seg :  org = 0x3ffe8000, len = 0x14000
    iram1_0_seg :  org = 0x40100000, len = 0x8000
    irom0_0_seg :  org = 0x40210000, len = 0x40000
}

/* define the top of RAM */
_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg);

PHDRS
{
    dport0_0_phdr PT_LOAD;
    dram0_0_phdr PT_LOAD;
    dram0_0_bss_phdr PT_LOAD;
    iram1_0_phdr PT_LOAD;
    irom0_0_phdr PT_LOAD;
}

ENTRY(call_user_start)

PROVIDE(_memmap_vecbase_reset = 0x40000000);

/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00000110;
_memmap_cacheattr_wt_base = 0x00000110;
_memmap_cacheattr_bp_base = 0x00000220;
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
_memmap_cacheattr_wb_trapnull = 0x2222211F;
_memmap_cacheattr_wba_trapnull = 0x2222211F;
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
_memmap_cacheattr_wt_trapnull = 0x2222211F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
_memmap_cacheattr_wb_allvalid = 0x22222112;
_memmap_cacheattr_wt_allvalid = 0x22222112;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);

SECTIONS
{

    .dport0.rodata : ALIGN(4)
    {
        _dport0_rodata_start = ABSOLUTE(.);
        *(.dport0.rodata)
        *(.dport.rodata)
        _dport0_rodata_end = ABSOLUTE(.);
    } >dport0_0_seg :dport0_0_phdr

    .dport0.literal : ALIGN(4)
    {
        _dport0_literal_start = ABSOLUTE(.);
        *(.dport0.literal)
        *(.dport.literal)
        _dport0_literal_end = ABSOLUTE(.);
    } >dport0_0_seg :dport0_0_phdr

    .dport0.data : ALIGN(4)
    {
        _dport0_data_start = ABSOLUTE(.);
        *(.dport0.data)
        *(.dport.data)
        _dport0_data_end = ABSOLUTE(.);
    } >dport0_0_seg :dport0_0_phdr

    .irom0.text : ALIGN(4)
    {
        _irom0_text_start = ABSOLUTE(.);
        *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)

        /* we put some specific text in this section */
        *py/*.o*(.literal* .text*)
        *pyexec.o(.literal*, .text*)
        *readline.o(.literal*, .text*)
        *pybstdio.o(.literal*, .text*)
        *modpyb.o(.literal*, .text*)
        *gccollect.o(.literal* .text*)
        *gchelper.o(.literal* .text*)

        /* we put as much rodata as possible in this section */
        /* note that only rodata accessed as a machine word is allowed here */
        *py/qstr.o(.rodata.const_pool)
        *py/*.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */
        *py/*.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */
        *py/*.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */

        _irom0_text_end = ABSOLUTE(.);
    } >irom0_0_seg :irom0_0_phdr

    .text : ALIGN(4)
    {
        _stext = .;
        _text_start = ABSOLUTE(.);
        *(.entry.text)
        *(.init.literal)
        *(.init)
        *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
        *(.fini.literal)
        *(.fini)
        *(.gnu.version)
        _text_end = ABSOLUTE(.);
        _etext = .;
    } >iram1_0_seg :iram1_0_phdr

    .lit4 : ALIGN(4)
    {
        _lit4_start = ABSOLUTE(.);
        *(*.lit4)
        *(.lit4.*)
        *(.gnu.linkonce.lit4.*)
        _lit4_end = ABSOLUTE(.);
    } >iram1_0_seg :iram1_0_phdr

    .data : ALIGN(4)
    {
        _data_start = ABSOLUTE(.);
        *(.data)
        *(.data.*)
        *(.gnu.linkonce.d.*)
        *(.data1)
        *(.sdata)
        *(.sdata.*)
        *(.gnu.linkonce.s.*)
        *(.sdata2)
        *(.sdata2.*)
        *(.gnu.linkonce.s2.*)
        *(.jcr)
        _data_end = ABSOLUTE(.);
    } >dram0_0_seg :dram0_0_phdr

    .rodata : ALIGN(4)
    {
        _rodata_start = ABSOLUTE(.);
        *(.rodata)
        *(.rodata.*)
        *(.gnu.linkonce.r.*)
        *(.rodata1)
        __XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
        *(.xt_except_table)
        *(.gcc_except_table)
        *(.gnu.linkonce.e.*)
        *(.gnu.version_r)
        *(.eh_frame)
        /*  C++ constructor and destructor tables, properly ordered:  */
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*(.ctors))
        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*(.dtors))
        /*  C++ exception handlers table:  */
        __XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
        *(.xt_except_desc)
        *(.gnu.linkonce.h.*)
        __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
        *(.xt_except_desc_end)
        *(.dynamic)
        *(.gnu.version_d)
        . = ALIGN(4);        /* this table MUST be 4-byte aligned */
        _bss_table_start = ABSOLUTE(.);
        LONG(_bss_start)
        LONG(_bss_end)
        _bss_table_end = ABSOLUTE(.);
        _rodata_end = ABSOLUTE(.);
    } >dram0_0_seg :dram0_0_phdr

    .bss ALIGN(8) (NOLOAD) : ALIGN(4)
    {
        . = ALIGN (8);
        _bss_start = ABSOLUTE(.);
        *(.dynsbss)
        *(.sbss)
        *(.sbss.*)
        *(.gnu.linkonce.sb.*)
        *(.scommon)
        *(.sbss2)
        *(.sbss2.*)
        *(.gnu.linkonce.sb2.*)
        *(.dynbss)
        *(.bss)
        *(.bss.*)
        *(.gnu.linkonce.b.*)
        *(COMMON)
        . = ALIGN (8);
        _bss_end = ABSOLUTE(.);
        _heap_start = ABSOLUTE(.);
    } >dram0_0_seg :dram0_0_bss_phdr
}

/* get ROM code address */
INCLUDE "eagle.rom.addr.v6.ld"

/* GNU linker script for ESP8266 */

MEMORY
{
    dport0_0_seg : org = 0x3ff00000, len = 0x10
    dram0_0_seg :  org = 0x3ffe8000, len = 0x14000
    iram1_0_seg :  org = 0x40100000, len = 0x8000
    irom0_0_seg :  org = 0x40210000, len = 0x40000
}

/* define the top of RAM */
_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg);

PHDRS
{
    dport0_0_phdr PT_LOAD;
    dram0_0_phdr PT_LOAD;
    dram0_0_bss_phdr PT_LOAD;
    iram1_0_phdr PT_LOAD;
    irom0_0_phdr PT_LOAD;
}

ENTRY(call_user_start)

PROVIDE(_memmap_vecbase_reset = 0x40000000);

/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00000110;
_memmap_cacheattr_wt_base = 0x00000110;
_memmap_cacheattr_bp_base = 0x00000220;
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
_memmap_cacheattr_wb_trapnull = 0x2222211F;
_memmap_cacheattr_wba_trapnull = 0x2222211F;
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
_memmap_cacheattr_wt_trapnull = 0x2222211F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
_memmap_cacheattr_wb_allvalid = 0x22222112;
_memmap_cacheattr_wt_allvalid = 0x22222112;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);

SECTIONS
{

    .dport0.rodata : ALIGN(4)
    {
        _dport0_rodata_start = ABSOLUTE(.);
        *(.dport0.rodata)
        *(.dport.rodata)
        _dport0_rodata_end = ABSOLUTE(.);
    } >dport0_0_seg :dport0_0_phdr

    .dport0.literal : ALIGN(4)
    {
        _dport0_literal_start = ABSOLUTE(.);
        *(.dport0.literal)
        *(.dport.literal)
        _dport0_literal_end = ABSOLUTE(.);
    } >dport0_0_seg :dport0_0_phdr

    .dport0.data : ALIGN(4)
    {
        _dport0_data_start = ABSOLUTE(.);
        *(.dport0.data)
        *(.dport.data)
        _dport0_data_end = ABSOLUTE(.);
    } >dport0_0_seg :dport0_0_phdr

    .irom0.text : ALIGN(4)
    {
        _irom0_text_start = ABSOLUTE(.);
        *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
        *py*.o*(.literal* .text*)
        *gccollect.o*(.literal* .text*)
        *gchelper.o*(.literal* .text*)
        _irom0_text_end = ABSOLUTE(.);
    } >irom0_0_seg :irom0_0_phdr

    .text : ALIGN(4)
    {
        _stext = .;
        _text_start = ABSOLUTE(.);
        *(.entry.text)
        *(.init.literal)
        *(.init)
        *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
        *(.fini.literal)
        *(.fini)
        *(.gnu.version)
        *qstr.o(.rodata.const_pool)
        *.o(.rodata.mp_type_*)
        /*
        can't put these here for some reason...
        *builtin.o(.rodata.mp_builtin_*_obj)
        *parse.o(.rodata.rule_*)
        */
        _text_end = ABSOLUTE(.);
        _etext = .;
    } >iram1_0_seg :iram1_0_phdr

    .lit4 : ALIGN(4)
    {
        _lit4_start = ABSOLUTE(.);
        *(*.lit4)
        *(.lit4.*)
        *(.gnu.linkonce.lit4.*)
        _lit4_end = ABSOLUTE(.);
    } >iram1_0_seg :iram1_0_phdr

    .data : ALIGN(4)
    {
        _data_start = ABSOLUTE(.);
        *(.data)
        *(.data.*)
        *(.gnu.linkonce.d.*)
        *(.data1)
        *(.sdata)
        *(.sdata.*)
        *(.gnu.linkonce.s.*)
        *(.sdata2)
        *(.sdata2.*)
        *(.gnu.linkonce.s2.*)
        *(.jcr)
        _data_end = ABSOLUTE(.);
    } >dram0_0_seg :dram0_0_phdr

    .rodata : ALIGN(4)
    {
        _rodata_start = ABSOLUTE(.);
        *(.rodata)
        *(.rodata.*)
        *(.gnu.linkonce.r.*)
        *(.rodata1)
        __XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
        *(.xt_except_table)
        *(.gcc_except_table)
        *(.gnu.linkonce.e.*)
        *(.gnu.version_r)
        *(.eh_frame)
        /*  C++ constructor and destructor tables, properly ordered:  */
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*(.ctors))
        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*(.dtors))
        /*  C++ exception handlers table:  */
        __XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
        *(.xt_except_desc)
        *(.gnu.linkonce.h.*)
        __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
        *(.xt_except_desc_end)
        *(.dynamic)
        *(.gnu.version_d)
        . = ALIGN(4);        /* this table MUST be 4-byte aligned */
        _bss_table_start = ABSOLUTE(.);
        LONG(_bss_start)
        LONG(_bss_end)
        _bss_table_end = ABSOLUTE(.);
        _rodata_end = ABSOLUTE(.);
    } >dram0_0_seg :dram0_0_phdr

    .bss ALIGN(8) (NOLOAD) : ALIGN(4)
    {
        . = ALIGN (8);
        _bss_start = ABSOLUTE(.);
        *(.dynsbss)
        *(.sbss)
        *(.sbss.*)
        *(.gnu.linkonce.sb.*)
        *(.scommon)
        *(.sbss2)
        *(.sbss2.*)
        *(.gnu.linkonce.sb2.*)
        *(.dynbss)
        *(.bss)
        *(.bss.*)
        *(.gnu.linkonce.b.*)
        *(COMMON)
        . = ALIGN (8);
        _bss_end = ABSOLUTE(.);
        _heap_start = ABSOLUTE(.);
    } >dram0_0_seg :dram0_0_bss_phdr
}

/* get ROM code address */
INCLUDE "eagle.rom.addr.v6.ld"


STM32H747_CM4: add RAM_D3 memory section

/* Linker script to configure memory regions. */
/*
 * SPDX-License-Identifier: BSD-3-Clause
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2016-2020 STMicroelectronics.
 * All rights reserved.
 *
 * This software component is licensed by ST under BSD 3-Clause license,
 * the "License"; You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                        opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************
*/

#include "../cmsis_nvic.h"

#if !defined(MBED_APP_START)
  #define MBED_APP_START  MBED_ROM_START
#endif

#if !defined(MBED_APP_SIZE)
  #define MBED_APP_SIZE  MBED_ROM_SIZE
#endif

#if !defined(MBED_CONF_TARGET_BOOT_STACK_SIZE)
    /* This value is normally defined by the tools
       to 0x1000 for bare metal and 0x400 for RTOS */
    #define MBED_CONF_TARGET_BOOT_STACK_SIZE  0x400
#endif

/* Round up VECTORS_SIZE to 8 bytes */
#define VECTORS_SIZE  (((NVIC_NUM_VECTORS * 4) + 7) & 0xFFFFFFF8)

MEMORY
{
    FLASH (rx)   : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE
    RAM (rwx)    : ORIGIN = MBED_RAM_START + VECTORS_SIZE, LENGTH = MBED_RAM_SIZE - VECTORS_SIZE
    RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
}

/* Linker script to place sections and symbol values. Should be used together
 * with other linker script that defines memory regions FLASH and RAM.
 * It references following symbols, which must be defined in code:
 *   Reset_Handler : Entry of reset handler
 *
 * It defines following symbols, which code can use without definition:
 *   __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
 *   _estack
 */
ENTRY(Reset_Handler)

SECTIONS
{
    .text :
    {
        KEEP(*(.isr_vector))
        *(.text*)

        KEEP(*(.init))
        KEEP(*(.fini))

        /* .ctors */
        *crtbegin.o(.ctors)
        *crtbegin?.o(.ctors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
        *(SORT(.ctors.*))
        *(.ctors)

        /* .dtors */
        *crtbegin.o(.dtors)
        *crtbegin?.o(.dtors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
        *(SORT(.dtors.*))
        *(.dtors)

        *(.rodata*)

        KEEP(*(.eh_frame*))
    } > FLASH

    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > FLASH

    __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    __exidx_end = .;

    __etext = .;
    _sidata = .;

    .data : AT (__etext)
    {
        __data_start__ = .;
        _sdata = .;
        *(vtable)
        *(.data*)

        . = ALIGN(8);
        /* preinit data */
        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP(*(.preinit_array))
        PROVIDE_HIDDEN (__preinit_array_end = .);

        . = ALIGN(8);
        /* init data */
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP(*(SORT(.init_array.*)))
        KEEP(*(.init_array))
        PROVIDE_HIDDEN (__init_array_end = .);

        . = ALIGN(8);
        /* finit data */
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP(*(SORT(.fini_array.*)))
        KEEP(*(.fini_array))
        PROVIDE_HIDDEN (__fini_array_end = .);

        KEEP(*(.jcr*))
        . = ALIGN(8);
        /* All data end */
        __data_end__ = .;
        _edata = .;

    } > RAM

    /* Uninitialized data section
     * This region is not initialized by the C/C++ library and can be used to
     * store state across soft reboots. */
    .uninitialized (NOLOAD):
    {
        . = ALIGN(32);
        __uninitialized_start = .;
        *(.uninitialized)
        KEEP(*(.keep.uninitialized))
        . = ALIGN(32);
        __uninitialized_end = .;
    } > RAM

    .bss :
    {
        . = ALIGN(8);
        __bss_start__ = .;
        _sbss = .;
        *(.bss*)
        *(COMMON)
        . = ALIGN(8);
        __bss_end__ = .;
        _ebss = .;
    } > RAM

    .heap (COPY):
    {
        __end__ = .;
        PROVIDE(end = .);
        *(.heap*)
        . = ORIGIN(RAM) + LENGTH(RAM) - MBED_CONF_TARGET_BOOT_STACK_SIZE;
        __HeapLimit = .;
    } > RAM

    /* .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 */
    .stack_dummy (COPY):
    {
        *(.stack*)
    } > RAM

    /* Set stack top to end of RAM, and stack limit move down by
     * size of stack_dummy section */
    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
    _estack = __StackTop;
    __StackLimit = __StackTop - MBED_CONF_TARGET_BOOT_STACK_SIZE;
    PROVIDE(__stack = __StackTop);

    /* Check if data + heap + stack exceeds RAM limit */
    ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

/* Linker script to configure memory regions. */
/*
 * SPDX-License-Identifier: BSD-3-Clause
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2016-2020 STMicroelectronics.
 * All rights reserved.
 *
 * This software component is licensed by ST under BSD 3-Clause license,
 * the "License"; You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                        opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************
*/

#include "../cmsis_nvic.h"

#if !defined(MBED_APP_START)
  #define MBED_APP_START  MBED_ROM_START
#endif

#if !defined(MBED_APP_SIZE)
  #define MBED_APP_SIZE  MBED_ROM_SIZE
#endif

#if !defined(MBED_CONF_TARGET_BOOT_STACK_SIZE)
    /* This value is normally defined by the tools
       to 0x1000 for bare metal and 0x400 for RTOS */
    #define MBED_CONF_TARGET_BOOT_STACK_SIZE  0x400
#endif

/* Round up VECTORS_SIZE to 8 bytes */
#define VECTORS_SIZE  (((NVIC_NUM_VECTORS * 4) + 7) & 0xFFFFFFF8)

MEMORY
{
    FLASH (rx)   : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE
    RAM (rwx)    : ORIGIN = MBED_RAM_START + VECTORS_SIZE, LENGTH = MBED_RAM_SIZE - VECTORS_SIZE
}

/* Linker script to place sections and symbol values. Should be used together
 * with other linker script that defines memory regions FLASH and RAM.
 * It references following symbols, which must be defined in code:
 *   Reset_Handler : Entry of reset handler
 *
 * It defines following symbols, which code can use without definition:
 *   __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
 *   _estack
 */
ENTRY(Reset_Handler)

SECTIONS
{
    .text :
    {
        KEEP(*(.isr_vector))
        *(.text*)

        KEEP(*(.init))
        KEEP(*(.fini))

        /* .ctors */
        *crtbegin.o(.ctors)
        *crtbegin?.o(.ctors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
        *(SORT(.ctors.*))
        *(.ctors)

        /* .dtors */
        *crtbegin.o(.dtors)
        *crtbegin?.o(.dtors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
        *(SORT(.dtors.*))
        *(.dtors)

        *(.rodata*)

        KEEP(*(.eh_frame*))
    } > FLASH

    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > FLASH

    __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    __exidx_end = .;

    __etext = .;
    _sidata = .;

    .data : AT (__etext)
    {
        __data_start__ = .;
        _sdata = .;
        *(vtable)
        *(.data*)

        . = ALIGN(8);
        /* preinit data */
        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP(*(.preinit_array))
        PROVIDE_HIDDEN (__preinit_array_end = .);

        . = ALIGN(8);
        /* init data */
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP(*(SORT(.init_array.*)))
        KEEP(*(.init_array))
        PROVIDE_HIDDEN (__init_array_end = .);

        . = ALIGN(8);
        /* finit data */
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP(*(SORT(.fini_array.*)))
        KEEP(*(.fini_array))
        PROVIDE_HIDDEN (__fini_array_end = .);

        KEEP(*(.jcr*))
        . = ALIGN(8);
        /* All data end */
        __data_end__ = .;
        _edata = .;

    } > RAM

    /* Uninitialized data section
     * This region is not initialized by the C/C++ library and can be used to
     * store state across soft reboots. */
    .uninitialized (NOLOAD):
    {
        . = ALIGN(32);
        __uninitialized_start = .;
        *(.uninitialized)
        KEEP(*(.keep.uninitialized))
        . = ALIGN(32);
        __uninitialized_end = .;
    } > RAM

    .bss :
    {
        . = ALIGN(8);
        __bss_start__ = .;
        _sbss = .;
        *(.bss*)
        *(COMMON)
        . = ALIGN(8);
        __bss_end__ = .;
        _ebss = .;
    } > RAM

    .heap (COPY):
    {
        __end__ = .;
        PROVIDE(end = .);
        *(.heap*)
        . = ORIGIN(RAM) + LENGTH(RAM) - MBED_CONF_TARGET_BOOT_STACK_SIZE;
        __HeapLimit = .;
    } > RAM

    /* .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 */
    .stack_dummy (COPY):
    {
        *(.stack*)
    } > RAM

    /* Set stack top to end of RAM, and stack limit move down by
     * size of stack_dummy section */
    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
    _estack = __StackTop;
    __StackLimit = __StackTop - MBED_CONF_TARGET_BOOT_STACK_SIZE;
    PROVIDE(__stack = __StackTop);

    /* Check if data + heap + stack exceeds RAM limit */
    ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}


Fix whitespace in linker file

Fix whitespace in linker file

ENTRY(kstart)
OUTPUT_FORMAT(elf64-x86-64)

KERNEL_OFFSET = 0xFFFF800000100000;

SECTIONS {
    . = KERNEL_OFFSET;

    . += SIZEOF_HEADERS;
    . = ALIGN(4096);

    .text : AT(ADDR(.text) - KERNEL_OFFSET) {
        __text_start = .;
        *(.text*)
        . = ALIGN(4096);
        __text_end = .;
    }

    .rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) {
        __rodata_start = .;
        *(.rodata*)
        . = ALIGN(4096);
        __rodata_end = .;
    }

    .data : AT(ADDR(.data) - KERNEL_OFFSET) {
        __data_start = .;
        *(.data*)
        . = ALIGN(4096);
        __data_end = .;
        __bss_start = .;
        *(.bss*)
        . = ALIGN(4096);
        __bss_end = .;
    }

    .tdata : AT(ADDR(.tdata) - KERNEL_OFFSET) {
        __tdata_start = .;
        *(.tdata*)
        . = ALIGN(4096);
        __tdata_end = .;
        __tbss_start = .;
        *(.tbss*)
        . += 8;
        . = ALIGN(4096);
        __tbss_end = .;
    }

    __end = .;

    /DISCARD/ : {
        *(.comment*)
        *(.eh_frame*)
        *(.gcc_except_table*)
        *(.note*)
        *(.rel.eh_frame*)
    }
}


stmhal/boards/stm32f405.ld: Increase FLASH_TEXT to end of 1MiB flash.

And and FLASH_FS, and use "K" values instead of hex numbers for lengths.

The increase of FLASH_TEXT is to allow more frozen bytecode for a
particular user's project.  It's not used for anything else.

/*
    GNU linker script for STM32F405
*/

/* Specify the memory areas */
MEMORY
{
    FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K /* entire flash */
    FLASH_ISR (rx)  : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
    FLASH_FS (rx)   : ORIGIN = 0x08004000, LENGTH = 112K /* sectors 1,2,3,4 are for filesystem */
    FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 896K /* sectors 5,6,7,8,9,10,11 */
    CCMRAM (xrw)    : ORIGIN = 0x10000000, LENGTH = 64K
    RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 128K
}

/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_heap_size = 16K;

/* Define tho top end of the stack.  The stack is full descending so begins just
   above last byte of RAM.  Note that EABI requires the stack to be 8-byte
   aligned for a call. */
_estack = ORIGIN(RAM) + LENGTH(RAM);

/* define common sections and symbols */
INCLUDE common.ld

/* RAM extents for the garbage collector */
_ram_start = ORIGIN(RAM);
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_start = _ebss; /* heap starts just after statically allocated memory */
_heap_end = 0x2001c000; /* tunable */

/*
    GNU linker script for STM32F405
*/

/* Specify the memory areas */
MEMORY
{
    FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 0x100000 /* entire flash, 1 MiB */
    FLASH_ISR (rx)  : ORIGIN = 0x08000000, LENGTH = 0x004000 /* sector 0, 16 KiB */
    FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 0x080000 /* sectors 5,6,7,8, 4*128KiB = 512 KiB (could increase it more) */
    CCMRAM (xrw)    : ORIGIN = 0x10000000, LENGTH = 0x010000 /* 64 KiB */
    RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 0x020000 /* 128 KiB */
}

/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_heap_size = 16K;

/* Define tho top end of the stack.  The stack is full descending so begins just
   above last byte of RAM.  Note that EABI requires the stack to be 8-byte
   aligned for a call. */
_estack = ORIGIN(RAM) + LENGTH(RAM);

/* define common sections and symbols */
INCLUDE common.ld

/* RAM extents for the garbage collector */
_ram_start = ORIGIN(RAM);
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_start = _ebss; /* heap starts just after statically allocated memory */
_heap_end = 0x2001c000; /* tunable */


improve linker script

improve linker script

 - explicitly DISCARD .note and .comment section, so they don't appear
   in `ld -M` output
 - add some asterisks to support input objects created with
   `-ffunction-sections` and `-fdata-sections`

OUTPUT_FORMAT(binary)
SECTIONS
{
    . = 0x0100;
    .text :
    {
	*(.text*);
    }
    .data :
    {
	*(.data*);
	*(.rodata*);
	*(COMMON);
	*(.bss*);
    }
    /DISCARD/ :
    {
	*(.note*);
	*(.comment*);
    }
    _heap = ALIGN(4);
}

OUTPUT_FORMAT(binary)
SECTIONS
{
    . = 0x0100;
    .text :
    {
	*(.text);
    }
    .data :
    {
	*(.data);
	*(.rodata);
	*(COMMON);
	*(.bss);
    }
    _heap = ALIGN(4);
}


Working build

Working build

bare-metal-arm
==============

A fork of the baremetal runtime example for the FRDM-KL25Z by Andrew Payne.

Currently configured as an eclipse project with hard coded paths to the toolchain. This will be fixed in due course.


[bsp/taihu] fix the link error

[bsp/taihu] fix the link error

The taihu.lds hardcoded the path of start_gcc.o. Change it as the layout
of build/ has change by commit a03816ef9aa583bb.

OUTPUT_ARCH(powerpc)

/* Do we need any of these for elf?
   __DYNAMIC = 0;    */
SECTIONS
{
  .resetvec 0xFFFFFFFC :
  {
    *(.resetvec)
  } = 0xffff

  /* Read-only sections, merged into text segment: */
  . = + SIZEOF_HEADERS;
  .interp : { *(.interp) }
  .hash          : { *(.hash)           }
  .dynsym        : { *(.dynsym)         }
  .dynstr        : { *(.dynstr)         }
  .rel.text      : { *(.rel.text)       }
  .rela.text     : { *(.rela.text)      }
  .rel.data      : { *(.rel.data)       }
  .rela.data     : { *(.rela.data)      }
  .rel.rodata    : { *(.rel.rodata)     }
  .rela.rodata   : { *(.rela.rodata)    }
  .rel.got       : { *(.rel.got)        }
  .rela.got      : { *(.rela.got)       }
  .rel.ctors     : { *(.rel.ctors)      }
  .rela.ctors    : { *(.rela.ctors)     }
  .rel.dtors     : { *(.rel.dtors)      }
  .rela.dtors    : { *(.rela.dtors)     }
  .rel.bss       : { *(.rel.bss)        }
  .rela.bss      : { *(.rela.bss)       }
  .rel.plt       : { *(.rel.plt)        }
  .rela.plt      : { *(.rela.plt)       }
  /* .init          : { *(.init)           } */
  .plt : { *(.plt) }

  .text      :
  {
    KEEP(build/kernel/libcpu/ppc/ppc405/start_gcc.o (.text))

    *(.text)
    *(.fixup)
    *(.got1)
  }
  _etext = .;
  PROVIDE (etext = .);
  .rodata    :
  {
    *(.eh_frame)
    *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
    /* section information for finsh shell */
    . = ALIGN(4);
    __fsymtab_start = .;
    KEEP(*(FSymTab))
    __fsymtab_end = .;
    . = ALIGN(4);
    __vsymtab_start = .;
    KEEP(*(VSymTab))
    __vsymtab_end = .;
  }
  .fini      : { *(.fini)    } =0
  .ctors     : { *(.ctors)   }
  .dtors     : { *(.dtors)   }

  /* Read-write section, merged into data segment: */
  . = (. + 0x00FF) & 0xFFFFFF00;
  _erotext = .;
  PROVIDE (erotext = .);
  .reloc   :
  {
    *(.got)
    _GOT2_TABLE_ = .;
    *(.got2)
    _FIXUP_TABLE_ = .;
    *(.fixup)
  }
  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
  __fixup_entries = (. - _FIXUP_TABLE_)>>2;

  .data    :
  {
    *(.data)
    *(.data1)
    *(.sdata)
    *(.sdata2)
    *(.dynamic)
    CONSTRUCTORS
  }
  _edata  =  .;
  PROVIDE (edata = .);

  . = .;
  __start___ex_table = .;
  __ex_table : { *(__ex_table) }
  __stop___ex_table = .;

  . = ALIGN(256);
  __init_begin = .;
  .text.init : { *(.text.init) }
  .data.init : { *(.data.init) }
  . = ALIGN(256);
  __init_end = .;

  __bss_start = .;
  .bss (NOLOAD)       :
  {
   *(.sbss) *(.scommon)
   *(.dynbss)
   *(.bss)
   *(COMMON)
   . = ALIGN(4);
  }
  __bss_end = .;

  . = ALIGN(256);

  PROVIDE(__stack_bottom = .);
  . += 0x100000; /* 1MB */
  PROVIDE(__stack_top = .);

  . = ALIGN(256);
  PROVIDE (__heap_start = .);
  . += 0x500000; /* 5MB */
  PROVIDE(__heap_end = .);

  _end = . ;
  PROVIDE (end = .);
}

OUTPUT_ARCH(powerpc)

/* Do we need any of these for elf?
   __DYNAMIC = 0;    */
SECTIONS
{
  .resetvec 0xFFFFFFFC :
  {
    *(.resetvec)
  } = 0xffff

  /* Read-only sections, merged into text segment: */
  . = + SIZEOF_HEADERS;
  .interp : { *(.interp) }
  .hash          : { *(.hash)           }
  .dynsym        : { *(.dynsym)         }
  .dynstr        : { *(.dynstr)         }
  .rel.text      : { *(.rel.text)       }
  .rela.text     : { *(.rela.text)      }
  .rel.data      : { *(.rel.data)       }
  .rela.data     : { *(.rela.data)      }
  .rel.rodata    : { *(.rel.rodata)     }
  .rela.rodata   : { *(.rela.rodata)    }
  .rel.got       : { *(.rel.got)        }
  .rela.got      : { *(.rela.got)       }
  .rel.ctors     : { *(.rel.ctors)      }
  .rela.ctors    : { *(.rela.ctors)     }
  .rel.dtors     : { *(.rel.dtors)      }
  .rela.dtors    : { *(.rela.dtors)     }
  .rel.bss       : { *(.rel.bss)        }
  .rela.bss      : { *(.rela.bss)       }
  .rel.plt       : { *(.rel.plt)        }
  .rela.plt      : { *(.rela.plt)       }
  /* .init          : { *(.init)           } */
  .plt : { *(.plt) }

  .text      :
  {
    KEEP(build/libcpu/ppc/ppc405/start_gcc.o (.text))

    *(.text)
    *(.fixup)
    *(.got1)
  }
  _etext = .;
  PROVIDE (etext = .);
  .rodata    :
  {
    *(.eh_frame)
    *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
    /* section information for finsh shell */
    . = ALIGN(4);
    __fsymtab_start = .;
    KEEP(*(FSymTab))
    __fsymtab_end = .;
    . = ALIGN(4);
    __vsymtab_start = .;
    KEEP(*(VSymTab))
    __vsymtab_end = .;
  }
  .fini      : { *(.fini)    } =0
  .ctors     : { *(.ctors)   }
  .dtors     : { *(.dtors)   }

  /* Read-write section, merged into data segment: */
  . = (. + 0x00FF) & 0xFFFFFF00;
  _erotext = .;
  PROVIDE (erotext = .);
  .reloc   :
  {
    *(.got)
    _GOT2_TABLE_ = .;
    *(.got2)
    _FIXUP_TABLE_ = .;
    *(.fixup)
  }
  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
  __fixup_entries = (. - _FIXUP_TABLE_)>>2;

  .data    :
  {
    *(.data)
    *(.data1)
    *(.sdata)
    *(.sdata2)
    *(.dynamic)
    CONSTRUCTORS
  }
  _edata  =  .;
  PROVIDE (edata = .);

  . = .;
  __start___ex_table = .;
  __ex_table : { *(__ex_table) }
  __stop___ex_table = .;

  . = ALIGN(256);
  __init_begin = .;
  .text.init : { *(.text.init) }
  .data.init : { *(.data.init) }
  . = ALIGN(256);
  __init_end = .;

  __bss_start = .;
  .bss (NOLOAD)       :
  {
   *(.sbss) *(.scommon)
   *(.dynbss)
   *(.bss)
   *(COMMON)
   . = ALIGN(4);
  }
  __bss_end = .;

  . = ALIGN(256);

  PROVIDE(__stack_bottom = .);
  . += 0x100000; /* 1MB */
  PROVIDE(__stack_top = .);

  . = ALIGN(256);
  PROVIDE (__heap_start = .);
  . += 0x500000; /* 5MB */
  PROVIDE(__heap_end = .);

  _end = . ;
  PROVIDE (end = .);
}


examples: Small fix in comment.

examples: Small fix in comment.

/* Stack size: 6 KB */
StackLog2 = 13; /* 8 KB */
StackFrac = 6;  /* 6/8 */

/* Two gorutines, 3 stacks. */
MaxTasks = 2;

INCLUDE stm32/f411
INCLUDE stm32/loadram
INCLUDE noos-cortexm

/* Stack size: 6 KB */
StackLog2 = 13; /* 8 KB */
StackFrac = 6;  /* 6/8 */

/* One stack, without gorutines */
MaxTasks = 2;

INCLUDE stm32/f411
INCLUDE stm32/loadram
INCLUDE noos-cortexm


doc: fix LDoc manual page custom_see_handler pattern.

* ext/posix/config.ld (custom_see_handler): Add a missing closing
`%)`.
(upat): Pull the format string up per LDoc documentation.

Signed-off-by: Gary V. Vaughan <f9023000f29773649f3850298becb9544b5fd6a9@gnu.org>

-- -*- lua -*-
file = 'posix.c'
project = 'luaposix'
description = 'POSIX bindings for Lua'

tparam_alias 'string'
tparam_alias 'int'
tparam_alias 'bool'

local upat = "http://www.kernel.org/doc/man-pages/online/pages/man%s/%s.%s.html"
custom_see_handler('^([%w_]+)%((%d)%)$',function(name,section)
    local url = upat:format(section,name,section)
    local name = name .. '(' .. section .. ')'
    return name, url
end)

examples = 'examples'

format = 'discount'

-- -*- lua -*-
file = 'posix.c'
project = 'luaposix'
description = 'POSIX bindings for Lua'

tparam_alias 'string'
tparam_alias 'int'
tparam_alias 'bool'

custom_see_handler('^([%w_]+)%((%d)$',function(name,section)
    local url = ("http://www.kernel.org/doc/man-pages/online/pages/man%s/%s.%s.html"):format(section,name,section)
    local name = name .. '(' ..section..')'
    return name, url
end)

examples = 'examples'

format = 'discount'


remove comment confusing py tools

remove comment confusing py tools

/*
    GNU linker script for STM32F401 with bootloader (from Meowbit Micropython)
    Doesn't work:

    Traceback (most recent call last):
  File "../../tools/build_memory_info.py", line 64, in <module>
    regions[region] = int(eval(space))
  File "<string>", line 1, in <module>
NameError: name 'FLASH_ISR' is not defined
*/

/* Specify the memory areas */
/*     FLASH_FS (rx)   : ORIGIN = 0x08020000, LENGTH = 128K */
/* sectors 5 128K */
MEMORY
{
    FLASH (rx)      : ORIGIN = 0x08010000, LENGTH = 512K - 64K /* entire flash */
    FLASH_ISR (rx)  : ORIGIN = 0x08010000, LENGTH = 64K /* sector 4, sec 0~3 reserved for booloader */
    FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 384K /* sectors 5, 6,7 are 128K */
    RAM (xrw)       : ORIGIN = 0x20000194, LENGTH = 96K - 0x194
}

/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_heap_size = 16K;

/* Define the stack.  The stack is full descending so begins just above last byte
   of RAM.  Note that EABI requires the stack to be 8-byte aligned for a call. */
_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve;
_sstack = _estack - 16K; /* tunable */

/* RAM extents for the garbage collector */
_ram_start = ORIGIN(RAM);
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_start = _ebss; /* heap starts just after statically allocated memory */
_heap_end = _sstack;

ENTRY(Reset_Handler)

/* define output sections */
SECTIONS
{
    /* The startup code goes first into FLASH */
    .isr_vector :
    {
        . = ALIGN(4);
        KEEP(*(.isr_vector)) /* Startup code */

        /* This first flash block is 16K annd the isr vectors only take up
           about 400 bytes. So we pull in a couple of object files to pad it
           out. */

        . = ALIGN(4);

        /* NOTE: If you update the list of files contained in .isr_vector,
                 then be sure to also update smhal/Makefile where it forcibly
           builds each of these files with -Os */

        */ff.o(.text*)
        */vfs_fat_*.o(.text*)
        */py/formatfloat.o(.text*)
        */py/parsenum.o(.text*)
        */py/mpprint.o(.text*)

        */py/compile.o(.text*)
        */py/objset.o(.text*)
        */py/mpz.o(.text*)
        */py/vm.o(.text*)

        . = ALIGN(4);
    } >FLASH_ISR

    /* The program code and other data goes into FLASH */
    .text :
    {
        . = ALIGN(4);
        *(.text*)          /* .text* sections (code) */
        *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    /*  *(.glue_7)   */    /* glue arm to thumb code */
    /*  *(.glue_7t)  */    /* glue thumb to arm code */

        . = ALIGN(4);
        _etext = .;        /* define a global symbol at end of code */
    } >FLASH_TEXT

    /* used by the startup to initialize data */
    _sidata = LOADADDR(.data);

    /* This is the initialized data section
    The program executes knowing that the data is in the RAM
    but the loader puts the initial values in the FLASH (inidata).
    It is one task of the startup to copy the initial values from FLASH to RAM. */
    .data :
    {
        . = ALIGN(4);
        _sdata = .;        /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
        *(.data*)          /* .data* sections */

        . = ALIGN(4);
        _edata = .;        /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
    } >RAM AT> FLASH_TEXT

    /* Uninitialized data section */
    .bss :
    {
        . = ALIGN(4);
        _sbss = .;         /* define a global symbol at bss start; used by startup code */
        *(.bss*)
        *(COMMON)

        . = ALIGN(4);
        _ebss = .;         /* define a global symbol at bss end; used by startup code and GC */
    } >RAM

    /* this is to define the start of the heap, and make sure we have a minimum size */
    .heap :
    {
        . = ALIGN(4);
        . = . + _minimum_heap_size;
        . = ALIGN(4);
    } >RAM

    /* this just checks there is enough RAM for the stack */
    .stack :
    {
        . = ALIGN(4);
        . = . + _minimum_stack_size;
        . = ALIGN(4);
    } >RAM

    .ARM.attributes 0 : { *(.ARM.attributes) }
}

/*
    GNU linker script for STM32F401 with bootloader (from Meowbit Micropython)
    Doesn't work:

    Traceback (most recent call last):
  File "../../tools/build_memory_info.py", line 64, in <module>
    regions[region] = int(eval(space))
  File "<string>", line 1, in <module>
NameError: name 'FLASH_ISR' is not defined
*/

/* Specify the memory areas */
/*     FLASH_FS (rx)   : ORIGIN = 0x08020000, LENGTH = 128K */
/* sectors 5 128K */
MEMORY
{
    FLASH (rx)      : ORIGIN = 0x08010000, LENGTH = 512K - 64K /* entire flash */
    FLASH_ISR (rx)  : ORIGIN = 0x08010000, LENGTH = 64K /* sector 4, sec 0~3 reserved for booloader */
    FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 384K /* sectors 5, 6,7 are 128K */
    RAM (xrw)       : ORIGIN = 0x20000194, LENGTH = 96K - 0x194
}

/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_heap_size = 16K;

/* Define the stack.  The stack is full descending so begins just above last byte
   of RAM.  Note that EABI requires the stack to be 8-byte aligned for a call. */
_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve;
_sstack = _estack - 16K; /* tunable */

/* RAM extents for the garbage collector */
_ram_start = ORIGIN(RAM);
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_start = _ebss; /* heap starts just after statically allocated memory */
_heap_end = _sstack;

/* Memory layout for internal flash storage configuration:

    FLASH_ISR   .isr_vector

    FLASH_TEXT  .text
    FLASH_TEXT  .data

    RAM         .data
    RAM         .bss
    RAM         .heap
    RAM         .stack
*/

ENTRY(Reset_Handler)

/* define output sections */
SECTIONS
{
    /* The startup code goes first into FLASH */
    .isr_vector :
    {
        . = ALIGN(4);
        KEEP(*(.isr_vector)) /* Startup code */

        /* This first flash block is 16K annd the isr vectors only take up
           about 400 bytes. So we pull in a couple of object files to pad it
           out. */

        . = ALIGN(4);

        /* NOTE: If you update the list of files contained in .isr_vector,
                 then be sure to also update smhal/Makefile where it forcibly
           builds each of these files with -Os */

        */ff.o(.text*)
        */vfs_fat_*.o(.text*)
        */py/formatfloat.o(.text*)
        */py/parsenum.o(.text*)
        */py/mpprint.o(.text*)

        */py/compile.o(.text*)
        */py/objset.o(.text*)
        */py/mpz.o(.text*)
        */py/vm.o(.text*)

        . = ALIGN(4);
    } >FLASH_ISR

    /* The program code and other data goes into FLASH */
    .text :
    {
        . = ALIGN(4);
        *(.text*)          /* .text* sections (code) */
        *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    /*  *(.glue_7)   */    /* glue arm to thumb code */
    /*  *(.glue_7t)  */    /* glue thumb to arm code */

        . = ALIGN(4);
        _etext = .;        /* define a global symbol at end of code */
    } >FLASH_TEXT

    /* used by the startup to initialize data */
    _sidata = LOADADDR(.data);

    /* This is the initialized data section
    The program executes knowing that the data is in the RAM
    but the loader puts the initial values in the FLASH (inidata).
    It is one task of the startup to copy the initial values from FLASH to RAM. */
    .data :
    {
        . = ALIGN(4);
        _sdata = .;        /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
        *(.data*)          /* .data* sections */

        . = ALIGN(4);
        _edata = .;        /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
    } >RAM AT> FLASH_TEXT

    /* Uninitialized data section */
    .bss :
    {
        . = ALIGN(4);
        _sbss = .;         /* define a global symbol at bss start; used by startup code */
        *(.bss*)
        *(COMMON)

        . = ALIGN(4);
        _ebss = .;         /* define a global symbol at bss end; used by startup code and GC */
    } >RAM

    /* this is to define the start of the heap, and make sure we have a minimum size */
    .heap :
    {
        . = ALIGN(4);
        . = . + _minimum_heap_size;
        . = ALIGN(4);
    } >RAM

    /* this just checks there is enough RAM for the stack */
    .stack :
    {
        . = ALIGN(4);
        . = . + _minimum_stack_size;
        . = ALIGN(4);
    } >RAM

    .ARM.attributes 0 : { *(.ARM.attributes) }
}


Shrink the memory region to avoid affacting RedBoot

ENTRY (main)

MEMORY
{
ram : ORIGIN = 0x00001024, LENGTH = 30M
rom : ORIGIN = 0x60000000, LENGTH = 8M
}

SECTIONS
{
data : /* Initialized data. */
{
_DataStart = . ;
*(.data)
_DataEnd = . ;
} >ram

bss : /* Uninitialized data. */
{
_BssStart = . ;
*(.bss)
_BssEnd = . ;
} >ram

text : /* The actual instructions. */
{
*(.text)
*(.got)
*(.got.plt)
*(.rodata)
*(.glue_7)
*(.glue_7t)
} >ram
}

ENTRY (main)

MEMORY
{
ram : ORIGIN = 0x00000000, LENGTH = 32M
rom : ORIGIN = 0x60000000, LENGTH = 8M
}

SECTIONS
{
data : /* Initialized data. */
{
_DataStart = . ;
*(.data)
_DataEnd = . ;
} >ram

bss : /* Uninitialized data. */
{
_BssStart = . ;
*(.bss)
_BssEnd = . ;
} >ram

text : /* The actual instructions. */
{
*(.text)
*(.got)
*(.got.plt)
*(.rodata)
*(.glue_7)
*(.glue_7t)
} >ram
}


THE KERNEL STARTS AFTER THE FIRST MEGABYTE

ENTRY (main)

MEMORY
{
  ram : ORIGIN = 0x00100000, LENGTH = 31M
  rom : ORIGIN = 0x60000000, LENGTH = 8M
}

SECTIONS
{
  .data : /* Initialized data. */
  {
    _DataStart = . ;
    *(.data.kern)
    _DataKernEnd = . ;
    *(.data)
    *(.data.rel.local)
    _DataEnd = . ;
  } >ram

  .bss : /* Uninitialized data. */
  {
    _BssStart = . ;
    *(.bss)
    *(.sbss)
    _BssEnd = . ;
  } >ram

  .text ALIGN(0x100): 	/* The actual instructions.          */
  {		      	/* Alignment ensures that data will  */
    _TextStart = . ;	/* not get loaded into the icache    */
    *(.text.kern)
    _TextKernEnd = . ;
    *(.text)
    *(.rodata)
    *(.rodata.str1.4)
    *(.glue_7)
    *(.glue_7t)
    _TextEnd = . ;
  } >ram
}

ENTRY (main)

MEMORY
{
  ram : ORIGIN = 0x00000000, LENGTH = 32M
  rom : ORIGIN = 0x60000000, LENGTH = 8M
}

SECTIONS
{
  .data 0x100000: /* Initialized data. */
  {
    _DataStart = . ;
    *(.data.kern)
    _DataKernEnd = . ;
    *(.data)
    *(.data.rel.local)
    _DataEnd = . ;
  } >ram

  .bss : /* Uninitialized data. */
  {
    _BssStart = . ;
    *(.bss)
    *(.sbss)
    _BssEnd = . ;
  } >ram

  .text ALIGN(0x100): 	/* The actual instructions.          */
  {		      	/* Alignment ensures that data will  */
    _TextStart = . ;	/* not get loaded into the icache    */
    *(.text.kern)
    _TextKernEnd = . ;
    *(.text)
    *(.rodata)
    *(.rodata.str1.4)
    *(.glue_7)
    *(.glue_7t)
    _TextEnd = . ;
  } >ram
}


Sort .text section to reduce fill on nRF

/*
    GNU linker script for NRF52840 w/ s140 6.0.0 SoftDevice
*/

/* Specify the memory areas */
MEMORY
{
    FLASH (rx)      : ORIGIN = 0x00000000, LENGTH = ${FLASH_SIZE} /* entire flash */
    /* nRF SoftDevice */
    FLASH_MBR (rx)  : ORIGIN = ${MBR_START_ADDR}, LENGTH = ${MBR_SIZE}
    FLASH_SD (rx)   : ORIGIN = ${SD_FLASH_START_ADDR}, LENGTH = ${SD_FLASH_SIZE}
    FLASH_ISR (rx)  : ORIGIN = ${ISR_START_ADDR}, LENGTH = ${ISR_SIZE}
    FLASH_FIRMWARE (rx) : ORIGIN = ${CIRCUITPY_FIRMWARE_START_ADDR}, LENGTH = ${CIRCUITPY_FIRMWARE_SIZE}
    FLASH_BLE_CONFIG (r) : ORIGIN = ${CIRCUITPY_BLE_CONFIG_START_ADDR}, LENGTH = ${CIRCUITPY_BLE_CONFIG_SIZE}
    FLASH_NVM (r)   : ORIGIN = ${CIRCUITPY_INTERNAL_NVM_START_ADDR}, LENGTH = ${CIRCUITPY_INTERNAL_NVM_SIZE}
    FLASH_FATFS (r) : ORIGIN = ${CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR}, LENGTH = ${CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE}
    FLASH_BOOTLOADER (rx) : ORIGIN = ${BOOTLOADER_START_ADDR}, LENGTH = ${BOOTLOADER_SIZE}
    FLASH_BOOTLOADER_SETTINGS (r) : ORIGIN = ${BOOTLOADER_SETTINGS_START_ADDR}, LENGTH = ${BOOTLOADER_SETTINGS_SIZE}

    /* SoftDevice RAM must start at the beginning of RAM: 0x2000000 (RAM_START_ADDR).
       On nRF52840, the first 64kB of RAM is composed of 8 8kB RAM blocks. Above those is
       RAM block 8, which is 192kB.
       If SPIM3_BUFFER_RAM_SIZE is 8kB, as opposed to zero, it must be in the first 64kB of RAM.
       So the amount of RAM reserved for the SoftDevice must be no more than 56kB.
    */
    RAM (xrw)       : ORIGIN = ${RAM_START_ADDR}, LENGTH = ${RAM_SIZE}
    SD_RAM (rw)     : ORIGIN = ${SOFTDEVICE_RAM_START_ADDR}, LENGTH = ${SOFTDEVICE_RAM_SIZE}
    SPIM3_RAM (rw)  : ORIGIN = ${SPIM3_BUFFER_RAM_START_ADDR}, LENGTH = ${SPIM3_BUFFER_RAM_SIZE}
    APP_RAM (xrw)   : ORIGIN = ${APP_RAM_START_ADDR}, LENGTH = ${APP_RAM_SIZE}
}

/* produce a link error if there is not this amount of RAM available */
_minimum_heap_size = 0;

/* top end of the stack */

/*_stack_end = ORIGIN(APP_RAM) + LENGTH(APP_RAM);*/
_estack = ORIGIN(APP_RAM) + LENGTH(APP_RAM);

/* RAM extents for the garbage collector */
_ram_end = ORIGIN(APP_RAM) + LENGTH(APP_RAM);
_heap_end = 0x20020000; /* tunable */

/* nrf52840 SPIM3 needs its own area to work around hardware problems. Nothing else may use this space. */
_spim3_ram = ORIGIN(SPIM3_RAM);
_spim3_ram_end = ORIGIN(SPIM3_RAM) + LENGTH(SPIM3_RAM);

/* define output sections */
SECTIONS
{
    /* The startup code goes first into FLASH */
    .isr_vector :
    {
        . = ALIGN(4);
        KEEP(*(.isr_vector)) /* Startup code */

        . = ALIGN(4);
    } >FLASH_ISR

    /* The program code and other data goes into FLASH */
    .text :
    {
        . = ALIGN(4);
        *SORT_BY_ALIGNMENT(SORT_BY_NAME(.text))           /* .text sections (code) */
        *SORT_BY_ALIGNMENT(SORT_BY_NAME(.text*))          /* .text* sections (code) */
        *(.rodata)         /* .rodata sections (constants, strings, etc.) */
        *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    /*  *(.glue_7)   */    /* glue arm to thumb code */
    /*  *(.glue_7t)  */    /* glue thumb to arm code */

        . = ALIGN(4);
        _etext = .;        /* define a global symbol at end of code */
    } >FLASH_FIRMWARE

    /* used by the startup to initialize data */
    _sidata = .;

    /* This is the initialized data section
    The program executes knowing that the data is in the RAM
    but the loader puts the initial values in the FLASH (inidata).
    It is one task of the startup to copy the initial values from FLASH to RAM. */
    .data : AT (_sidata)
    {
        . = ALIGN(4);
        _sdata = .;        /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
        _ram_start = .;    /* create a global symbol at ram start for garbage collector */
        *SORT_BY_ALIGNMENT(SORT_BY_NAME(.data))           /* .data sections */
        *SORT_BY_ALIGNMENT(SORT_BY_NAME(.data*))          /* .data* sections */

        . = ALIGN(4);
        _edata = .;        /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
    } >APP_RAM

    /* Zero-initialized data section */
    .bss :
    {
        . = ALIGN(4);
        _sbss = .;         /* define a global symbol at bss start; used by startup code */
        *SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss))
        *SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))
        *(COMMON)

        . = ALIGN(4);
        _ebss = .;         /* define a global symbol at bss end; used by startup code and GC */
    } >APP_RAM

    /* Uninitialized data section
    Data placed into this section will remain unchanged across reboots. */
    .uninitialized (NOLOAD) :
    {
        . = ALIGN(4);
        _suninitialized = .; /* define a global symbol at uninitialized start; currently unused */
        *(.uninitialized)
        *(.uninitialized*)

        . = ALIGN(4);
        _euninitialized = .; /* define a global symbol at uninitialized end; currently unused */
    } >APP_RAM

    /* this is to define the start of the heap, and make sure we have a minimum size */
    .heap :
    {
        . = ALIGN(4);
	      PROVIDE ( end = . );
	      PROVIDE ( _end = . );
        _heap_start = .;    /* define a global symbol at heap start */
        . = . + _minimum_heap_size;
    } >APP_RAM

    /* this just checks there is enough RAM for the stack */
    .stack :
    {
        . = ALIGN(4);
        . = . + ${CIRCUITPY_DEFAULT_STACK_SIZE};
        . = ALIGN(4);
    } >APP_RAM

    /* Remove exception unwinding information, since CircuitPython
       does not support this GCC feature. */
    /DISCARD/ :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
        *(.ARM.exidx*)
    }

    /* Remove information from the standard libraries */
    /*
    /DISCARD/ :
    {
        libc.a ( * )
        libm.a ( * )
        libgcc.a ( * )
    }
    */

    .ARM.attributes 0 : { *(.ARM.attributes) }
}

/*
    GNU linker script for NRF52840 w/ s140 6.0.0 SoftDevice
*/

/* Specify the memory areas */
MEMORY
{
    FLASH (rx)      : ORIGIN = 0x00000000, LENGTH = ${FLASH_SIZE} /* entire flash */
    /* nRF SoftDevice */
    FLASH_MBR (rx)  : ORIGIN = ${MBR_START_ADDR}, LENGTH = ${MBR_SIZE}
    FLASH_SD (rx)   : ORIGIN = ${SD_FLASH_START_ADDR}, LENGTH = ${SD_FLASH_SIZE}
    FLASH_ISR (rx)  : ORIGIN = ${ISR_START_ADDR}, LENGTH = ${ISR_SIZE}
    FLASH_FIRMWARE (rx) : ORIGIN = ${CIRCUITPY_FIRMWARE_START_ADDR}, LENGTH = ${CIRCUITPY_FIRMWARE_SIZE}
    FLASH_BLE_CONFIG (r) : ORIGIN = ${CIRCUITPY_BLE_CONFIG_START_ADDR}, LENGTH = ${CIRCUITPY_BLE_CONFIG_SIZE}
    FLASH_NVM (r)   : ORIGIN = ${CIRCUITPY_INTERNAL_NVM_START_ADDR}, LENGTH = ${CIRCUITPY_INTERNAL_NVM_SIZE}
    FLASH_FATFS (r) : ORIGIN = ${CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR}, LENGTH = ${CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE}
    FLASH_BOOTLOADER (rx) : ORIGIN = ${BOOTLOADER_START_ADDR}, LENGTH = ${BOOTLOADER_SIZE}
    FLASH_BOOTLOADER_SETTINGS (r) : ORIGIN = ${BOOTLOADER_SETTINGS_START_ADDR}, LENGTH = ${BOOTLOADER_SETTINGS_SIZE}

    /* SoftDevice RAM must start at the beginning of RAM: 0x2000000 (RAM_START_ADDR).
       On nRF52840, the first 64kB of RAM is composed of 8 8kB RAM blocks. Above those is
       RAM block 8, which is 192kB.
       If SPIM3_BUFFER_RAM_SIZE is 8kB, as opposed to zero, it must be in the first 64kB of RAM.
       So the amount of RAM reserved for the SoftDevice must be no more than 56kB.
    */
    RAM (xrw)       : ORIGIN = ${RAM_START_ADDR}, LENGTH = ${RAM_SIZE}
    SD_RAM (rw)     : ORIGIN = ${SOFTDEVICE_RAM_START_ADDR}, LENGTH = ${SOFTDEVICE_RAM_SIZE}
    SPIM3_RAM (rw)  : ORIGIN = ${SPIM3_BUFFER_RAM_START_ADDR}, LENGTH = ${SPIM3_BUFFER_RAM_SIZE}
    APP_RAM (xrw)   : ORIGIN = ${APP_RAM_START_ADDR}, LENGTH = ${APP_RAM_SIZE}
}

/* produce a link error if there is not this amount of RAM available */
_minimum_heap_size = 0;

/* top end of the stack */

/*_stack_end = ORIGIN(APP_RAM) + LENGTH(APP_RAM);*/
_estack = ORIGIN(APP_RAM) + LENGTH(APP_RAM);

/* RAM extents for the garbage collector */
_ram_end = ORIGIN(APP_RAM) + LENGTH(APP_RAM);
_heap_end = 0x20020000; /* tunable */

/* nrf52840 SPIM3 needs its own area to work around hardware problems. Nothing else may use this space. */
_spim3_ram = ORIGIN(SPIM3_RAM);
_spim3_ram_end = ORIGIN(SPIM3_RAM) + LENGTH(SPIM3_RAM);

/* define output sections */
SECTIONS
{
    /* The startup code goes first into FLASH */
    .isr_vector :
    {
        . = ALIGN(4);
        KEEP(*(.isr_vector)) /* Startup code */

        . = ALIGN(4);
    } >FLASH_ISR

    /* The program code and other data goes into FLASH */
    .text :
    {
        . = ALIGN(4);
        *(.text)           /* .text sections (code) */
        *(.text*)          /* .text* sections (code) */
        *(.rodata)         /* .rodata sections (constants, strings, etc.) */
        *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    /*  *(.glue_7)   */    /* glue arm to thumb code */
    /*  *(.glue_7t)  */    /* glue thumb to arm code */

        . = ALIGN(4);
        _etext = .;        /* define a global symbol at end of code */
    } >FLASH_FIRMWARE

    /* used by the startup to initialize data */
    _sidata = .;

    /* This is the initialized data section
    The program executes knowing that the data is in the RAM
    but the loader puts the initial values in the FLASH (inidata).
    It is one task of the startup to copy the initial values from FLASH to RAM. */
    .data : AT (_sidata)
    {
        . = ALIGN(4);
        _sdata = .;        /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
        _ram_start = .;    /* create a global symbol at ram start for garbage collector */
        *(.data)           /* .data sections */
        *(.data*)          /* .data* sections */

        . = ALIGN(4);
        _edata = .;        /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
    } >APP_RAM

    /* Zero-initialized data section */
    .bss :
    {
        . = ALIGN(4);
        _sbss = .;         /* define a global symbol at bss start; used by startup code */
        *(.bss)
        *(.bss*)
        *(COMMON)

        . = ALIGN(4);
        _ebss = .;         /* define a global symbol at bss end; used by startup code and GC */
    } >APP_RAM

    /* Uninitialized data section
    Data placed into this section will remain unchanged across reboots. */
    .uninitialized (NOLOAD) :
    {
        . = ALIGN(4);
        _suninitialized = .; /* define a global symbol at uninitialized start; currently unused */
        *(.uninitialized)
        *(.uninitialized*)

        . = ALIGN(4);
        _euninitialized = .; /* define a global symbol at uninitialized end; currently unused */
    } >APP_RAM

    /* this is to define the start of the heap, and make sure we have a minimum size */
    .heap :
    {
        . = ALIGN(4);
	      PROVIDE ( end = . );
	      PROVIDE ( _end = . );
        _heap_start = .;    /* define a global symbol at heap start */
        . = . + _minimum_heap_size;
    } >APP_RAM

    /* this just checks there is enough RAM for the stack */
    .stack :
    {
        . = ALIGN(4);
        . = . + ${CIRCUITPY_DEFAULT_STACK_SIZE};
        . = ALIGN(4);
    } >APP_RAM

    /* Remove exception unwinding information, since CircuitPython
       does not support this GCC feature. */
    /DISCARD/ :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
        *(.ARM.exidx*)
    }

    /* Remove information from the standard libraries */
    /*
    /DISCARD/ :
    {
        libc.a ( * )
        libm.a ( * )
        libgcc.a ( * )
    }
    */

    .ARM.attributes 0 : { *(.ARM.attributes) }
}