Skip to content

Boot Process

NtinosTheGamer2324 edited this page Dec 28, 2025 · 2 revisions

Boot Process

This document describes the complete boot sequence of ModuOS from power-on to shell prompt.

Overview

ModuOS uses the Multiboot2 boot protocol with GRUB2 as the bootloader. The boot process transitions through several CPU modes before reaching the kernel proper.

Boot Stages

Power On → BIOS → GRUB2 → Multiboot2 → 
Protected Mode (32-bit) → Long Mode (64-bit) → 
Kernel Initialization → Shell

Stage 1: BIOS/UEFI

When the system powers on:

  1. BIOS/UEFI initializes hardware
  2. Reads Master Boot Record (MBR) or GPT
  3. Loads GRUB2 bootloader from boot sector
  4. Transfers control to GRUB

Stage 2: GRUB2 Bootloader

Configuration: targets/AMD64/iso/boot/grub/grub.cfg

menuentry "ModuOS" {
    multiboot2 /ModuOS/System64/mdsys.sqr
    boot
}

GRUB2:

  1. Displays boot menu
  2. Loads kernel (mdsys.sqr) into memory
  3. Parses Multiboot2 header
  4. Sets up initial environment
  5. Jumps to kernel entry point in Protected Mode (32-bit)

Multiboot2 Header

File: src/arch/AMD64/boot/header.asm

section .multiboot_header
header_start:
    dd 0xe85250d6           ; Magic number (Multiboot2)
    dd 0                    ; Architecture (i386 protected mode)
    dd header_end - header_start  ; Header length
    dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start))  ; Checksum
    
    ; End tag
    dw 0
    dw 0
    dd 8
header_end:

Information Provided by GRUB:

  • Memory map (available/reserved regions)
  • Boot device information
  • Loaded modules
  • Framebuffer info (if available)
  • ACPI tables location

Stage 3: 32-bit Bootstrap

File: src/arch/AMD64/boot/main.asm

3.1 Stack Setup

section .bss
align 16
stack_bottom:
    resb 16384              ; 16KB stack
stack_top:

section .text
bits 32
global start

start:
    mov esp, stack_top      ; Set up stack pointer
    mov edi, ebx            ; Save Multiboot2 info pointer

3.2 CPU Verification

; Check for CPUID support
pushfd
pop eax
mov ecx, eax
xor eax, 1 << 21
push eax
popfd
pushfd
pop eax
push ecx
popfd
cmp eax, ecx
je .no_cpuid                ; CPUID not supported

; Check for long mode
mov eax, 0x80000000
cpuid
cmp eax, 0x80000001
jb .no_long_mode

mov eax, 0x80000001
cpuid
test edx, 1 << 29           ; LM bit
jz .no_long_mode

3.3 Paging Setup

; Identity map first 2GB using 2MB pages

; PML4: Point to PDPT
mov eax, pdpt
or eax, 0b11                ; Present + Writable
mov [pml4], eax

; PDPT: Point to PD
mov eax, pd
or eax, 0b11
mov [pdpt], eax

; PD: Map 1024 entries (2GB)
mov ecx, 0
.map_pd:
    mov eax, 0x200000       ; 2MB page size
    mul ecx
    or eax, 0b10000011      ; Present + Writable + Huge
    mov [pd + ecx * 8], eax
    inc ecx
    cmp ecx, 1024
    jne .map_pd

Page Table Structure:

PML4 (Level 4) → 512 entries → 256TB each
  ↓
PDPT (Level 3) → 512 entries → 512GB each
  ↓
PD (Level 2)   → 512 entries → 1GB each (using 2MB pages)
  ↓
PT (Level 1)   → (not used, using 2MB huge pages)

3.4 Enable Long Mode

; Load PML4 into CR3
mov eax, pml4
mov cr3, eax

; Enable PAE (Physical Address Extension)
mov eax, cr4
or eax, 1 << 5
mov cr4, eax

; Set Long Mode bit in EFER MSR
mov ecx, 0xC0000080         ; EFER MSR
rdmsr
or eax, 1 << 8              ; LM bit
wrmsr

; Enable paging
mov eax, cr0
or eax, 1 << 31
mov cr0, eax

3.5 Load GDT and Jump to 64-bit

lgdt [gdt64.pointer]
jmp gdt64.code:long_mode_start

section .rodata
gdt64:
    dq 0                    ; Null descriptor
.code: equ $ - gdt64
    dq (1<<43) | (1<<44) | (1<<47) | (1<<53)  ; Code segment
.pointer:
    dw $ - gdt64 - 1
    dq gdt64

Stage 4: 64-bit Kernel Entry

File: src/arch/AMD64/boot/main64.asm

section .text
bits 64

long_mode_start:
    ; Clear segment registers
    mov ax, 0
    mov ss, ax
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    
    ; Call C kernel
    extern kernel_main
    call kernel_main
    
    ; If kernel returns, halt
    cli
