WatBIOS

WatBIOS is loaded by watload and the entry point is at 0x10000.

The watinit.asm file contains the entry point and segments are defined in segments.inc and segment order is defined in the link file. The BIOSinitEntry segment must be the first segment due to containing the entry point code _cstart_. Entry is via a far jump from watinit.asm switching from real mode to protected mode. On entry, the interrupts must be disabled and stay disabled.

The entry code first sets up the protected mode descriptors and the stack. The watload the location of real mode data in di/si:

typedef struct realmode_data {
    uint16_t IDTAddr; // IDT location
    uint16_t GDTAddr; // GDT location
    uint16_t MEMMapAddr; // BIOS memmap location
    uint16_t INT11RET; // Return from INT 0x11
    uint16_t INT15C0Size; // INT15 C0 number of bytes following
    uint8_t INT15C0Data[0x0F]; // Actual returned data from INT15 C0
    uint8_t VESAMajor; // VESA version major
    uint8_t VESAMinor; // VESA version minor
    uint16_t VESATotalMem; // VESA memory chunks
} realmode_data;

Note: Because of the above rmdata.inc and rndata.h must be kept synchronized.

This data is stored and registers are cleared as is normal for a known starting value. Next, a jump into _TEXT is executed. As a default, and probably will not change, the IDT will start at 0x00. Now move the IVT to an out of the way location at 0x90000 and clear the old IVT area with 0x00. This module also sets BSS and stack parameters.

Finally, an IODelay is calculated calling FindIODelay. I am not sure if I need the IODelay, but at this point I have it. The code for IODelay is located in iodelay.asm and timer.inc which was pulled in from an old loader project. The defines used do not match those in other C-headers. This probably needs to be fixed in the future. A jump to the start of C-code in ldrinit.c is executed.

Execution picks up in ldrinit.c as C-code at main(). At this point ldrinit.c is used for calling functions and printing debug information. The module defines the global bootparams structure to store all system information as it is processed. There are two calls:

init_pics( )
detect_memory( )

Initial Memory Map

The initial probe for memory is performed in watload and stored at a default address of 0000:0900. This address is passed to watbios as a hand-off check and in case the location changes, symbol _MMPADDR. Three probes are performed, following an older Linux method, INT 0x15 88, e801, and e802.

BIOS Function: INT 0x15, AH = 0x88

This function may limit itself to reporting 15M (for legacy reasons) even if BIOS detects more memory than that. It may also report up to 64M. It only reports contiguous (usable) RAM. Stored in a 16bit (2 byte) value at _MMPADDR + 0. In watbios, value is retrieved to meminfo.ext_mem_k representing number of contiguous KB of usable RAM starting at 0x00100000. If contains signature then there was an error.

BIOS Function: INT 0x15, AX = 0xE801

BIOS Function: INT 0x15, EAX = 0xE820

Each e820 entry is 24 bytes stored sequentially, starting at _MMPADDR + 0x0F with the format:

  • 8 bytes – memory chunk start;
  • 8 bytes – memory chunk length;
  • 4 bytes – memory type
  • 4 bytes – four NOPs 0x90 as separator