Syscalls are effects. The kernel is the last handler.
fxos is an operating system written in Loon, a language with algebraic effects. Programs ask for things — a file, the time, a pixel — by performing an effect. What that means is decided by whoever handles it: a sandbox, a tracer, a deterministic simulation, a record/replay tape, or, at the very bottom, hardware. There is no OS underneath. The program is the kernel.
[effect Console [write [String] Unit]]
[fn main []
[Console.write "hello from loon, running as the kernel\n"]]
Boot that on a RISC-V machine and the outermost handler is a UART driver. Run it on your laptop and it's a libc write. The source cannot tell, and neither can its output — that equivalence is enforced by test.
os/ | the OS as a Loon library: Sys effects, kernel/sandbox/trace/tape handlers, a cooperative scheduler, a sealed simulation, chaos + supervision, a lossy network, agent containment. Runs anywhere Loon runs. |
kernel/ | fxk — the bare-metal side. A RISC-V unikernel that boots under QEMU, interprets a Loon boot image, and hands unhandled effects to drivers (UART, framebuffer). |
docs/design.md | the design: model, effect ABI, roadmap, decisions, measurements. |
# the language
cargo install --git https://github.com/ecto/loon loon-cli
# the OS library — sandbox, trace, replay, scheduler, simulation, chaos
loon run --unchecked os/demo-agent.oo
./os/test.sh
# the machine
brew install qemu && rustup target add riscv64gc-unknown-none-elf
make -C kernel run # boot Loon as the kernel, serial console
make -C kernel gui # boot with a display; a Loon program paints it
make -C kernel check # prove host and bare metal print the same bytesPhases 1–3 of the roadmap are shipped: the hosted OS library, cooperative processes, and a booting unikernel with a console and a framebuffer. Not yet: preemption, SMP, input, text on the display, static handler resolution, and speed (~500 ns per interpreted op).
One thing to know: the os/ library is dynamically correct — every test
passes — but Loon's static checker currently rejects it (heterogeneous maps
used as records, effect ops declared in a used module not visible to the
checker). Hence --unchecked. That is a bug in the language and is tracked
there; the flag goes away when it is fixed.
fxos depends on Loon as a tool, not a crate: kernel/build.rs runs
loon image to compile boot programs, and os/ is plain Loon source. The
boot-image format (loon image, eir/image.rs) is the ABI between the two
repos and is pinned by tests on the Loon side.