.loop:
    hlt
    jmp .loop

Stage 5: Kernel Initialization

File: src/kernel/kernel.c - kernel_main()

5.1 Early Initialization

void kernel_main(void) {
    // 1. Initialize COM ports for debug output
    com_early_init(COM1_PORT);
    com_early_init(COM2_PORT);
    COM_LOG_INFO(COM1_PORT, "ModuOS Kernel Starting...");
    
    // 2. Initialize VGA text mode
    VGA_init();
    VGA_clear_screen();
    VGA_print("ModuOS v0.1\n");

5.2 Memory Management

    // 3. Parse Multiboot2 info
    extern uint64_t multiboot_info_ptr;
    memory_system_init((void*)multiboot_info_ptr);
    
    // 4. Initialize physical memory allocator
    phys_init(total_memory, usable_regions, region_count);
    
    // 5. Set up paging
    paging_init();
    
    // 6. Initialize kernel heap
    kheap_init();

5.3 Interrupt Setup

    // 7. Set up IDT
    idt_init();
    
    // 8. Configure PIC
    pic_init();
    
    // 9. Install fault handlers
    fault_init();
    
    // 10. Install IRQ handlers
    irq_init();
    
    // 11. Initialize PIT timer (100Hz)
    pit_init(100);
    
    // 12. Enable interrupts
    __asm__ volatile("sti");

5.4 Driver Initialization

    // 13. Initialize FPU/SSE
    fpu_init();
    
    // 14. Scan PCI bus
    pci_init();
    
    // 15. Initialize ACPI
    acpi_init();
    
    // 16. Initialize storage drivers
    ata_init();          // ATA/ATAPI
    ahci_init();         // AHCI/SATA
    vdrive_init();       // Virtual drive layer
    
    // 17. Initialize input drivers
    input_init();        // PS/2 keyboard/mouse
    ps2_init();

5.5 File System Initialization

    // 18. Initialize file system layer
    fs_init();
    fd_init();
    
    // 19. Detect and mount boot drive
    boot_drive_index = detect_boot_drive();
    
    // 20. Mount boot drive to Z:
    if (boot_drive_index >= 0) {
        fs_mount_drive(boot_drive_index, 0, FS_TYPE_FAT32);
    }

5.6 Process System Initialization

    // 21. Initialize process manager
    process_init();
    scheduler_init();
    
    // 22. Initialize system call interface
    syscall_init();

5.7 Start Shell

    // 23. Launch shell as init process
    COM_LOG_INFO(COM1_PORT, "Starting shell...");
    
    // Switch to userland shell
    zenith4_shell();  // Main shell loop
    
    // Should never return
    panic("Kernel main returned!");
}

Stage 6: Shell

The shell (zenith4_shell()) provides the user interface:

  1. Displays a shell prompt (e.g. # user@pc />).
  2. Reads keyboard input
  3. Parses commands
  4. Executes built-in or loads ELF programs
  5. Returns to prompt

Boot Timeline

Time Stage Activity
0ms BIOS Hardware initialization
+100ms GRUB Bootloader loads kernel
+200ms Bootstrap Protected mode → Long mode
+250ms Kernel Memory management setup
+300ms Kernel Interrupt system ready
+400ms Kernel Driver initialization
+500ms Kernel File system mounted
+600ms Shell User prompt displayed

Memory Layout After Boot

Physical Memory:
0x00000000 - 0x000FFFFF : Real mode/BIOS (1MB)
0x00100000 - 0x00??????  : Kernel code/data
0x???????? - 0x????????  : Kernel heap
0x???????? - 0x????????  : Page tables
0x???????? - 0xFFFFFFFF  : Available for allocation

Virtual Memory (Identity Mapped):
0x00000000 - 0x7FFFFFFF : First 2GB identity mapped
0xFFFFFFFF80000000+     : Higher-half kernel (optional)

Boot Drive Detection

ModuOS automatically detects the boot drive by looking for /ModuOS/System64/mdsys.sqr:

for each vDrive:
    for each partition:
        if exists("/ModuOS/System64/mdsys.sqr"):
            boot_drive = this drive
            boot drive becomes current mount slot (used for `/...` paths)
            also available via $/mnt/vDriveN/

Debugging Boot Issues

Enable Verbose Logging

Add to kernel_main():

COM_LOG_DEBUG(COM1_PORT, "Stage: XYZ");

Check com1.log for output.

Common Boot Failures

Hang after GRUB:

  • Check Multiboot2 header magic number
  • Verify kernel is loaded at correct address

Triple fault/reboot:

  • Page tables not set up correctly
  • Invalid IDT entry
  • Stack overflow

Black screen:

  • VGA not initialized
  • Check serial logs (com1.log)

QEMU Debug Flags

qemu-system-x86_64 -d int,cpu_reset -no-reboot

Next Steps

Clone this wiki locally