-
Notifications
You must be signed in to change notification settings - Fork 0
Boot Process
This document describes the complete boot sequence of ModuOS from power-on to shell prompt.
ModuOS uses the Multiboot2 boot protocol with GRUB2 as the bootloader. The boot process transitions through several CPU modes before reaching the kernel proper.
Power On → BIOS → GRUB2 → Multiboot2 →
Protected Mode (32-bit) → Long Mode (64-bit) →
Kernel Initialization → Shell
When the system powers on:
- BIOS/UEFI initializes hardware
- Reads Master Boot Record (MBR) or GPT
- Loads GRUB2 bootloader from boot sector
- Transfers control to GRUB
Configuration: targets/AMD64/iso/boot/grub/grub.cfg
menuentry "ModuOS" {
multiboot2 /ModuOS/System64/mdsys.sqr
boot
}
GRUB2:
- Displays boot menu
- Loads kernel (
mdsys.sqr) into memory - Parses Multiboot2 header
- Sets up initial environment
- Jumps to kernel entry point in Protected Mode (32-bit)
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
File: src/arch/AMD64/boot/main.asm
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; 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; 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_pdPage 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)
; 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, eaxlgdt [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 gdt64File: 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 .loopFile: src/kernel/kernel.c - kernel_main()
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"); // 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(); // 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"); // 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(); // 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);
} // 21. Initialize process manager
process_init();
scheduler_init();
// 22. Initialize system call interface
syscall_init(); // 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!");
}The shell (zenith4_shell()) provides the user interface:
- Displays a shell prompt (e.g.
# user@pc />). - Reads keyboard input
- Parses commands
- Executes built-in or loads ELF programs
- Returns to prompt
| 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 |
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)
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/Add to kernel_main():
COM_LOG_DEBUG(COM1_PORT, "Stage: XYZ");Check com1.log for output.
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-system-x86_64 -d int,cpu_reset -no-reboot- Memory Management - Paging details
- Interrupt Handling - IDT/IRQ setup
- Device Drivers - Driver initialization