Загрузка данных


/* Entry Point */
ENTRY(Reset_Handler)

HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x0400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;
M_VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x0620 : 0x0;

/* 
   Карта памяти i.MX 95 DDR строго синхронизированная с файлом DTS Linux.
   Адресация прямая, без смещений между ядрами A55 и M7.
*/
MEMORY
{
  /* Таблица ресурсов: Строго по адресу rsc_table из DTS */
  m_rsc_tbl             (RW)  : ORIGIN = 0x88220000, LENGTH = 0x00001000

  /* ISR vectors: Таблица векторов прерываний М7 в начале вашего 8МБ окна */
  m_interrupts          (RX)  : ORIGIN = 0x88320000, LENGTH = 0x00000800
  
  /* Program code: Код программы и константы (4 Mb - 2 Kb) */
  m_text                (RX)  : ORIGIN = 0x88320800, LENGTH = 0x003FF800
  
  /* Data: Переменные, стек и динамическая куча в оставшейся части 8МБ окна (4 Mb) */
  m_data                (RW)  : ORIGIN = 0x88720000, LENGTH = 0x00400000
  
  /* Ncache: Буферы RPMSG, посаженные точно на регион vdevbuffer из DTS */
  m_ncache              (RW)  : ORIGIN = 0x88020000, LENGTH = 0x00100000
}

/* Define output sections */
SECTIONS
{
  __NCACHE_REGION_START = ORIGIN(m_ncache);
  __NCACHE_REGION_SIZE  = LENGTH(m_ncache);
  
  /* Вектора прерываний в начале выделенной под код памяти */
  .interrupts :
  {
    __VECTOR_TABLE = .;
    __Vectors = .;
    . = ALIGN(4);
    KEEP(*(.isr_vector))     
    . = ALIGN(4);
  } > m_interrupts

  /* 
     Таблица ресурсов для взаимодействия с Linux Remoteproc.
     Она вынесена в отдельный регион памяти, жестко согласованный с DTS.
  */
  .resource_table :
  {
    . = ALIGN(8);
    KEEP(*(.resource_table)) 
    . = ALIGN(8);
  } > m_rsc_tbl

  /* Исполняемый код программы и константы */
  .text :
  {
    . = ALIGN(4);
    *(.text)                 
    *(.text*)                
    __quickcodeaccess_start__ = .;
    . = ALIGN(32);
    *(CodeQuickAccess)        
    . = ALIGN(32);
    __quickcodeaccess_end__ = .;
    *(.rodata)               
    *(.rodata*)              
    *(.glue_7)               
    *(.glue_7t)              
    *(.eh_frame)
    KEEP (*(.init))
    KEEP (*(.fini))
    . = ALIGN(4);
  } > m_text

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

  .ARM :
  {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } > m_text

  .ctors :
  {
    __CTOR_LIST__ = .;
    KEEP (*crtbegin.o(.ctors))
    KEEP (*crtbegin?.o(.ctors))
    KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
    __CTOR_END__ = .;
  } > m_text

  .dtors :
  {
    __DTOR_LIST__ = .;
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
    __DTOR_END__ = .;
  } > m_text

  .preinit_array :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } > m_text

  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } > m_text

  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } > m_text

  __etext = .;    
  __DATA_ROM = .; 

  /* Секция векторов прерываний в ОЗУ (внутри m_data) */
  .interrupts_ram :
  {
    . = ALIGN(4);
    __VECTOR_RAM__ = .;
    __interrupts_ram_start__ = .; 
    *(.m_interrupts_ram)     
    . += M_VECTOR_RAM_SIZE;
    . = ALIGN(4);
    __interrupts_ram_end__ = .; 
  } > m_data

  __VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts);
  __RAM_VECTOR_TABLE_SIZE_BYTES = DEFINED(__ram_vector_table__) ? (__interrupts_ram_end__ - __interrupts_ram_start__) : 0x0;

  /* Инициализированные глобальные и статические переменные (внутри m_data) */
  .data : AT(__DATA_ROM)
  {
    . = ALIGN(4);
    __DATA_RAM = .;
    __data_start__ = .;      
    __quickdataaccess_start__ = .;
    . = ALIGN(32);
    *(DataQuickAccess)
    . = ALIGN(32);
    __quickdataaccess_end__ = .;
    *(.data)                 
    *(.data*)                
    KEEP(*(.jcr*))
    . = ALIGN(4);
    __data_end__ = .;        
  } > m_data

  __NDATA_ROM = __DATA_ROM + SIZEOF(.data); 
  
  /* Инициализируемые некэшируемые структуры данных межъядерного обмена */
  .ncache.init : AT(__NDATA_ROM)
  {
    __noncachedata_start__ = .;   
    *(NonCacheable.init)
    . = ALIGN(4);
    __noncachedata_init_end__ = .;   
  } > m_ncache

  . = __noncachedata_init_end__;
  
  /* Стандартные некэшируемые буферы очередей RPMSG */
  .ncache :
  {
    *(NonCacheable)
    . = ALIGN(4);
    __noncachedata_end__ = .;     
  } > m_ncache

  __DATA_END = __NDATA_ROM + SIZEOF(.ncache.init);
  text_end = ORIGIN(m_text) + LENGTH(m_text);
  ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data")

  /* Глобальные неинициализированные переменные (.bss автоматически растет в m_data) */
  .bss :
  {
    . = ALIGN(4);
    __START_BSS = .;
    __bss_start__ = .;
    *(.bss)
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
    __END_BSS = .;
  } > m_data

  /* Выделение динамической кучи (Heap) внутри m_data */
  .heap :
  {
    . = ALIGN(8);
    __end__ = .;
    PROVIDE(end = .);
    __HeapBase = .;
    . += HEAP_SIZE;
    __HeapLimit = .;
    __heap_limit = .; 
  } > m_data

  /* Выделение стека функций (Stack) внутри m_data */
  .stack :
  {
    . = ALIGN(8);
    . += STACK_SIZE;
  } > m_data

  /* Расчет верхушки стека от верхней физической границы пула m_data */
  __StackTop   = ORIGIN(m_data) + LENGTH(m_data);
  __StackLimit = __StackTop - STACK_SIZE;
  PROVIDE(__stack = __StackTop);

  /* Алиасы для обратной совместимости с драйверами SDK */
  __RscTblStart = ORIGIN(m_rsc_tbl);
  __RscTblEnd = ORIGIN(m_rsc_tbl) + LENGTH(m_rsc_tbl);
  __RscTblInDramStart = ORIGIN(m_rsc_tbl_in_dram);
  __RscTblInDramEnd = ORIGIN(m_rsc_tbl_in_dram) + LENGTH(m_rsc_tbl_in_dram);

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

  ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap")
}