# Deploying Dusk OS

Prerequisites: arch, sys/io

To deploy Dusk OS on your hardware, you need to craft a bootable media for it.
If you're deploying to an already supported platform, then it's only a matter of
using the existing build scripts, maybe tweak the init.fs a bit.

If you're deploying hardware that isn't supported yet, then you'll need to craft
those build scripts yourself.

To understand this document, you should have read doc/usage and doc/arch.

## The general steps

The steps to create a build media are the same everywhere:

1. Prepare a media with FAT on it.
2. Devise a way to make this media bootable so that it loads the kernel and boot
   layer in memory, and execute it.
3. Compile the kernel, install it on the media.
4. Create the boot "stream" (boot source files lined up next to each other) and
   place it on the media.
5. Copy all Dusk files in the target FAT volume.
6. Create a init.fs file and place it in the target FAT volume.

## Supported platforms

To deploy to a supported platform, it's generally only a matter of tweaking the
init.fs file and run the build script. You should follow hardware-dependent
deploy documentation:

* PC: hw/i386/pc/deploy

## New platforms

Deploying Dusk to a new platform is quite a challenge which involves a lot of
trial and errors. Maybe these little guidelines can help you.

### Bootloader

The first thing you have to do is to write your bootloader. I don't know your
platform, so I can't tell you how, but what I can tell you is that it has to
load both the kernel and the boot "stream" in memory. By "stream", I mean that
the content of all the source files that compose the boot sequence are lined up
one after the other so that the Forth interpreter can consume it all from
memory.

You have to place your boot stream so that the "boot<" word reads from it. It's
generally going to be right after the kernel in memory, but it doesn't have to.

### Writing the kernel

Writing the kernel is pretty hard. You will probably want to do this in an
emulator. My advice is to try to find a way to test each word as you write it,
however hacked up that way is. For the PC, my trick was to write stuff to memory
at $b8000 (the vga text mode buffer) because I didn't have a word "emit" yet. If
you're in an emulator, you have access to machine state, so you can debug
through that too.

### Testing bootsrc

Compiling and testing the "bootsrc" layer is the best way to iron kinks out of
the kernel. Even though all your words were tested in isolation as you built the
kernel, it's likely that subtle bugs are still lurking in there, but if your
kernel can compile bootsrc and, say, instantiate a dummy struct, then you can be
confident that your kernel is solid.

Again, you don't have "emit" yet, so you need some tricks to visualize the
results of your tests. A blinking LED maybe?

So, what you do is that you begin with a dummy test right at "boot<". Something
like "blink my LED and loop forever". We're good? alright. Now copy the first
few lines of bootsrc (those that handle ":" and ";") and copy that into your
bootloader stream. Then, create a word definition that blinks your LED. Still
good? The hard part's over! Now let's get those other lines of code wiggling!

So, you have instantiated that dummy struct? It's working? Seriously, the hard
part is really over. Congratulations!

### Storage

Magic is about to trickle in. You'll want to get to your first "fload". You need
to begin writing your storage driver. I can't tell you how, but as always, you
should proceed in incremental steps. Read a sector, test it. Does it work for
other sectors too? Well, that sounds good, it looks like you can plug fatlo in.

For this, I recommend looking at how the PC platform does it. It should look the
same for all targets: we stream bootsrc in, then the storage driver, then fatlo,
then the "glue" file, which create an instance of Filesystem as well as a
"bootfs" structbind to it.

If you look at PC's glue.fs, you'll also see something about "floaded," the goal
of that is to "register" files in the boot stream as "loaded" so that "?f<<"
doesn't load them twice.

### init.fs

You're almost done! Your next step is to create a dummy init.fs, again blinking
your LED. Working? good!

Did you try a f<< call? Working too? You're on a roll!

You have a working Dusk system. The rest is up to you. You probably want a
prompt, right? To have that, you need to set the Console. So, write your drivers
for input and output (a serial console is usually the quickest way to this) and
have those drivers create structures that extend IO. You'll want your input
driver to implement :readbuf and your output driver to implement :writebuf. I
recommend looking at PC drivers for inspiration.

Once you have those drivers, you instantiate them in your init.fs and plug them
to the Console.

That's all you need driver-wise. You're now ready to write the "user" part of
your init.fs, the one that will load the sys/rdln subsystem and define the
"init" word. You can copy it from xcomp/init.fs or write your own.

You're done, Congratulations!
