Overview

The FreeWorld OS UEFI bootloader provides complete modern firmware-based booting for x64 systems. It replaces legacy BIOS boot and provides better hardware support, faster boot times, and modern features like Secure Boot readiness.

✅ Fully Implemented

Key Features: EFI System Partition support, boot parameter passing, memory map handling, ACPI support, initrd support, compression detection

Components

1. UEFI Bootloader

Location: boot/uefi/bootx64.c

Complete EFI application that:

  • Early Hardware Detection: Detects CPU, memory, ACPI, PCI, storage
  • Kernel Loading: Loads kernel from EFI System Partition
  • Compression Detection: Detects gzip, LZMA2/XZ, ZSTD compression
  • Initrd Loading: Loads initial ramdisk if present
  • Memory Map: Retrieves and manages EFI memory map
  • ExitBootServices: Properly exits boot services
  • Boot Parameters: Builds and passes boot parameter structure

Key Functions

  • efi_main() - Main EFI entry point
  • DetectHardwareEarly() - Early hardware detection
  • LoadKernel() - Load kernel from ESP
  • LoadInitrd() - Load initrd from ESP
  • GetMemoryMap() - Get EFI memory map
  • ExitBootServices() - Exit boot services
  • DecompressKernel() - Detect and handle compression

2. Boot Parameters

Location: boot/uefi/boot_params.h

Structured boot parameter passing between bootloader and kernel:

  • Magic Number: Validation (BOOT_PARAMS_MAGIC)
  • Memory Map: EFI memory map pointer and metadata
  • ACPI RSDP: ACPI Root System Description Pointer (retrieved from UEFI System Table BEFORE ExitBootServices)
  • GOP Framebuffer: Graphics Output Protocol framebuffer information (base, size, width, height, pixels per scanline, bits per pixel)
  • Initrd: Initial ramdisk address and size
  • Command Line: Boot command-line arguments (UTF-16)
Important: All UEFI data (memory map, ACPI RSDP, GOP framebuffer) must be retrieved BEFORE calling ExitBootServices(), as UEFI services are no longer available after that point.

3. Kernel Entry Point

Location: kernel/arch/x64/kernel_entry_uefi.asm

64-bit long mode entry point that:

  • Receives Boot Parameters: Extracts boot parameter structure (passed in RDI)
  • Extracts UEFI Data: Parses framebuffer, memory map, ACPI RSDP from boot parameters
  • Initializes Framebuffer Console: Sets up GOP framebuffer for text output (replaces serial debugging)
  • Initializes Kernel: Calls kernel_init_64_uefi for UEFI-aware initialization
  • No Mode Transitions: Already in 64-bit long mode from UEFI

4. Decompression Detection

Location: boot/uefi/decompress.c

Compression format detection:

  • gzip: Detects 0x1F 0x8B magic
  • LZMA2/XZ: Detects XZ magic bytes
  • ZSTD: Detects ZSTD magic bytes
  • Note: Full decompression handled by kernel if needed

Boot Flow

UEFI Boot Sequence

UEFI Firmware
    ↓
Load bootx64.efi from /EFI/BOOT/ or /EFI/FreeWorld/
    ↓
bootx64.efi:
    [1/5] Early Hardware Detection
        - CPU detection
        - Memory detection (via EFI memory map)
        - ACPI table discovery
        - PCI presence detection
        - Storage detection
    ↓
    [2/5] Load Kernel
        - Search for kernel in ESP
        - Allocate memory for kernel
        - Read kernel file
    ↓
    [3/5] Decompress Kernel (if compressed)
        - Detect compression format
        - Decompress or pass to kernel
    ↓
    [4/5] Load Initrd (optional)
        - Search for initrd in ESP
        - Allocate memory for initrd
        - Read initrd file
    ↓
    [5/5] Prepare Boot Services Exit
        - Get memory map (via GetMemoryMap)
        - Get ACPI RSDP (from UEFI System Table Configuration Table)
        - Get GOP framebuffer info (via Graphics Output Protocol)
        - Build boot parameters (stash all UEFI data)
        - ExitBootServices (UEFI services no longer available)
        - Pass boot parameters to kernel (via RDI register)
        - Jump to kernel_entry_uefi
    ↓
kernel_entry_uefi (64-bit long mode):
    - Extract boot parameters from RDI
    - Extract framebuffer info (base, size, width, height)
    - Extract memory map info
    - Extract ACPI RSDP
    - Initialize framebuffer console (GOP-based, not serial)
    - Call kernel_init_64_uefi
    - Enter kernel main loop

Boot Parameters Structure

typedef struct {
    uint64_t magic;              // BOOT_PARAMS_MAGIC ("FWOS")
    uint64_t version;            // BOOT_PARAMS_VERSION
    void* memory_map;            // EFI memory map pointer
    uint64_t memory_map_size;    // Memory map size in bytes
    uint64_t descriptor_size;    // Size of each descriptor
    uint32_t descriptor_version; // Descriptor version
    void* acpi_rsdp;             // ACPI RSDP pointer (from UEFI System Table)
    void* initrd_address;        // Initrd address (or NULL)
    uint64_t initrd_size;        // Initrd size in bytes
    void* command_line;          // Boot command line (UTF-16, or NULL)
    // GOP Framebuffer Information (NEW in UEFI migration)
    uint64_t framebuffer_base;   // Physical framebuffer base address
    uint64_t framebuffer_size;   // Framebuffer size in bytes
    uint32_t framebuffer_width;  // Screen width in pixels
    uint32_t framebuffer_height; // Screen height in pixels
    uint32_t pixels_per_scanline;// Pixels per scanline
    uint32_t framebuffer_bpp;   // Bits per pixel
} boot_params_t;

