# Dusk's POSIX VM 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. ## Requirements 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. ## API 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`.