# Deploying Dusk OS

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.

## 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 "payload" (see [doc/boot]) 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

The Dusk OS repository doesn't contain deployment recipes for specific machines.
This collection of recipe live in a separate code repository named
duskos-deployments, which is available at http://duskos.org/deployments.html.

## 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 "payload" in memory. By "payload", 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 payload so that the "in<" 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.

Then, get an interpret loop running as fast as you can so you can feed your
in-development kernel with stuff to debug with. Initially, it will be whatever
contents help you debug your new kernel words at the most basic level.
Eventually, you'll feed it with more serious content: xcomp/boot.

### Testing the kernel with xcomp/boot

Compiling and testing the [xcomp/boot.fs] unit 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 xcomp/boot and, say, instantiate a dummy struct, then you can
be confident that your kernel is solid.

What you want to do is to go gradually. Gradually feed a bit or xcomp/boot to
your kernel and test the result through whatever means.

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 "in<". Something
like "blink my LED and loop forever". We're good? alright. Now copy the first
few lines of xcomp/boot (that code that defines "SYSVARS") and copy that into
your bootloader payload. 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 "f<<". 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 fs/fat in.

For this, I recommend looking at how the PC platform does it. It should look the
same for all targets: we stream xcomp/boot in, then then sys/io and sys/file,
then the storage driver, then fs/fat, then the "glue" file, which create an
instance of Filesystem and feed it to "bootfs!".

### 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!
