11/* SPDX-License-Identifier: GPL-3.0-only */
22
3- /* C stack size */
4- __stack_size = 2048 ;
5- PROVIDE ( _stack_size = __stack_size );
6-
73/* Memory region info */
84PROVIDE ( flash.start = ORIGIN (FLASH) );
95PROVIDE ( flash.size = LENGTH (FLASH) );
106PROVIDE ( ram.start = ORIGIN (RAM) );
117PROVIDE ( ram.size = LENGTH (RAM) );
128
9+ /*
10+ Defining our own PHDRS to control the segment permissions and
11+ section allocations explicitly. When running amforth on top of
12+ linux kernel, the loader often ignores section attributes and
13+ looks at the segment headers only.
14+ */
15+
16+ PHDRS
17+ {
18+ text PT_LOAD FLAGS (5 ); /* r-x */
19+ data PT_LOAD FLAGS (6 ); /* rw- */
20+ forth PT_LOAD FLAGS (7 ); /* rwx */
21+ forth_ram PT_LOAD FLAGS (7 ); /* rwx */
22+ stack PT_LOAD FLAGS (6 ); /* rw- */
23+ forth_pv PT_LOAD FLAGS (6 ); /* rw- */
24+ }
25+
1326SECTIONS
1427{
1528
@@ -21,15 +34,15 @@ SECTIONS
2134 KEEP (*(SORT_NONE (.init )))
2235 . = ALIGN (4 );
2336 _einit = .;
24- } >FLASH AT>FLASH
37+ } >FLASH AT>FLASH :text
2538
2639 /* Hardware interrupt table */
2740
2841 .vector :
2942 {
3043 *(.vector );
3144 . = ALIGN (64 );
32- } >FLASH AT>FLASH
45+ } >FLASH AT>FLASH :text
3346
3447 /* C code sections */
3548
@@ -44,13 +57,13 @@ SECTIONS
4457 *(.rodata *)
4558 *(.gnu .linkonce .t .*)
4659 . = ALIGN (4 );
47- } >FLASH AT>FLASH
60+ } >FLASH AT>FLASH :text
4861
4962 .fini :
5063 {
5164 KEEP (*(SORT_NONE (.fini )))
5265 . = ALIGN (4 );
53- } >FLASH AT>FLASH
66+ } >FLASH AT>FLASH :text
5467
5568 PROVIDE ( _etext = . );
5669 PROVIDE ( _eitcm = . );
@@ -60,23 +73,23 @@ SECTIONS
6073 PROVIDE_HIDDEN (__preinit_array_start = .);
6174 KEEP (*(.preinit_array ))
6275 PROVIDE_HIDDEN (__preinit_array_end = .);
63- } >FLASH AT>FLASH
76+ } >FLASH AT>FLASH :text
6477
6578 .init_array :
6679 {
6780 PROVIDE_HIDDEN (__init_array_start = .);
6881 KEEP (*(SORT_BY_INIT_PRIORITY (.init_array .*) SORT_BY_INIT_PRIORITY (.ctors .*)))
6982 KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors ))
7083 PROVIDE_HIDDEN (__init_array_end = .);
71- } >FLASH AT>FLASH
84+ } >FLASH AT>FLASH :text
7285
7386 .fini_array :
7487 {
7588 PROVIDE_HIDDEN (__fini_array_start = .);
7689 KEEP (*(SORT_BY_INIT_PRIORITY (.fini_array .*) SORT_BY_INIT_PRIORITY (.dtors .*)))
7790 KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors ))
7891 PROVIDE_HIDDEN (__fini_array_end = .);
79- } >FLASH AT>FLASH
92+ } >FLASH AT>FLASH :text
8093
8194 .ctors :
8295 {
@@ -98,7 +111,7 @@ SECTIONS
98111 KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors ))
99112 KEEP (*(SORT (.ctors .*)))
100113 KEEP (*(.ctors ))
101- } >FLASH AT>FLASH
114+ } >FLASH AT>FLASH :text
102115
103116 .dtors :
104117 {
@@ -107,7 +120,7 @@ SECTIONS
107120 KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors ))
108121 KEEP (*(SORT (.dtors .*)))
109122 KEEP (*(.dtors ))
110- } >FLASH AT>FLASH
123+ } >FLASH AT>FLASH :text
111124
112125 /*
113126 This is the main AmForth flash section housing all the predefined words.
@@ -119,7 +132,7 @@ SECTIONS
119132 *(amforth)
120133 *amforth.o (.text .text .*)
121134
122- } >FLASH AT>FLASH
135+ } >FLASH AT>FLASH :forth
123136
124137 /*
125138 RAM resident code, i.e. code that must run from RAM.
@@ -132,7 +145,7 @@ SECTIONS
132145 PROVIDE (RAM_lower_res = . );
133146 *(amres)
134147 PROVIDE (RAM_upper_res = . );
135- } >RAM AT>FLASH
148+ } >RAM AT>FLASH :text
136149
137150 PROVIDE (RAM_size_res = RAM_upper_res - RAM_lower_res) ;
138151 PROVIDE (RAM_stuf_res = SIZEOF (amramres)) ;
@@ -143,14 +156,14 @@ SECTIONS
143156 userdict represents the free space used for new words created at runtime in flash (and therefore persistent).
144157 It generally occupies the rest of the FLASH memory region. (Tracked by dp.flash)
145158 */
146- userdict :
159+ userdict ( NOLOAD) :
147160 {
148161 . = ALIGN (flash_page) ;
149162 /* . = ALIGN(MAX(flash_cell,cellsize)) ; ->page_end zero filled - not erasesd? */
150163 PROVIDE ( dp0.flash = . );
151164 PROVIDE ( flash.high = . );
152165 PROVIDE ( flash.max = ORIGIN (FLASH) + LENGTH (FLASH));
153- } >FLASH AT>FLASH
166+ } >FLASH AT>FLASH :forth
154167
155168 ASSERT (FSH_upper_res <= dp0.flash ," *ERROR* userdict overlaps amramres" )
156169
@@ -169,7 +182,7 @@ SECTIONS
169182 FILL (0xDEADBEEF ); /* fill value MUST match first_boot_marker */
170183 . = . + flash_page - 1 ;
171184 BYTE (0 ); /* seems to be needed to actually get a write */
172- } >FLASH AT>FLASH
185+ } >FLASH AT>FLASH :forth
173186
174187 ASSERT (FSH_upper_res <= first_boot , " *ERROR* first_boot overlaps amramres" )
175188
@@ -180,11 +193,11 @@ SECTIONS
180193 and amforth will segfault if that memory is accessed.
181194 */
182195 unused_flash = ORIGIN (FLASH) + LENGTH (FLASH) - ADDR (first_boot) - flash_page - csec_size ;
183- userdict2 :
196+ userdict2 ( NOLOAD) :
184197 {
185198 /* actually allocate the rest of unused FLASH */
186199 . += unused_flash ;
187- } >FLASH AT>FLASH
200+ } >FLASH AT>FLASH :forth
188201
189202 /* C data sections */
190203
@@ -195,13 +208,13 @@ SECTIONS
195208 {
196209 . = ALIGN (4 );
197210 PROVIDE (_data_vma = .);
198- } >RAM AT>FLASH
211+ } >RAM AT>FLASH :data
199212
200213 .dlalign :
201214 {
202215 . = ALIGN (4 );
203216 PROVIDE (_data_lma = .);
204- } >FLASH AT>FLASH
217+ } >FLASH AT>FLASH :data
205218
206219 .data :
207220 {
@@ -221,7 +234,7 @@ SECTIONS
221234 *(.srodata .srodata .*)
222235 . = ALIGN (4 );
223236 PROVIDE ( _edata = .);
224- } >RAM AT>FLASH
237+ } >RAM AT>FLASH :data
225238
226239 .bss :
227240 {
@@ -235,7 +248,7 @@ SECTIONS
235248 . = ALIGN (4 );
236249 PROVIDE ( _ebss = .);
237250 PROVIDE ( ram_ripe = .); /* QEMU */
238- } >RAM AT>FLASH
251+ } >RAM AT>FLASH :data
239252
240253 PROVIDE ( _end = _ebss);
241254 PROVIDE ( end = . );
@@ -245,28 +258,31 @@ SECTIONS
245258 /* The RAM side of amramres section is first */
246259
247260 /* amramlo contains RAM allocations of all the pre-compiled words */
248- amramlo :
261+ amramlo ( NOLOAD) :
249262 {
250263 . = ALIGN (256 ) ;
251264
252265 PROVIDE (RAM_lower_fi = . ) ;
253266 . = . + 256 ;
254267 PROVIDE (RAM_upper_fi = . ) ;
255268
256- } >RAM
269+ } >RAM :forth_ram
257270
258271 ASSERT (RAM_upper_res <= RAM_lower_fi ," *ERROR* amramres and amramlo overlap" )
259272
260273 /*
261274 amramhi contains:
262275 * RAM pool, where runtime defined flash words allocate RAM (vp)
263276 * ram-dictionary where RAM defined words are compiled (dp.ram)
277+
278+ We want to allocate all remaining RAM between amramlo and .stack for amramhi,
279+ thus the stack_start calculation below.
264280 */
265281
266- /* calculate size of unallocated RAM, minus some fudge factor (256) for alignments */
267- PROVIDE ( unused_ram = LENGTH (RAM) - SIZEOF (amramres ) - SIZEOF (amramlo) - rampool_size - __stack_size - 256 ) ;
282+ slack = cellsize ;
283+ stack_start = ORIGIN (RAM) + LENGTH (RAM ) - __stack_size - slack ;
268284
269- amramhi :
285+ amramhi ( NOLOAD) :
270286 {
271287 . = ALIGN (4 ) ;
272288
@@ -285,25 +301,24 @@ SECTIONS
285301 the kernel won't actually map it into the process' memory space
286302 and amforth will segfault if that memory is accessed.
287303 */
288- . += unused_ram ;
304+ . = ABSOLUTE (stack_start) - . ;
289305
290- } > RAM
306+ } >RAM :forth_ram
291307
292308 ASSERT (RAM_upper_fi <= vp0 ," *ERROR* amramlo and amramhi overlap" )
293309
294310 /* Sections at the high end of RAM */
295311
296312 /* C stack section */
297- slack = cellsize ;
298- stack_start = ORIGIN (RAM) + LENGTH (RAM) - __stack_size - slack ;
299- .stack stack_start :
313+
314+ .stack stack_start (NOLOAD) :
300315 {
301316 PROVIDE ( _heap_end = . );
302317 . = ALIGN (4 );
303318 PROVIDE (_susrstack = . );
304319 . = . + __stack_size;
305320 PROVIDE ( _eusrstack = .);
306- } >RAM
321+ } >RAM :stack
307322 PROVIDE ( dp.ram .max = ADDR (.stack ) - slack );
308323
309324 /* End of RAM sections */
@@ -341,15 +356,15 @@ SECTIONS
341356 /* predefined size of pvalue arenas, use whole PVFLASH. */
342357 PROVIDE (pvarena.size = LENGTH (PVFLASH) / 2 );
343358
344- pvarena1 : {
359+ pvarena1 ( NOLOAD) : {
345360 PROVIDE (pvarena1_lower = . );
346361 . = . + pvarena.size ;
347362 PROVIDE (pvarena1_upper = .);
348- } >PVFLASH
363+ } >PVFLASH :forth_pv
349364
350- pvarena2 : {
365+ pvarena2 ( NOLOAD) : {
351366 PROVIDE (pvarena2_lower = . );
352367 . = . + pvarena.size ;
353368 PROVIDE (pvarena2_upper = .);
354- } >PVFLASH
369+ } >PVFLASH :forth_pv
355370}
0 commit comments