Boot Parameter Flags

  • BOOT_FLAG_VERBOSE - Verbose boot output
  • BOOT_FLAG_DEBUG - Debug mode
  • BOOT_FLAG_SINGLE_USER - Single user mode
  • BOOT_FLAG_NO_INITRD - Skip initrd

EFI System Partition (ESP)

Directory Structure

/EFI/
├── BOOT/
│   └── bootx64.efi          # Standard UEFI boot path
└── FreeWorld/
    ├── bootx64.efi          # FreeWorld bootloader
    ├── fwoskrnl.exe         # Kernel
    └── initrd.img           # Initial ramdisk (optional)

File Locations

The bootloader searches for the kernel in this order:

  1. \EFI\FreeWorld\fwoskrnl.exe
  2. \fwoskrnl.exe
  3. \kernel\fwoskrnl.exe

The bootloader searches for initrd in this order:

  1. \EFI\FreeWorld\initrd.img
  2. \initrd.img

Building

Prerequisites

# Install UEFI development tools
sudo apt-get install gnu-efi

Build Bootloader

cd boot/uefi
make

This creates bootx64.efi - the UEFI bootloader.

Create Disk Image

./scripts/create-disk-uefi.sh

This creates build/freeworld_uefi.img with GPT partitions and ESP.

Testing

QEMU with OVMF

./scripts/test-boot-uefi.sh

Manual QEMU Command

qemu-system-x86_64 \
    -drive file=build/freeworld_uefi.img,format=raw \
    -bios /usr/share/ovmf/OVMF.fd \
    -m 512M \
    -serial stdio

Real Hardware

  1. Copy bootx64.efi to ESP: /EFI/FreeWorld/bootx64.efi
  2. Copy kernel to ESP: /EFI/FreeWorld/fwoskrnl.exe
  3. Add FreeWorld to UEFI boot menu (or use as default)

Boot Command Line

Setting Boot Parameters

Boot command line can be set via EFI variables:

# From EFI shell or boot manager
efi-setvar BootParameters \
    -guid {8BE4DF61-93CA-11D2-AA0D-00E09802402A} \
    -s "root=/dev/sda2 quiet"

Common Boot Options

  • root= - Root filesystem device
  • quiet - Quiet boot (minimal output)
  • debug - Debug mode
  • single - Single user mode
  • initrd= - Initrd path (if not in standard location)

Advantages Over BIOS Boot

  • No Mode Transitions: Direct 64-bit entry, no 16-bit/32-bit code
  • Better Hardware Support: UEFI provides more hardware information
  • Faster Boot: More efficient initialization
  • Modern Standards: Uses modern UEFI protocols
  • Secure Boot Ready: Can be extended for Secure Boot support
  • Better Error Handling: UEFI provides better error reporting
  • Large Disk Support: GPT partition table support
  • Network Boot: Can be extended for PXE boot

Integration Points

With Kernel

The kernel receives boot parameters via the boot_params_t structure and uses them for:

  • Memory Management: UEFI memory map for physical memory manager (replaces E820)
  • ACPI Table Parsing: RSDP from UEFI System Table (no memory searching needed)
  • Graphics: GOP framebuffer for console output (replaces VGA/VESA)
  • Initrd Mounting: Initrd address and size for filesystem initialization
  • Boot Option Parsing: Command-line arguments for kernel configuration

With Hardware Detection

UEFI provides hardware information that the kernel uses for:

  • CPU: Already in 64-bit long mode, CPU features available via CPUID
  • Memory: UEFI memory map provides complete memory layout (replaces E820)
  • ACPI: RSDP in UEFI System Table Configuration Table (no memory searching)
  • Graphics: GOP framebuffer provides linear framebuffer (replaces VGA/VESA)
  • Storage: UEFI Simple File System Protocol for disk access

UEFI Migration Status

✅ UEFI Migration Complete (2025)
FreeWorld OS has been fully migrated from legacy BIOS to modern UEFI boot. All components now use UEFI protocols and modern hardware interfaces.

Completed Migrations

  • Bootloader: UEFI bootloader with proper data stashing
  • Graphics: GOP framebuffer (replaces VGA/VESA)
  • Memory: UEFI memory map (replaces E820)
  • ACPI: RSDP from UEFI System Table
  • Interrupts: I/O APIC (replaces legacy PIC)
  • Timers: HPET (replaces legacy PIT)
  • Drivers: USB xHCI, NVMe, AHCI via PCI enumeration
  • Console: Framebuffer console (replaces serial debugging)

Deprecated/Legacy Components

  • ⚠️ VGA/VESA: Replaced by GOP framebuffer
  • ⚠️ Serial Port Debugging: Replaced by framebuffer console
  • ⚠️ E820 Memory Detection: Replaced by UEFI memory map
  • ⚠️ Legacy PIC: Replaced by I/O APIC
  • ⚠️ PIT Timer: Replaced by HPET
  • ⚠️ ATA PIO: Replaced by NVMe/AHCI

Future Enhancements

  • Secure Boot support (sign bootloader and kernel)
  • Full decompression in bootloader (currently kernel handles it)
  • Graphical boot menu for kernel selection
  • Recovery mode automatic boot option
  • Persistent boot logs
  • Multi-boot support (multiple kernel versions)
  • PXE network boot support

Related Documentation