/*
 * linker script for STM32H750XBHx with GNU ld
 * Supports internal Flash (128KB) and QSPI Flash (mapped to 0x90000000)
 * Optimized for RT-Thread 5.1.0
 */

/* Memory Regions */
MEMORY
{
    ITCM_ROM (rx)  : ORIGIN = 0x08000000, LENGTH = 128K    /* Internal Flash */
    QSPI_ROM (rx)  : ORIGIN = 0x90000000, LENGTH = 2048k      /* QSPI Flash (2MB) */
    DTCM_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K    /* DTCM (Tightly-Coupled) */
    AXI_RAM (rw)   : ORIGIN = 0x24000000, LENGTH = 128K    /* AXI SRAM (Main RAM) */
}

/* Entry Point */
ENTRY(Reset_Handler)

/* Stack Size */
_system_stack_size = 0x1000;  /* 4KB system stack */

/* Section Definitions */
SECTIONS
{
    /* ==================== INTERNAL FLASH SECTIONS ==================== */
    /* Interrupt Vector Table (MUST be in internal Flash) */
    .isr_vector :
    {
        . = ALIGN(4);
        KEEP(*(.isr_vector))     /* Interrupt vector table */
        KEEP(*(.isr_vector.*))   /* For compatibility */
        . = ALIGN(4);
    } > ITCM_ROM

    /* Critical startup code */
    .startup :
    {
        . = ALIGN(4);
        KEEP(*(.startup))        /* Startup code */
        *(.text.Reset_Handler)   /* Reset handler */
        *(.text.SystemInit)      /* System initialization */
        . = ALIGN(4);
    } > ITCM_ROM

    /* ==================== QSPI FLASH SECTIONS ==================== */
    /* Main program code */
    .text : 
    {
        . = ALIGN(4);
        _stext = .;              /* Start of text */
        
        /* Program code */
        *(.text)                 /* General code */
        *(.text.*)               /* Subsection code */
        *(.glue_7)              /* ARM-Thumb glue */
        *(.glue_7t)              /* Thumb-ARM glue */
        *(.gnu.linkonce.t.*)     /* GNU linker sections */
        
        /* RT-Thread specific sections */
        . = ALIGN(4);
        __fsymtab_start = .;
        KEEP(*(FSymTab))         /* Finsh symbol table */
        __fsymtab_end = .;
        
        . = ALIGN(4);
        __vsymtab_start = .;
        KEEP(*(VSymTab))         /* Component init table */
        __vsymtab_end = .;
        
        . = ALIGN(4);
        __rtatcmdtab_start = .;
        KEEP(*(RtAtCmdTab))      /* AT command table */
        __rtatcmdtab_end = .;
        
        . = ALIGN(4);
        __rt_init_start = .;
        KEEP(*(SORT(.rti_fn*)))  /* Sorted init functions */
        __rt_init_end = .;
        
        /* C++ constructors */
        . = ALIGN(4);
        __ctors_start__ = .;
        KEEP(*(SORT(.init_array.*)))
        KEEP(*(.init_array))
        __ctors_end__ = .;
        
        . = ALIGN(4);
        _etext = .;              /* End of text */
    } > QSPI_ROM
    
     .eh_frame : 
      { 
       *(.eh_frame*)   
      } > QSPI_ROM

    /* Read-only data */
    .rodata :
    {
        . = ALIGN(4);
        *(.rodata)               /* Read-only data */
        *(.rodata.*)             /* Read-only data subsections */
        . = ALIGN(4);
    } > QSPI_ROM

    /* Custom constant sections */
    .rodata_const :
    {
        . = ALIGN(4);
        *(.rodata.ng_table)      /* Natural gas tables */
        *(.rodata.flow_cal)      /* Flow calibration data */
        . = ALIGN(4);
    } > QSPI_ROM

    /* ARM exception handling */
    .ARM.extab : 
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > QSPI_ROM

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

    /* ==================== RAM SECTIONS ==================== */
    /* Initialized data (stored in QSPI, loaded to DTCM at startup) */
    _sidata = LOADADDR(.data);   /* Source in QSPI */
    
    .data : 
    {
        . = ALIGN(4);
        _sdata = .;              /* Start in DTCM */
        
        *(.data)                /* Initialized data */
        *(.data.*)              /* Data subsections */
        *(.gnu.linkonce.d.*)    /* GNU linker sections */
        
        /* C++ destructors */
        . = ALIGN(4);
        __dtors_start__ = .;
        KEEP(*(SORT(.dtors.*)))
        KEEP(*(.dtors))
        __dtors_end__ = .;
        
        . = ALIGN(4);
        _edata = .;             /* End of data in DTCM */
    } > DTCM_RAM AT > QSPI_ROM

    /* System stack (in fast DTCM) */
    .stack : 
    {
        . = ALIGN(8);           /* 8-byte alignment for FPU */
        _sstack = .;            /* Stack start */
        . += _system_stack_size; /* Allocate stack space */
        . = ALIGN(8);
        _estack = .;            /* Stack end */
    } > DTCM_RAM

    /* Uninitialized data (BSS) */
    .bss (NOLOAD) :
    {
        . = ALIGN(4);
        _sbss = .;              /* BSS start */
        __bss_start__ = .;
        
        *(.bss)                /* Uninitialized data */
        *(.bss.*)              /* BSS subsections */
        *(COMMON)               /* Common symbols */
        
        . = ALIGN(4);
        _ebss = .;             /* BSS end */
        __bss_end__ = .;
        PROVIDE(__bss_end = .); /* 添加此符号以解决未定义引用问题 */
    } > AXI_RAM

    /* Heap space */
    .heap (NOLOAD) :
    {
        . = ALIGN(8);
        PROVIDE(__heap_start = .);
        . = ORIGIN(AXI_RAM) + LENGTH(AXI_RAM); /* End of AXI RAM */
        PROVIDE(__heap_end = .);
    } > AXI_RAM

    /* End of memory */
    _end = .;

    /* ==================== DEBUG SECTIONS ==================== */
    /* Discard debug sections to reduce binary size */
    /DISCARD/ :
    {
        *(.comment)
        *(.debug*)
        *(.note*)
        *(.group*)
        *(.stab*)
        *(.eh_frame*)
        *(.ARM.attributes)
    }
    
    /* Symbols for memory usage analysis */
    PROVIDE(__itcm_rom_used = SIZEOF(.isr_vector) + SIZEOF(.startup));
    PROVIDE(__qspi_rom_used = SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.rodata_const) + 
                         SIZEOF(.ARM.extab) + SIZEOF(.ARM.exidx));
    PROVIDE(__dtcm_ram_used = SIZEOF(.data) + SIZEOF(.stack));
    PROVIDE(__axi_ram_used = SIZEOF(.bss) + (__heap_end - __heap_start));
}