Skip to content

Commit 32d36dd

Browse files
committed
arm/linux: dtest and CI segfault
1 parent 933858e commit 32d36dd

5 files changed

Lines changed: 76 additions & 50 deletions

File tree

.github/workflows/arm-linux-build.yaml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,20 @@ jobs:
3333
make segments
3434
make sections
3535
36-
# - name: Cache and Install QEMU USER ARM
37-
# uses: awalsh128/cache-apt-pkgs-action@latest
38-
# with:
39-
# packages: qemu-user-static
40-
# version: 1 # Change this to manually bust the cache
36+
- name: Cache and Install QEMU USER ARM
37+
uses: awalsh128/cache-apt-pkgs-action@latest
38+
with:
39+
packages: qemu-user-static
40+
version: 1 # Change this to manually bust the cache
4141

42-
# - name: QEMU Core Tests
43-
# run: cd arm/mcu/linux && TIMEOUT=5s make tests
42+
- name: QEMU Core Tests
43+
run: cd arm/mcu/linux && TIMEOUT=5s make tests
4444

4545
- name: Build Linux/RaspPi (WANT_ITC)
46-
run: cd arm/mcu/linux && WANT_ITC=1 make all
46+
run: cd arm/mcu/linux && WANT_IGNORECASE=1 WANT_ITC=1 make all
4747

48-
# - name: QEMU Core Tests (WANT_ITC)
49-
# run: cd arm/mcu/linux && TIMEOUT=5s make tests
48+
- name: QEMU Core Tests (WANT_ITC)
49+
run: cd arm/mcu/linux && TIMEOUT=5s make tests
5050

5151
- name: Update Refcards
5252
if: github.ref == 'refs/heads/main'

core/amforth32.ld

Lines changed: 54 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
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 */
84
PROVIDE( flash.start = ORIGIN(FLASH) );
95
PROVIDE( flash.size = LENGTH(FLASH) );
106
PROVIDE( ram.start = ORIGIN(RAM) );
117
PROVIDE( 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+
1326
SECTIONS
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
}

core/config.inc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
.global rampool_size
2828

2929

30+
/* C stack size */
31+
.equ __stack_size, 2048
32+
.global __stack_size
33+
3034
/*
3135
Flash parameters
3236

rv/mcu/hifive1/config.inc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
.equ datastack_size, 32 * cellsize
55
.equ returnstack_size, 32 * cellsize
66

7+
.equ rampool_size, 1024 * cellsize
8+
79
/* TODO: this is made up, needs correcting */
810
.equ flash_page, 1*1024
911
.equ flash_cell, 1
1012
.equ flash_erased, 0xFFFFFFFF /* a word in erased flash */
13+
14+
/* C stack size */
15+
.equ __stack_size, 0

rv/mcu/qemu/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@ include $(AMFORTH)/rv/dev/Makefile
2020
.PRECIOUS: amforth.s
2121

2222
#? --- QEM ---
23+
# QEMU := $(QEMU_RV32) -M virt -bios none -kernel build/amforth.elf
2324

2425
# This is quite different from the -kernel option, which will for the RV 'virt' jump to
2526
# 0x8000_0000 no matter what ENTRY() has in the linker file. The cpu-num=0 sets the PC
2627
# to the value indicated by ENTRY(), which is much more suitable our needs. The commented
2728
# out line gives a hint as to how to set the PC to an absolute address at boot time.
2829

29-
QEMU := $(QEMU_RV32) -M virt -bios none -device loader,file=build/amforth.elf,cpu-num=0
30+
# QEMU := $(QEMU_RV32) -M virt -bios none -device loader,file=build/amforth.elf,cpu-num=0
31+
QEMU := $(QEMU_RV32) -M virt -bios none -device loader,file=build/amforth.bin,addr=0x20010000,cpu-num=0
3032
# -device loader,addr=0x20000000,cpu-num=0
3133

3234
## Start AmForth under QEMU with operator uart connected to stdio

0 commit comments

Comments
 (0)