Phobos The PHOBOS bootstrap


This page describes how PHOBOS is loaded into memory from the boot medium. Currently, only booting from diskette is supported. The diskette uses the standard FAT-12 format (first used with PC-DOS and MS-DOS), so it is easy to construct a suitable diskette.

The bootstrap operates in two stages. The first stage is contained in the diskette boot sector, which is the first logical sector on the diskette (track 0, head 0, sector 1). The second stage is found in a file called LOADER.BIN. This in turn loads the kernel, which is always in a file called KERNEL.EXE. The following sections describe these components in more detail.

Note that decimal numbers are written 'as is', and hexadecimal numbers are written with a trailing H except where otherwise noted.

Hardware and BIOS initialisation

On system reset, the BIOS is given control by the CPU. After performing tests and system initialisation, the BIOS starts the system boot operation; this all takes place in real mode, generally using 16 bit code, although some 32 bit instructions may be used. The actual sequence of operation depends on the BIOS options selected, but in most cases the BIOS will attempt to boot from the first diskette drive, which is all that we are concerned with here.

The boot operation consists of reading the first sector (cylinder 0, head 0, sector 1) from the boot device, and placing it into memory starting at address 0000:7C00H (segment 0, offset 7C00). Control is then transferred to address 0000:7C00H, i.e. with CS (the code segment register) set to 0000H, and IP (the instruction pointer) set to 7C00H. Note that this is functionally different to having CS set to 07C0H, and IP set to 0000H!

The first stage bootstrap

The first stage bootstrap occupies the single sector loaded by the BIOS, as stated above. The first instruction executed is at 0000:7C00H, which starts at the first byte in that sector. The instruction is a jump over some standard data areas, and invokes the main code. The following paragraphs summarise this code.

The principal problem is there is not enough room in this single sector for enough code to load the kernel. because of this, the aim of the code is to load another file called LOADER.BIN, which contains the extra code that is required.

First, the stack segment and stack pointer registers are set to locate the stack immediately below the boot code in memory (the stack runs towards lower addresses from there). Next, some calculations are done in order to determine the location of the start of the root directory; it appears after the boot block, any reserved sectors, and however many FATs have been put on the disk. The information needed to determine this is stored in the BIOS Parameter Block (BPB), which occupies the start of a boot sector, at least on most PC disks, preceded only by the aforementioned jump instruction. The whole root directory is read into memory, starting at 03C0:0000H.

The root directory is then scanned in order to find an entry for the file LOADER.BIN. Once found, this is loaded into memory immediately after the boot sector (i.e. at 0000:7E00H); this is a simple task because the file is a simple memory image. In principle, it could occupy several sectors, although just one is currently sufficient. The code which reads LOADER.BIN is very simple, and it assumes that LOADER.BIN is a contiguous file.

Once LOADER.BIN has been loaded, control is transferred to it at the label SECBOOT, to continue system loading. Note that there are two other procedures in the primary bootstrap; a message output routine, and a disk read routine. Both of these are also utilised by the second stage bootstrap, in order to save space. There are also various data items and messages filling up the small amount of remaining space in the initial boot sector.

The second stage bootstrap

The task of the second stage bootstrap is to load the file KERNEL.EXE into memory. This file has a more complex format, defined many years ago, and is the result of a standard compile and link operation. It may contain relocation entries, and also has a header detailing requirements for additional uninitialised memory areas.

The root directory is still in memory at 03C00:0000H. It is once again scanned, this time to find the entry for KERNEL.EXE. Once again, this file is assumed to be contiguous on the disk. Once the file has been located, its first sector (the header) is read into memory at 03A0:0000H. Information in the header is used to calculate the total size of the load module; this includes both the initialised and uninitialised portions. This size is not needed by the bootstrap, but must be passed to the kernel so that it can allocate space as necessary. It is a 32 bit value, and is stored in the kernel information area, located at 07C00:0000H, i.e. the start of the boot sector, since this area is no longer needed for anything else. This is a fixed location, and therefore is known to the kernel when it needs to retrieve the information stored there.

The kernel image is now read into memory from the KERNEL.EXE file. Any relocations (adjustments to locations that cannot be determined until load time) are now applied; these are detailed in the kernel file header read in earlier. The stack segment and stack pointer are set from the initial values stored in the kernel file header.

A further useful piece of information is the size of 'conventional' memory; that is, memory below the 1MB line; this is all that can be used by a program running strictly in real mode. Usually, it is 640KB, but some BIOS implementations 'steal' 1KB or more from the end, so the true value may be slightly less. A standard BIOS call is used to retrieve the conventional memory size; this is converted to 16 byte multiples (known as paragraphs) and the value is stored in the kernel information area.

The values of CS and IP for kernel entry (obtained from the kernel file header) are pushed onto the stack, and a far return instruction is used to transfer control to the kernel proper.

It is planned that data areas vacated by the boot code will be re-used at a later time.

Valid XHTML 1.0! Valid CSS!

This site is copyright © 2008 Bob Eager
Last updated: 11 Nov 2008