Conversation
mkobetic
commented
Apr 9, 2026
|
|
||
| /* C stack size */ | ||
| .equ __stack_size, 2048 | ||
| .global __stack_size |
Owner
Author
There was a problem hiding this comment.
Moved from amforth32.ld so that it can be overriden in mcu config.s
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
So fortunately the CI segfault also reproduced in local Docker, and although that is not exactly a friendly debugging target either (GDB doesn't work in emulated container) I was able to deduce that the issue is that the user dictionary spaces weren't mapped as executable regions. It is possible to get the containerized process to dump the core file (need to invoke
ulimit -c unlimitedfirst), but the core file can then be analyzed using GDB outside of the container. The segfault was happening in the synthetic jump instruction we compile into DOES> words and is therefore executed in those spaces.So, how to mark the memory as executable? We need to mark the memory segments produced by the linker as executable. For that most reasonable way seems to be adding a PHDRS section to the linker file and declaring segments explicitly instead of letting the linker conjure them up, and then assigning each section to a specific segment (the :segment bit at the end of the section definitions).
Coming up with the set of segments was also a journey, because the :segment is only a hint apparently and you need to be careful about making segments span large memory areas and therefore large MemSiz value in the
make segmentsoutput below. It is very easy to end up with a large segment that contains other segments, usually you'll see the same section mapped to multiple segments in that case. What we want is to have nice tidy segments and each section mapped to exactly one of them.Below is the final arm/linux layout, note that the segments 02 and 03 containing all the forth sections are marked RWE (E = executable). amramhi is what made the tests segfault, but we also want the userdict section executable for >flash compiled words.
Another tweak in amforth32.ld is the addition of
(NOLOAD)flag to some of the sections, which marks the section as not having any content in the file. It was one of the AI recommendations to deal with the slow load problem on RV qemu, but it didn't help because the issue isn't loading things from file but zeroing out of empty memory and the (NOLOAD) doesn't really affect that. But the sections are marked correctly this way and I figured I may as well leave it there.Otherwise the actual fix is the change of the
-device loaderto use the.binfile instead of the.elffile and thus bypassing the ELF loading logic altogether:While fussing around with the segments I had to change the way the
amramhiallocation of the available RAM was done, by moving thestack_startcomputation up and using it in theamramhidefinition. This triggered a discovery of an issue on hifive which has so little RAM that there wan't enough room for both the default amount oframpool_sizeand__stack_size. To solve it I moved__stack_sizeinto config.s and reduced both in hifive's config.s so that things could actually fit.With these fixes I was able to enable the CI tests for arm/linux and things seem to be happy now.