BOOTMGR - FreeWorld Boot Manager
Overview
BOOTMGR (Boot Manager) is the initial boot loader for FreeWorld OS. It consists of two stages:
- Stage 1 (bootloader_stage1.asm): The MBR bootloader (512 bytes) that loads stage 2
- Stage 2 (bootloader_ui.asm): The graphical bootloader that displays the boot menu and loads the kernel
Boot Sector Structure
The boot sector follows the standard PC boot sector format:
- Size: 512 bytes
- Boot Signature: 0xAA55 at bytes 510-511
- Entry Point: 0x7C00 (standard BIOS load address)
Code Structure
Assembly Directives
bits 16 ; 16-bit real mode org 0x7C00 ; BIOS loads boot sector at 0x7C00
Entry Point: start
The start label is the entry point executed by the BIOS:
start:
cli ; Disable interrupts
xor ax, ax ; Clear AX register
mov ds, ax ; Set data segment to 0
mov es, ax ; Set extra segment to 0
mov ss, ax ; Set stack segment to 0
mov sp, 0x7C00 ; Set stack pointer
Functions
init_serial
Initializes serial port COM1 at 0x3F8 for debugging output:
init_serial:
; Set baud rate to 38400 (divisor 0x0003)
; Configure: 8 bits, no parity, 1 stop bit
; Enable FIFO
Purpose: Enables serial port debugging output alongside video output.
print_serial
Prints a character to the serial port (COM1):
print_serial:
; Wait for transmit ready
; Send character to COM1 data port
Purpose: Outputs debug information to serial port for QEMU debugging.
print_string
Displays a null-terminated string using BIOS interrupt 0x10 and serial port:
print_string:
lodsb ; Load byte from [SI] into AL, increment SI
or al, al ; Check if AL is zero (end of string)
jz done ; Jump to done if zero
mov ah, 0x0E ; BIOS teletype function
int 0x10 ; BIOS video interrupt
jmp print_string ; Loop
done:
ret ; Return
Disk Read (Stage 1)
Stage 1 loads stage 2 from disk using LBA extended read with CHS fallback:
; Check for LBA extended read support
mov ah, 0x41 ; Check Extensions Present
mov bx, 0x55AA
mov dl, [boot_device]
int 0x13
jc .use_chs ; Fall back to CHS if not supported
; Use LBA extended read (Disk Address Packet)
mov si, dap ; DAP structure
mov ah, 0x42 ; Extended Read Sectors
mov dl, [boot_device]
int 0x13
jnc .verify_load ; Success
.use_chs:
; CHS addressing (required for floppy disks)
mov ah, 0x02 ; Read sectors
mov al, 4 ; Read 4 sectors (stage 2)
mov ch, 0 ; Cylinder 0
mov cl, 3 ; CHS sector 3 (physical sector 2)
mov dh, 0 ; Head 0
mov dl, [boot_device]
xor bx, bx
mov es, bx
mov bx, 0x7E00 ; Load to 0x0000:0x7E00
int 0x13
.verify_load:
; Verify stage 2 signature ('OB' = 0x424F)
cmp byte [es:0x7E00], 'O'
jne .bad_sig
cmp byte [es:0x7E00 + 1], 'B'
jne .bad_sig
jmp 0x0000:0x7E00 ; Jump to stage 2
Purpose: Loads stage 2 bootloader from disk into memory at 0x0000:0x7E00.
Critical: Uses CHS sector 3 (not 2) because CHS sectors are 1-based while physical sectors are 0-based.
Error Handling: Checks for disk read errors and verifies stage 2 signature ('OB') before jumping.
- Physical sector 0 = CHS sector 1 (MBR)
- Physical sector 2 = CHS sector 3 (Stage 2 start)
- Physical sector 6 = CHS sector 7 (Graphics start)
- Physical sector 33 = CHS sector 33 (Kernel start)
JMP Instructions
Jump to Kernel
After loading the kernel, BOOTMGR jumps to the kernel entry point:
jmp 0x1000:0x0000 ; Far jump to kernel at segment 0x1000, offset 0x0000
Jump in print_string Loop
Conditional jump used in the string printing loop:
jz done ; Jump if zero flag is set (end of string) jmp print_string ; Unconditional jump to continue loop
Variables and Constants
| Name | Type | Value | Description |
|---|---|---|---|
boot_msg |
String | 'FreeWorld Boot Manager v0.1' | Boot message displayed on startup |
0x7C00 |
Address | 0x7C00 | BIOS boot sector load address |
0xAA55 |
Signature | 0xAA55 | Boot sector signature (bytes 510-511) |
0x1000:0x0000 |
Address | Segment:Offset | Kernel entry point address |
Boot Process Flow
Stage 1 (bootloader_stage1.asm)
- BIOS loads boot sector (512 bytes) from disk to memory at 0x7C00
- BIOS jumps to 0x7C00 (start label)
- Stage 1 initializes segments, stack, and serial port
- Stage 1 initializes VGA text mode (80x25)
- Stage 1 displays "Loading FreeWorld OS..." message
- Stage 1 checks for LBA extended read support
- Stage 1 loads stage 2 from CHS sector 3 (physical sector 2) to 0x0000:0x7E00
- Stage 1 verifies stage 2 signature ('OB')
- Stage 1 passes boot device number to stage 2
- Stage 1 jumps to stage 2 at 0x0000:0x7E00
Stage 2 (bootloader_ui.asm)
- Stage 2 initializes segments and stack
- Stage 2 initializes graphics mode (VESA or VGA)
- Stage 2 loads graphics from disk (logo, background, icons)
- Stage 2 displays graphical boot menu
- Stage 2 waits for user selection
- Stage 2 loads kernel from CHS sector 33 (physical sector 33) to 0x1000:0x0000
- Stage 2 verifies kernel signature ('FREEWORL')
- Stage 2 jumps to kernel entry point (0x1000:0x0000)
Memory Layout
0x0000 - 0x03FF : Interrupt Vector Table 0x0400 - 0x04FF : BIOS Data Area 0x0500 - 0x7BFF : Available 0x7C00 - 0x7DFF : Stage 1 Bootloader (512 bytes) 0x7E00 - 0x9FFF : Stage 2 Bootloader (~2KB) 0x8000 - 0x8FFF : Graphics Index Table 0x9000 - 0x9FFF : Logo Graphics Buffer 0xA000 - 0xAFFF : Background Graphics Buffer 0xB000 - 0xB7FF : Selection Highlight Buffer 0xB800 - 0xBFFF : Progress Bar Buffer 0xC000 - 0xC1FF : Error Icon Buffer 0xC200 - 0xC3FF : Success Icon Buffer 0xA000 - 0xBFFF : Video Memory (VGA) 0xC000 - 0xFFFF : BIOS ROM 0x1000:0x0000 : Kernel Entry Point
Disk Layout
The boot disk is organized as follows:
Physical Sector 0 : Stage 1 Bootloader (MBR, 512 bytes) Physical Sector 1 : Unused Physical Sector 2 : Stage 2 Bootloader start (CHS sector 3) Physical Sectors 2-5: Stage 2 Bootloader (4 sectors, ~2KB) Physical Sector 6 : Graphics start (Logo, CHS sector 7) Physical Sectors 6-32: Graphics resources Physical Sector 33 : Kernel start (CHS sector 33)
BIOS Interrupts Used
| Interrupt | Function | AH Register | Description |
|---|---|---|---|
| 0x10 | Video Services | 0x00 | Set video mode (AL=0x03 for 80x25 text mode) |
| 0x10 | Video Services | 0x0E | Teletype output - prints character in AL register |
| 0x13 | Disk Services | 0x00 | Reset disk system |
| 0x13 | Disk Services | 0x41 | Check if extended disk access functions are available |
| 0x13 | Disk Services | 0x42 | Extended Read Sectors (LBA) - uses Disk Address Packet (DAP) |
| 0x13 | Disk Services | 0x02 | Read Sectors (CHS) - traditional cylinder-head-sector addressing |
Build Instructions
To build the bootloader:
# Build Stage 1 cd boot nasm -f bin bootloader_stage1.asm -o build/bootloader_stage1.bin # Build Stage 2 make bootloader_ui.bin # Create boot image ./scripts/fix-boot-layout.sh
The output file bootloader_stage1.bin is exactly 512 bytes and must be written to the first sector (sector 0) of a bootable disk.
The fix-boot-layout.sh script ensures correct placement of all boot components on the disk image.
Integration Points
- BIOS/UEFI: Loaded by BIOS at 0x7C00
- Kernel: Loads and transfers control to kernel at 0x1000:0x0000 (linear 0x10000)
- Serial Port: Outputs debug information to COM1 (0x3F8) for QEMU debugging
- BCD: May read BCD configuration (future)
Debug Output
Stage 1 outputs messages to both video (BIOS INT 0x10) and serial port (COM1):
- "S1" - Stage 1 started (serial only)
- "Loading FreeWorld OS..." - Before loading stage 2
- "OK" - Disk read successful (serial only)
- "JMP" - Jumping to stage 2 (serial only)
- "Disk read failed!" - If disk read fails
- "Bad signature! Got: XX" - If stage 2 signature doesn't match
Serial port output is particularly useful for debugging in QEMU with -serial stdio or -serial file:serial.log.
strings serial.log or hexdump -C serial.log to view the output after a QEMU run.
Recent Fixes
The following critical fixes were implemented:
- CHS Sector Mapping: Fixed incorrect sector calculation - physical sector 2 now correctly maps to CHS sector 3
- LBA Extended Read: Implemented LBA extended read (INT 0x13, AH=0x42) with automatic fallback to CHS
- Graphics Loader: Fixed graphics loader to use correct CHS sectors matching disk layout
- Disk Reset: Added disk reset before reading to ensure reliable disk access
- Register Preservation: Fixed register preservation during INT 0x13 calls