# Deploying Dusk to a PC

Prerequisites: arch, deploy

As long as the PC has a 80386 CPU, it should be good enough to run Dusk, which
has very small memory and disk requirements.

So far, the most underpowered computer Dusk has been known to run on is an old
Pentium 75Mhz laptop from Zenith Data Systems with 16MB of RAM. It boots in
about 5 seconds and can load DuskCC from its ATA disk in about another 5
seconds.

Dusk can boot from whatever media the BIOS can read. Its boot-time drive is
[drv/pc/int13h.fs], a Drive implementation that can read and write to the boot
drive through the "int13h" word implemented in the PC-specific part of the i386
kernel [xcomp/i386/pc/kernel.fs].

You *can* stay on this drive if you want, but calling BIOS from protected mode
is tricky and error prone. It's better to get off that Drive implementation as
soon as possible.

At this time, Dusk has storage drivers for floppy, ATA and AHCI storage
controllers. USB storage isn't implemented yet.

## Creating a boot media for the PC

Whatever the BIOS can read through INT13h, Dusk can boot from it. Dusk is
installed as a FAT volume with a bootloader embedded in its first sector.
Following that first sector are a few dozens "reserved" sectors which contain
Dusk's kernel followed by its embedded boot code.

The task of the bootloader is to load those reserved sectors in memory, go in
32-bit protected mode, then jump to the first address of these sectors we've
just loaded. Then, bootstrapping takes placed normally.

Then, what you need to do is to copy all files of the Dusk system into that new
FAT volume, and craft a proper "/init.fs" file.

There is some helper code to craft such a volume in xcomp/i386/pc/build.fs.
Upon loading this unit, a bootloader and kernel are compiled, and FAT creation
helper words become available. 

Here's an example code listing that deploys to a drive "mydrv":

  f<< /xcomp/i386/pc/build.fs
  fatopts$
  4 to fatopts secperclus
  68 to fatopts rsvdsec
  mydrv FAT newFAT
  mydrv FAT :mountvolume value myfat
  bootfs :self myfat copyfs
  mydrv setupMBR
  mydrv DriveIO :new $200 over IO :seek spitBoot
  S" /xcomp/i386/pc/init.fs" S" /xcomp/init.fs" myfat combineInit

What this does is:

1. Create a new FAT volume (FAT12 only for now) in the specified drive with the
   specified cluster count.
2. Copy all files present in the current boot filesystem into this new FAT
   volume.
3. Copy the bootloader in the first sector, embedded in FAT headers.
4. Copy the kernel in the reserved sectors.
5. After the kernel, still in the reserved sectors, copy all files that the
   kernel needs for bootstrapping on the PC (for example, the int13h driver).

After that's done, you're almost ready to boot. The only thing you have to do is
to tweak the "/init.fs" file in that new FAT volume. The one from your current
system was copied and that might not be what you need on your target machine.
For example, you might want to change the storage driver parameters.

That's it! you have a new bootable Dusk media.

### Booting from a floppy

Dusk's bootloader uses FAT headers to determine boot device geometry. Except for
floppies, almost all boot media have the same geometry: 63 sectors per track and
16 heads and drive number 128.

If you let these default be written to a 1.44MB floppy, that floppy will not
boot. To fix this problem, you will have to change "fatops" so that "secpertrk",
"numheads" and "drvnum" FAT options are 18, 2 and 0. Then, your floppy will
boot.

### Bootloader options

If you look at mbr.fs, you'll see some commented out code. Those are some
options you can enable if you need them.

One of them is a keyboard-enabled alternate boot location chooser. At boot, it
checks if left control key is pressed and if it is, it loads its sector sequence
(same length as the main sequence, same destination too) from another CHS
location. In the example code, it loads from cylinder 1 instead of 0.

This is useful if you want to try a new kernel or boot code without breaking
your system.

Another piece of commented code is simply to wait for a keypress before going to
video mode 80x25 so that you have enough time to see debug output.

## Troubleshooting

This section is for various troubleshooting notes.

### Can't boot?

This is a frequent problem and many things can be wrong. The first thing to
check when you can't boot is to check at what level the break happens. You have
to try a few things in order.

1. Minimal /init.fs: Remove everything from the init.fs except the code needed
to get something to spit on screen. If you can spit something on screen, you're
good to go, add things back one at a time and see when it breaks.

2. If you can't get something on screen, you'll have to use a trick: write stuff
at $b8000, the VGA text buffer. Each character in the screen is 2 bytes wide.
The low byte is the character, the high byte is the color. To write a 'X', it's
"$758 $b8000 w!". What you can do is insert these little snippets at different
stages of the boot process: right on top of boot.fs, at the end of it, right
before the first "fload", right at the top of /init.fs. This gives you an idea
of where to look for problems.

3. Debug INT13H. In most other OSes, the console is setup before disk access is.
In Dusk, because of its peculiar boot process, it's not the case. It is
therefore very important to make sure that the boot process is able to read from
the disk. Some PCs have weird drive geometry and you should ensure that you have
the right one setup in your FAT headers. For example, I was really confused by
how I couldn't get my Zenith Data System Pentium 75Mhz laptop to cross the first
cylinder boundary, after head $0f (the BIOS *says* the HDD has 16 heads), but it
turns out that, on that 1G hard drive, the proper value for "numheads" is 64.
To do this kind of debugging, see hw/i386/pc/bios13.
