Загрузка данных
/* 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;
/*
8MB DDR RAM (0x80000000 - 0x80800000)
Плотное монолитное распределение памяти для бесконфликтной работы с Remoteproc
*/
MEMORY
{
/* ISR vectors: Таблица векторов прерываний М7 (2 Kb) */
m_interrupts (RX) : ORIGIN = 0x80000000, LENGTH = 0x00000800
/* Исполняемый код, константы и Resource Table (4 Mb - 2 Kb) */
m_text (RX) : ORIGIN = 0x80000800, LENGTH = 0x003FF800
/* Переменные, стек, куча и кэшируемые данные (2 Mb) */
m_data (RW) : ORIGIN = 0x80400000, LENGTH = 0x00200000
/* Некэшируемые данные: Буферы для межъядерного обмена RPMSG (2 Mb) */
m_ncache (RW) : ORIGIN = 0x80600000, LENGTH = 0x00200000
}
/* Define output sections */
SECTIONS
{
__NCACHE_REGION_START = ORIGIN(m_ncache);
__NCACHE_REGION_SIZE = LENGTH(m_ncache);
/* Вектора прерываний в самом начале DDR */
.interrupts :
{
__VECTOR_TABLE = .;
__Vectors = .;
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} > m_interrupts
/*
КРИТИЧЕСКОЕ ИСПРАВЛЕНИЕ: Таблица ресурсов размещена плотно на стыке
с кодом в регионе m_text. Больше нет разрывов памяти в ELF.
*/
.resource_table :
{
. = ALIGN(8);
KEEP(*(.resource_table))
. = ALIGN(8);
} > m_text
/* Исполняемый код программы и константы (автоматически растет вниз) */
.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__;
/* Стандартные некэшируемые буферы */
.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")
/* Глобальные неинициализированные переменные (автоматически растет в 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_text);
__RscTblEnd = ORIGIN(m_text) + 0x100;
__RscTblInDramStart = ORIGIN(m_text);
__RscTblInDramEnd = ORIGIN(m_text) + 0x100;
.ARM.attributes 0 : { *(.ARM.attributes) }
ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap")
}