# Boot sequence

One of Dusk OS' defining qualities is the fact that it boots from a tiny kernel
and then builds the entirety of the system from source, at boot time. This page
describes the boot process.

## Arch-specific bootloader

When the machine powers up, what it does depends on that machine. Arch-specific
provisions have to be made to ensure that:

1. The binary kernel is loaded in memory.
2. The "boot payload" (see below) is loaded in memory and that the kernel knows
   where to find it.
3. We jump to the kernel's first address in memory.

At this point, we have the HAL [doc/hal] as well as an interpret loop. After
having done its core initialization (see [doc/kernel]), the kernel starts its
interpret loop by feeding itself from its boot payload.

## Boot payload

The "boot payload" is a stream of source code that the kernel interprets at
boot time to become whatever it's destined to become. It's placed in memory by
the bootloader and is read from there.

In the near-totality of the time, it begins with [xcomp/boot.fs]. Once this
code is interpreted, we have a lot of useful words, which are documented in
[doc/dict].

Then, in the vast majority of cases, we'll want I/O and files, which means that
[io/stream] and [fs/core] will follow in the payload. These units imply Big
Moustache [lib/bm].

Then, what follows is usually the drivers and filesystems that will allow us to
call "bootfs!".

For example, the boot payload for the PC is a concatenation /drv/pc/int13h.fs
and /fs/fat.fs (along with their respective dependencies).

All of this is then followed by the "glue code".

## Glue code

When we created Dusk's boot media, we didn't only concatenate a few units to the
payload, we also appended to it what we call the "glue code".

That code is system-specific code that wraps things together to provide it with
either it's final destination or a way to load "/init.fs".

If we have a system with a very specific purpose and don't really need the
configurability of "/init.fs", then we can just call whatever loop we want to
call and be done with it.

For the majority of interactive systems, we'll be interested in the flexibility
that "/init.fs" allows so the role of the glue code will be to:

1. Initialize fs/core through "bootfs!".
2. Load /init.fs
3. Call "quit"

Then, the boot payload ends because it is expected that whatever the "init" word
does will set up a new input stream.

## init.fs

What the init.fs file contains is up to the operator and is meant to be easy to
change. At that point, we have the base dictionary, I/O, files, we're pretty
well set up.

The init.fs file can do whatever it wants, but if the goal is to boot to an
interactive system, it will have the responsibility of setting up that
interactive input. This usually involves "quit hooks" [doc/usage/flow] and
setting ABORTPTR to its "regular behavior" be making it point to (abort).

This is what [io/prompt] does.

After having loaded init.fs, the boot payload does one last thing: call "quit".
This will trigger the quit hook installed by the interactive system, so that the
input stream no longer comes from the boot payload.

And that's it, you're booted up!
