Hi.
Could someone tell me what aspects of the Crystal toolchain and libraries need to be extended or changed to target a bare metal environment for an existing LLVM supported processor architecture ?
I’m interested in targeting a bare metal Arm AArch64 environment. The aim is to incrementally explore the possible use of Crystal for firmware development as a first step.
The underlying assumptions are that so long as Crystal’s run-time requirements can be met for the bare-metal environment (things like memory allocators, GC aspects, signal/exception handling etc perhaps) and the application or use-case isn’t susceptible to the potential time determinism issues around the use of a GC etc, then the expressiveness of Crystal and it’s type-safety et al can be attractive for systems development.
Any thoughts appreciated.
At present I’m studying Lilith which I think would have had to address similar things.
Cheers
1 Like
Hi again.
Here are some things that I’ve learnt that I’d like to share in case they help someone, along with some additional questions that I have. Would appreciate any insights.
-
Some of the bare-metal crystal experiments I’ve seen so far are:
-
The Lilith strategy (which Stakach re-uses) is to use a modified compiler + custom allocator + custom conservative mark and sweep garbage collector + custom prelude. The allocator and the GC are a part of the OS kernel which IIUC links against the compiler library.
-
Some compiler modifications are to do with introducing a Markable class which dynamic types (such as Array and Hash) are made to inherit from. This class introduces scaffolding that helps the custom GC do its marking action.
-
Other compiler modifications are to do with making certain symbols accessible by the OS kernel (such as where the globals reside) which are then used by the custom GC.
-
And then there’s the custom prelude which re-implements most of the language primitives.
-
Question: What I don’t get is why should there be a custom prelude ? Why can’t the compiler’s ‘built-in’ prelude (crystal/src/prelude.cr) be used as-is especially since the allocator and GC are being used from outside the compiler ? Also: Why the need to have explicit Markability ? Doesn’t the built-in Boehm GC have all of that when working with the crystal compiler already ?
-
At present, my thinking is that a good solution to make Crystal usable for bare-metal targets would be:
-
Look for target “rich” run-time environment specific code or assumptions in the compiler and its supplied libs (Linux/Windows et al). Where applicable, find clean ways of making such code conditionally re-targetable to a bare-metal environment. The GNU target triple would be $ARCH-unknown-none. The code I am alluding to is anything that relies on OS kernel specific facilities (threads, processes, synchronisation primitives, signals, filesystem nuances et al). For such code, a reasonable set of assumptions can be made with regard to the bare-metal environment. Initially one can stub out complex bits in favour of a single threaded non-preemptive environment. Then more complexity can be added incrementally culminating in bridging to an RTOS etc.
-
Look for similar bits in the compiler supplied prelude. Try to define clean interfaces that make it possible to use as much of the prelude as possible by a bare-metal environment.
-
Do the same for any allocator and GC specific code and make it possible to conditionally link to a bare-metal environment specified GC and allocator combination. Basically analyse what Lilith has done and see if interfaces can be implemented that make linkage with a more general bare-metal environment as clean as possible.
-
Use an emulated environment (qemu for Cortex-M class microcontrollers) as the basis for all of this with the ultimate aim of migrating to real silicon (probably Raspberry Pi Pico which is well supported by micropython today).
-
Question: Does the above sound like a reasonable route to enabling crystal use in bare-metal environments ?
I’ll continue studying and experimenting and I hope to share what I learn in the hope that I don’t veer to far off. Any thoughts welcome! Thanks.
3 Likes
In this context, yes that’s what it means. Think micropython or mruby.
1 Like
@fork-bomber Hi, wonder if you got anywhere with this… I’d like to run Crystal on an RP2040.