The POSIX VM is an implementation of a Dusk kernel written in C that can be compiled and ran on any POSIX platform. It's slow and not featureful, but it runs on many platforms.

Because every Dusk kernel must implement a HAL and because the purpose of this VM is to run on any POSIX platform, it has its own simplistic and inefficient bytecode that it runs on. It implements a HAL on top of it and bingo! we have a kernel.

This is the main "gateway" to Dusk OS as this VM is used as a launching platform to build Dusk binaries to actual targets.

Its filesystem is a tar snapshot of the fs directory that is taken at compile time and embedded in its binary.


To build the POSIX VM, you needs a POSIX system with a C compiler, Make and tar.

Build and run

Running make at the root of this project (that is, not in the posix/ directory, in its parent) yields a dusk executable. If you run it, you get an interactive Dusk console.

Dusk OS expects a non-canonical raw input. With a regular TTY, your input will be buffered and echoed twice and reads to it will be blocking. We don't want that. To avoid that, you can invoke it like this:

(stty -icanon -echo min 0; ./dusk; stty icanon echo)

make run does this for you.

The stdio structbind

The POSIX VM has a special stdio that wrap file descriptors 0 and 1 (stdin and stdout) into an I/O struct.

This wrapper replaces -1 (error) from fdread and fdwrite with zero. It's not quite right, but there's no straightforward ways to place that error condition into the IO subsystem in a way that makes it recoverable. So, hum, for now it works...

Out of band data transfers

In the POSIX VM, we treat file descriptors 3 and 4 in a special way. They're the "out of band transfer" streams. Because the purpose of the POSIX VM is mostly to compile binaries, we need a clean way to get source data in and binary data out and doing so through stdin/stdout/stderr is often messy.

In the Forth part of the POSIX VM, we have a dataio IO structbind that reads from FD 4 and writes to FD 3. This allows stuff like:

echo "Hello" > datain
echo "console :self dataio :spit" | ./dusk 4< datain

which will print "Hello!" to the console.


The POSIX VM exposes an API to interact with the host OS, mostly to interact with files and streams.

fdopen ( strpath write? -- ?size fd-or-0 )
    Run `open(2)` on `strpath` and yield its file descriptor or 0 if there's
    an error. If `write?` is nonzero, open it in R/W mode.

    If `fd` is nonzero, the size in bytes of the opened file is yielded as

fdclose ( fd -- )
    Run `close(2)` on `fd`.

fdread ( a u fd -- n )
    Run `read(2)` on `fd`, reading `u` bytes at destination address `a`.

fdwrite ( a u fd -- n )
    Run `write(2)` on `fd`, writing `u` bytes from source address `a`.

fdseek ( off fd -- )
    Run `lseek(2)` on `fd` with `whence=SEEK_SET` and offset `off`.