mirror of
https://github.com/openmv/openmv.git
synced 2025-09-26 23:09:13 +08:00
283 lines
6.7 KiB
ArmAsm
283 lines
6.7 KiB
ArmAsm
// SPDX-License-Identifier: MIT
|
|
//
|
|
// Copyright (C) 2013-2024 OpenMV, LLC.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
// THE SOFTWARE.
|
|
//
|
|
// NOTE this linker script is pre-processed using the CPP first before passing it
|
|
// to LD. It has access to the board config file, can define and use CPP macros,
|
|
// and it uses a lot of magic 🪄.
|
|
|
|
/* Adds a section to a table */
|
|
#define OMV_ADD_SECTION(s) \
|
|
LONG (ADDR(s)) \
|
|
LONG (SIZEOF(s))
|
|
|
|
/* Aligns a section to the next power of 2. */
|
|
#define OMV_ALIGN_DMA_SECTION(section) \
|
|
ALIGN(., 1 << LOG2CEIL(SIZEOF(section)))
|
|
|
|
/* Define a new GC block. */
|
|
#define OMV_GC_BLOCK_NEW(n) \
|
|
.gc.block##n (NOLOAD) : { \
|
|
. = ALIGN(4); \
|
|
. += OMV_GC_BLOCK##n##_SIZE; \
|
|
. = ALIGN(4); \
|
|
} >OMV_GC_BLOCK##n##_MEMORY \
|
|
|
|
/* Define a new DMA buffer region. */
|
|
#define OMV_DMA_MEMORY_NEW(X) \
|
|
.dma.memory##X (NOLOAD) : ALIGN(32) \
|
|
{ \
|
|
*(.d##X##_dma_buffer) \
|
|
. = OMV_ALIGN_DMA_SECTION(.dma.memory##X); \
|
|
} >OMV_DMA_MEMORY_D##X
|
|
|
|
/* Main GC heap for MicroPython */
|
|
#if defined(OMV_GC_BLOCK0_MEMORY)
|
|
.gc.block0 (NOLOAD) : ALIGN(4)
|
|
{
|
|
_heap_start = .;
|
|
. = . + OMV_GC_BLOCK0_SIZE;
|
|
. = ALIGN(4);
|
|
_heap_end = .;
|
|
} >OMV_GC_BLOCK0_MEMORY
|
|
#endif
|
|
|
|
/* Additional GC heap blocks */
|
|
#if defined(OMV_GC_BLOCK1_MEMORY)
|
|
OMV_GC_BLOCK_NEW(1)
|
|
#endif
|
|
#if defined(OMV_GC_BLOCK2_MEMORY)
|
|
OMV_GC_BLOCK_NEW(2)
|
|
#endif
|
|
#if defined(OMV_GC_BLOCK3_MEMORY)
|
|
OMV_GC_BLOCK_NEW(3)
|
|
#endif
|
|
#if defined(OMV_GC_BLOCK4_MEMORY)
|
|
OMV_GC_BLOCK_NEW(4)
|
|
#endif
|
|
|
|
/* Additional GC heap blocks table */
|
|
#if defined(OMV_GC_BLOCK1_MEMORY)
|
|
.gc.blocks.table (READONLY) :
|
|
{
|
|
. = ALIGN(4);
|
|
_gc_blocks_table_start = .;
|
|
OMV_ADD_SECTION(.gc.block1)
|
|
#if defined(OMV_GC_BLOCK2_MEMORY)
|
|
OMV_ADD_SECTION(.gc.block2)
|
|
#endif
|
|
#if defined(OMV_GC_BLOCK3_MEMORY)
|
|
OMV_ADD_SECTION(.gc.block3)
|
|
#endif
|
|
#if defined(OMV_GC_BLOCK4_MEMORY)
|
|
OMV_ADD_SECTION(.gc.block4)
|
|
#endif
|
|
_gc_blocks_table_end = .;
|
|
. = ALIGN(4);
|
|
} > FLASH_TEXT
|
|
#endif
|
|
|
|
/* Heap memfor libc malloc/sbrk */
|
|
#if defined(OMV_HEAP_MEMORY)
|
|
.heap (NOLOAD) : ALIGN(4)
|
|
{
|
|
__end__ = .;
|
|
PROVIDE(end = .);
|
|
. = . + OMV_HEAP_SIZE;
|
|
. = ALIGN(4);
|
|
_heap_limit = .;
|
|
} > OMV_HEAP_MEMORY
|
|
#endif
|
|
|
|
/* Stack memory */
|
|
#if defined(OMV_STACK_MEMORY)
|
|
.stack (NOLOAD) : ALIGN(8)
|
|
{
|
|
_sstack = .;
|
|
__StackLimit = .;
|
|
. = . + OMV_STACK_SIZE;
|
|
. = ALIGN(8);
|
|
_estack = .;
|
|
__StackTop = .;
|
|
} > OMV_STACK_MEMORY
|
|
PROVIDE(__stack = __StackTop);
|
|
#endif
|
|
|
|
/* Streaming buffer memory */
|
|
#if defined(OMV_SB_MEMORY)
|
|
.sb_memory (NOLOAD) :
|
|
{
|
|
. = ALIGN(4);
|
|
_sb_memory_start = .;
|
|
. = . + OMV_SB_SIZE;
|
|
. = ALIGN(4);
|
|
_sb_memory_end = .;
|
|
} >OMV_SB_MEMORY
|
|
#endif
|
|
|
|
/* GPU memory */
|
|
#if defined(OMV_GPU_MEMORY)
|
|
.gpu_memory (NOLOAD) :
|
|
{
|
|
. = ALIGN(16);
|
|
_gpu_memory_start = .;
|
|
. = . + OMV_GPU_SIZE;
|
|
. = ALIGN(16);
|
|
_gpu_memory_end = .;
|
|
} >OMV_GPU_MEMORY
|
|
#endif
|
|
|
|
/* Open-AMP Shared Memory Region */
|
|
#if defined(OMV_OPENAMP_MEMORY)
|
|
.openamp_memory (NOLOAD) : ALIGN(32)
|
|
{
|
|
_openamp_shm_region_start = .;
|
|
. = . + OMV_OPENAMP_SIZE;
|
|
_openamp_shm_region_end = .;
|
|
. = OMV_ALIGN_DMA_SECTION(.openamp_memory);
|
|
} >OMV_OPENAMP_MEMORY
|
|
#endif
|
|
|
|
/* Memory for the second core */
|
|
#if defined(OMV_CORE1_MEMORY)
|
|
.core1_memory (NOLOAD) : ALIGN(32)
|
|
{
|
|
_core1_memory_start = .;
|
|
. = . + OMV_CORE1_SIZE;
|
|
_core1_memory_end = .;
|
|
. = OMV_ALIGN_DMA_SECTION(.core1_memory);
|
|
} >OMV_CORE1_MEMORY
|
|
#endif
|
|
|
|
/* Main framebuffer memory */
|
|
#if defined(OMV_FB_MEMORY)
|
|
.fb_memory (NOLOAD) :
|
|
{
|
|
. = ALIGN(4);
|
|
_fb_memory_start = .;
|
|
. += OMV_FB_SIZE;
|
|
. = ALIGN(4);
|
|
_fb_memory_end = .;
|
|
. += OMV_FB_ALLOC_SIZE;
|
|
. = ALIGN(4);
|
|
_fb_alloc_end = .;
|
|
. = ALIGN(4);
|
|
} >OMV_FB_MEMORY
|
|
#endif
|
|
|
|
/* Main framebuffer fast memory */
|
|
#if defined(OMV_FB_OVERLAY_MEMORY)
|
|
.fb_overlay_memory (NOLOAD) :
|
|
{
|
|
. = ALIGN(4);
|
|
_fballoc_overlay_start = .;
|
|
. = . + OMV_FB_OVERLAY_SIZE;
|
|
_fballoc_overlay_end = .;
|
|
} >OMV_FB_OVERLAY_MEMORY
|
|
#endif
|
|
|
|
/* Misc DMA buffers section */
|
|
.dma.memory0 (NOLOAD) : ALIGN(32)
|
|
{
|
|
/* Image line buffer. */
|
|
#if defined(OMV_LINE_BUF_SIZE)
|
|
. = ALIGN(16);
|
|
_line_buf = .;
|
|
. = . + OMV_LINE_BUF_SIZE;
|
|
#endif
|
|
|
|
/* USB MSC bot data (2K) */
|
|
#if defined(OMV_MSC_BUF_SIZE)
|
|
. = ALIGN(16);
|
|
_msc_buf = .;
|
|
. = . + OMV_MSC_BUF_SIZE;
|
|
#endif
|
|
|
|
#if defined(OMV_SB_SIZE) && !defined(OMV_SB_MEMORY)
|
|
. = ALIGN(16);
|
|
_sb_memory_start = .;
|
|
. = . + OMV_SB_SIZE;
|
|
_sb_memory_end = .;
|
|
#endif
|
|
|
|
/* FFS (internal) filesystem buffer */
|
|
#if defined(OMV_FFS_BUF_SIZE)
|
|
. = ALIGN(16);
|
|
_micropy_hw_internal_flash_storage_ram_cache_start = .;
|
|
. = . + OMV_FFS_BUF_SIZE;
|
|
_micropy_hw_internal_flash_storage_ram_cache_end = .;
|
|
#endif
|
|
|
|
. = ALIGN(16);
|
|
*(.dma_buffer)
|
|
|
|
. = ALIGN(16);
|
|
*(NonCacheable)
|
|
|
|
. = OMV_ALIGN_DMA_SECTION(.dma.memory0);
|
|
#if defined(OMV_DMA_MEMORY)
|
|
} >OMV_DMA_MEMORY
|
|
#else
|
|
} >OMV_MAIN_MEMORY
|
|
#endif
|
|
|
|
/* Additional DMA memory buffers */
|
|
#if defined(OMV_DMA_MEMORY_D1)
|
|
OMV_DMA_MEMORY_NEW(1)
|
|
#endif
|
|
#if defined(OMV_DMA_MEMORY_D2)
|
|
OMV_DMA_MEMORY_NEW(2)
|
|
#endif
|
|
#if defined(OMV_DMA_MEMORY_D3)
|
|
OMV_DMA_MEMORY_NEW(3)
|
|
#endif
|
|
|
|
/* Additional DMA memory tables */
|
|
.dma.memory.table (READONLY) :
|
|
{
|
|
. = ALIGN(4);
|
|
_dma_memory_table_start = .;
|
|
OMV_ADD_SECTION(.dma.memory0)
|
|
#if defined(OMV_DMA_MEMORY_D1)
|
|
OMV_ADD_SECTION(.dma.memory1)
|
|
#endif
|
|
#if defined(OMV_DMA_MEMORY_D2)
|
|
OMV_ADD_SECTION(.dma.memory2)
|
|
#endif
|
|
#if defined(OMV_DMA_MEMORY_D3)
|
|
OMV_ADD_SECTION(.dma.memory3)
|
|
#endif
|
|
_dma_memory_table_end = .;
|
|
. = ALIGN(4);
|
|
} > FLASH_TEXT
|
|
|
|
#if defined(OMV_ROMFS_PART0_ORIGIN)
|
|
_micropy_hw_romfs_part0_start = OMV_ROMFS_PART0_ORIGIN;
|
|
_micropy_hw_romfs_part0_size = OMV_ROMFS_PART0_LENGTH;
|
|
#endif
|
|
|
|
#if defined(OMV_ROMFS_PART1_ORIGIN)
|
|
_micropy_hw_romfs_part1_start = OMV_ROMFS_PART1_ORIGIN;
|
|
_micropy_hw_romfs_part1_size = OMV_ROMFS_PART1_LENGTH;
|
|
#endif
|
|
|
|
.ARM.attributes 0 : { *(.ARM.attributes) }
|