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.
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 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...
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
`?size`.
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`.