1/*
2** ###################################################################
3**     Processors:          MIMX8UX5AVLFZ
4**                          MIMX8UX5AVOFZ
5**                          MIMX8UX5CVLDZ
6**
7**     Compiler:            GNU C Compiler
8**     Reference manual:    IMX8DQXPRM, Rev. E, 6/2019
9**     Version:             rev. 4.0, 2020-06-19
10**     Build:               b201113
11**
12**     Abstract:
13**         Linker file for the GNU C Compiler
14**
15**     Copyright 2016 Freescale Semiconductor, Inc.
16**     Copyright 2016-2020 NXP
17**     All rights reserved.
18**
19**     SPDX-License-Identifier: BSD-3-Clause
20**
21**     http:                 www.nxp.com
22**     mail:                 support@nxp.com
23**
24** ###################################################################
25*/
26
27/* Entry Point */
28ENTRY(Reset_Handler)
29
30HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x0400;
31STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;
32
33/* Reserved for PFU fetches, which is six 16-bit Thumb instructions */
34SAFE_BOUNDARY_LEN = 12;
35
36/* Specify the memory areas */
37/* M4 always start up from TCM. The SCU will copy the first 32 bytes of the binary to TCM
38if the start address is not TCM. The TCM region [0x1FFE0000-0x1FFE001F] is reserved for this purpose. */
39MEMORY
40{
41  m_interrupts          (RX)  : ORIGIN = DEFINED(__STARTUP_CONFIG_DDR_ALIAS)?0x08000000:0x88000000, LENGTH = 0x00000A00
42  m_text                (RX)  : ORIGIN = DEFINED(__STARTUP_CONFIG_DDR_ALIAS)?0x08000A00:0x88000A00, LENGTH = 0x001FF600
43  m_data                (RW)  : ORIGIN = 0x88200000, LENGTH = 0x00200000
44  m_data2               (RW)  : ORIGIN = 0x88400000, LENGTH = 0x07C00000
45  m_tcml                (RW)  : ORIGIN = 0x1FFE0020, LENGTH = 0x0001FFE0
46  m_tcmu                (RW)  : ORIGIN = 0x20000000, LENGTH = 0x00020000
47}
48
49/* Define output sections */
50SECTIONS
51{
52  /* The startup code goes first into internal RAM */
53  .interrupts :
54  {
55    . = ALIGN(4);
56    KEEP(*(.isr_vector))     /* Startup code */
57    . = ALIGN(4);
58  } > m_interrupts
59
60  .resource_table :
61  {
62    . = ALIGN(8);
63    KEEP(*(.resource_table)) /* Resource table */
64    . = ALIGN(8);
65  } > m_text
66
67  /* The program code and other data goes into internal RAM */
68  .text :
69  {
70    . = ALIGN(4);
71    *(.text)                 /* .text sections (code) */
72    *(.text*)                /* .text* sections (code) */
73    *(.rodata)               /* .rodata sections (constants, strings, etc.) */
74    *(.rodata*)              /* .rodata* sections (constants, strings, etc.) */
75    *(.glue_7)               /* glue arm to thumb code */
76    *(.glue_7t)              /* glue thumb to arm code */
77    *(.eh_frame)
78    KEEP (*(.init))
79    KEEP (*(.fini))
80    . = ALIGN(4);
81  } > m_text
82
83  .ARM.extab :
84  {
85    *(.ARM.extab* .gnu.linkonce.armextab.*)
86  } > m_text
87
88  .ARM :
89  {
90    __exidx_start = .;
91    *(.ARM.exidx*)
92    __exidx_end = .;
93  } > m_text
94
95 .ctors :
96  {
97    __CTOR_LIST__ = .;
98    /* gcc uses crtbegin.o to find the start of
99       the constructors, so we make sure it is
100       first.  Because this is a wildcard, it
101       doesn't matter if the user does not
102       actually link against crtbegin.o; the
103       linker won't look for a file to match a
104       wildcard.  The wildcard also means that it
105       doesn't matter which directory crtbegin.o
106       is in.  */
107    KEEP (*crtbegin.o(.ctors))
108    KEEP (*crtbegin?.o(.ctors))
109    /* We don't want to include the .ctor section from
110       from the crtend.o file until after the sorted ctors.
111       The .ctor section from the crtend file contains the
112       end of ctors marker and it must be last */
113    KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
114    KEEP (*(SORT(.ctors.*)))
115    KEEP (*(.ctors))
116    __CTOR_END__ = .;
117  } > m_text
118
119  .dtors :
120  {
121    __DTOR_LIST__ = .;
122    KEEP (*crtbegin.o(.dtors))
123    KEEP (*crtbegin?.o(.dtors))
124    KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
125    KEEP (*(SORT(.dtors.*)))
126    KEEP (*(.dtors))
127    __DTOR_END__ = .;
128  } > m_text
129
130  .preinit_array :
131  {
132    PROVIDE_HIDDEN (__preinit_array_start = .);
133    KEEP (*(.preinit_array*))
134    PROVIDE_HIDDEN (__preinit_array_end = .);
135  } > m_text
136
137  .init_array :
138  {
139    PROVIDE_HIDDEN (__init_array_start = .);
140    KEEP (*(SORT(.init_array.*)))
141    KEEP (*(.init_array*))
142    PROVIDE_HIDDEN (__init_array_end = .);
143  } > m_text
144
145  .fini_array :
146  {
147    PROVIDE_HIDDEN (__fini_array_start = .);
148    KEEP (*(SORT(.fini_array.*)))
149    KEEP (*(.fini_array*))
150    PROVIDE_HIDDEN (__fini_array_end = .);
151  } > m_text
152
153  __etext = .;    /* define a global symbol at end of code */
154  __DATA_ROM = .; /* Symbol is used by startup for data initialization */
155
156  .data : AT(__DATA_ROM)
157  {
158    . = ALIGN(4);
159    __DATA_RAM = .;
160    __data_start__ = .;      /* create a global symbol at data start */
161    *(.data)                 /* .data sections */
162    *(.data*)                /* .data* sections */
163    KEEP(*(.jcr*))
164    . = ALIGN(4);
165    __data_end__ = .;        /* define a global symbol at data end */
166  } > m_data
167
168  __TDATA_ROM = __DATA_ROM + SIZEOF(.data); /* Symbol is used by startup for TCM data initialization */
169  .quickaccess : AT(__TDATA_ROM)
170  {
171    __quickaccess_start__ = .;
172    . = ALIGN(32);
173    *(CodeQuickAccess)
174    . += SAFE_BOUNDARY_LEN;
175    *(DataQuickAccess)
176    . = ALIGN(128);
177    __quickaccess_end__ = .;
178  } > m_tcml
179
180  __CACHE_REGION_START = DEFINED(__STARTUP_CONFIG_DDR_ALIAS) ? ORIGIN(m_data) : ORIGIN(m_interrupts);
181  __CACHE_REGION_SIZE = DEFINED(__STARTUP_CONFIG_DDR_ALIAS) ? LENGTH(m_data) : LENGTH(m_interrupts) + LENGTH(m_text) + LENGTH(m_data);
182
183
184  __NDATA_ROM = __TDATA_ROM + SIZEOF(.quickaccess); /* Symbol is used by startup for ncache data initialization */
185
186  .ncache.init : AT(__NDATA_ROM)
187  {
188    __noncachedata_start__ = .;   /* create a global symbol at ncache data start */
189    *(NonCacheable.init)
190    . = ALIGN(4);
191    __noncachedata_init_end__ = .;   /* create a global symbol at initialized ncache data end */
192  } > m_data2
193
194  . = __noncachedata_init_end__;
195  .ncache :
196  {
197    *(NonCacheable)
198    . = ALIGN(4);
199    __noncachedata_end__ = .;     /* define a global symbol at ncache data end */
200  } > m_data2
201
202  __DATA_END = __NDATA_ROM + SIZEOF(.ncache.init);
203  text_end = ORIGIN(m_text) + LENGTH(m_text);
204  ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data")
205
206  /* Uninitialized data section */
207  .bss :
208  {
209    /* This is used by the startup in order to initialize the .bss section */
210    . = ALIGN(4);
211    __START_BSS = .;
212    __bss_start__ = .;
213    *(.bss)
214    *(.bss*)
215    *(COMMON)
216    . = ALIGN(4);
217    __bss_end__ = .;
218    __END_BSS = .;
219  } > m_data
220
221  .heap :
222  {
223    . = ALIGN(8);
224    __end__ = .;
225    PROVIDE(end = .);
226    __HeapBase = .;
227    . += HEAP_SIZE;
228    __HeapLimit = .;
229    __heap_limit = .; /* Add for _sbrk */
230  } > m_data
231
232  .stack :
233  {
234    . = ALIGN(8);
235    . += STACK_SIZE;
236  } > m_data
237
238  /* Initializes stack on the end of block */
239  __StackTop   = ORIGIN(m_data) + LENGTH(m_data);
240  __StackLimit = __StackTop - STACK_SIZE;
241  PROVIDE(__stack = __StackTop);
242
243  .ARM.attributes 0 : { *(.ARM.attributes) }
244
245  ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap")
246}
247
248