# 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` ```nasm 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 ```nasm 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 ```nasm ; 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 ```nasm ; 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 ```nasm ; 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 ```nasm 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` ```nasm 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 ```c 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 ```c // 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 ```c // 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 ```c // 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 ```c // 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 ```c // 21. Initialize process manager process_init(); scheduler_init(); // 22. Initialize system call interface syscall_init(); ``` ### 5.7 Start Shell ```c // 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`: ```c 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(): ```c 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 ```bash qemu-system-x86_64 -d int,cpu_reset -no-reboot ``` ## Next Steps - [Memory Management](Memory-Management.md) - Paging details - [Interrupt Handling](Interrupt-Handling.md) - IDT/IRQ setup - [Device Drivers](Device-Drivers.md) - Driver initialization