# 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, 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]. We also have namespaces, structs and the Drive structure, which is
documented in [doc/lib/drive].

Then, in the vast majority of cases, we'll want I/O and files, which means that
[sys/io.fs] and [sys/file.fs] will follow in the payload.

Then, what follows is usually the drivers and filesystems that will allow us to
call "bootfs!" (see [doc/sys/file]).

For example, the boot payload for the PC is a concatenation /drv/pc/int13h.fs,
/lib/drive.fs and then /fs/fat.fs.

All of this the 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 sys/file through "bootfs!" and "bootfloads,".
2. Load /init.fs
3. Call "init"

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.

Our role at that point is to define a "init" word that will take the input
stream out of the boot payload, because we're getting dangerously close to the
end of the road on that front.

Most of the time, this means setting up an interactive prompt, which is most
often done through [sys/rdln].

It's the boot payload's reponsibility to call "init" because otherwise, the
"init.fs" file isn't properly closed and monopolizes a file cursor.

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