diff --git a/README.md b/README.md index ec11a5f..3dd28e1 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,25 @@ # MetalOS -A minimal operating system built from the ground up to run QT6 applications on AMD64 hardware with Radeon RX 6600 GPU and UEFI boot. +**The most minimal OS possible that runs QT6 Hello World.** -**Not Linux. Not BSD. Not Windows.** Just enough OS to run a QT6 Hello World full-screen application. +Not Linux. Not BSD. Not Windows. Just enough code to boot, initialize GPU, and run one app. + +## Extreme Minimalism + +MetalOS is an exercise in **absolute minimalism**: + +- ❌ **No scheduler** - one app = always running +- ❌ **No process management** - one process only +- ❌ **No file system** - app embedded in boot image +- ❌ **No networking** - not needed +- ❌ **No shell/command line** - boot directly to app +- ❌ **No security** - trust everything +- ❌ **No multi-core** - one CPU core +- ❌ **No dynamic linking** - static link everything + +**If it doesn't help QT6 Hello World run, it doesn't exist.** + +Target: **< 200 KB OS code** (excluding QT6 itself) ## Project Status @@ -12,7 +29,23 @@ Currently: Project structure, documentation, and skeleton code in place. ## What is MetalOS? -MetalOS is a **minimal, purpose-built operating system** with a single goal: demonstrate that you can build a custom OS from scratch to run modern GUI applications (specifically QT6). +MetalOS is **the smallest possible operating system** that can boot QT6 Hello World on specific hardware. + +### Philosophy + +Every feature must answer: **"Does this help run QT6 Hello World?"** + +If no → it doesn't exist. + +### Aggressive Minimalism + +- **Bootloader**: < 10 KB (just load kernel and jump) +- **Kernel**: < 100 KB (memory, interrupts, drivers) +- **GPU Driver**: < 50 KB (minimal display init) +- **Input Drivers**: < 20 KB (keyboard + mouse only) +- **Total OS**: ~200 KB + +Compare to Linux kernel: ~30 MB. We're **150x smaller** by doing only one thing. ### Key Features @@ -82,10 +115,13 @@ See [docs/BUILD.md](docs/BUILD.md) for instructions on creating a bootable USB d ## Documentation -- **[ARCHITECTURE.md](docs/ARCHITECTURE.md)** - System design and architecture -- **[BUILD.md](docs/BUILD.md)** - Build instructions and dependencies -- **[DEVELOPMENT.md](docs/DEVELOPMENT.md)** - Development workflow and guidelines -- **[ROADMAP.md](docs/ROADMAP.md)** - Development phases and timeline +- **[MINIMALISM.md](docs/MINIMALISM.md)** - ⭐ **START HERE** - Philosophy and what we cut +- **[ARCHITECTURE.md](docs/ARCHITECTURE.md)** - System design (minimal version) +- **[ROADMAP.md](docs/ROADMAP.md)** - Development phases +- **[BUILD.md](docs/BUILD.md)** - Build instructions +- **[DEVELOPMENT.md](docs/DEVELOPMENT.md)** - Development workflow +- **[COMPONENTS.md](docs/COMPONENTS.md)** - Component checklist +- **[STATUS.md](docs/STATUS.md)** - Current implementation status ## Project Structure @@ -116,13 +152,13 @@ See [docs/ROADMAP.md](docs/ROADMAP.md) for detailed breakdown. ## Why? -**Learning**: Building an OS from scratch is the ultimate systems programming education. +**Minimalism**: How small can an OS be and still run GUI apps? -**Minimal Design**: Modern OSes are complex. This project asks: "What's the absolute minimum needed for a GUI application?" +**Learning**: Building an OS from scratch is the ultimate systems programming challenge. -**Custom Hardware**: Show that you can optimize an OS for specific hardware instead of supporting everything. +**Proof of Concept**: Modern frameworks like QT6 can run on tiny custom OSes. -**QT6 Demo**: Prove that modern application frameworks can run on custom OS implementations. +**Fun**: Because we can. ## Technology Stack @@ -142,15 +178,22 @@ See [docs/ROADMAP.md](docs/ROADMAP.md) for detailed breakdown. ## Contributing -This is primarily a learning/demonstration project, but contributions are welcome! +**Golden Rule**: If it doesn't help QT6 Hello World, don't add it. -**Guidelines**: -- Keep it minimal - every feature must justify its existence -- Document your changes -- Follow existing code style -- Test on QEMU before submitting +Contributions welcome for: +- Simplifying existing code (make it smaller!) +- Bug fixes +- GPU driver work (hardest part) +- QT6 port work +- Documentation -See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for details. +Not welcome: +- Adding features "for completeness" +- POSIX compatibility +- Supporting other hardware +- Generalizing anything + +See [CONTRIBUTING.md](CONTRIBUTING.md) and [docs/MINIMALISM.md](docs/MINIMALISM.md). ## License diff --git a/bootloader/src/main.c b/bootloader/src/main.c index 2d38a05..21d72a1 100644 --- a/bootloader/src/main.c +++ b/bootloader/src/main.c @@ -1,12 +1,13 @@ /* * MetalOS UEFI Bootloader * - * This is a minimal UEFI bootloader that: - * 1. Initializes graphics output - * 2. Loads the kernel from disk - * 3. Retrieves memory map and system information - * 4. Exits boot services - * 5. Transfers control to kernel + * MINIMAL bootloader: + * 1. Get framebuffer from UEFI + * 2. Load kernel blob from disk + * 3. Exit boot services + * 4. Jump to kernel + * + * That's it. No fancy stuff. */ #include "bootloader.h" @@ -116,46 +117,35 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable) { gST = SystemTable; // Print banner - print_string(u"MetalOS Bootloader v0.1.0\r\n"); - print_string(u"=========================\r\n\r\n"); + print_string(u"MetalOS v0.1 - MINIMAL BOOTLOADER\r\n"); + print_string(u"==================================\r\n\r\n"); - // Initialize graphics - print_string(u"Initializing graphics...\r\n"); + // Get framebuffer (don't care about resolution, take what UEFI gives us) + print_string(u"Getting framebuffer...\r\n"); status = initialize_graphics(ImageHandle); - print_status(u"Graphics initialization", status); if (status != EFI_SUCCESS) { - print_string(u"WARNING: Graphics initialization failed, continuing...\r\n"); + print_string(u"WARNING: No graphics, continuing anyway...\r\n"); } - // Load kernel + // Load kernel (just read metalos.bin, don't overthink it) print_string(u"Loading kernel...\r\n"); status = load_kernel(ImageHandle); - print_status(u"Kernel load", status); if (status != EFI_SUCCESS) { - print_string(u"ERROR: Failed to load kernel\r\n"); + print_string(u"ERROR: Can't load kernel\r\n"); return status; } - // Get ACPI information - print_string(u"Retrieving ACPI tables...\r\n"); - boot_info.rsdp = get_rsdp(); + // Get memory map (minimal info) + print_string(u"Getting memory map...\r\n"); + // TODO: GetMemoryMap - // Get memory map - print_string(u"Retrieving memory map...\r\n"); - // TODO: Call GetMemoryMap - - // Exit boot services - print_string(u"Exiting boot services...\r\n"); - // TODO: Call ExitBootServices + // Exit boot services (point of no return) + print_string(u"Exiting UEFI boot services...\r\n"); + // TODO: ExitBootServices // Jump to kernel - print_string(u"Starting kernel...\r\n"); + // TODO: ((void(*)(BootInfo*))KERNEL_LOAD_ADDRESS)(&boot_info); - // TODO: Call kernel entry point with boot_info - // typedef void (*KernelEntry)(BootInfo*); - // KernelEntry kernel = (KernelEntry)KERNEL_LOAD_ADDRESS; - // kernel(&boot_info); - - // If we get here, something went wrong + // Should never get here return EFI_SUCCESS; } diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 68e251e..0f6fe9b 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -6,10 +6,10 @@ MetalOS is a ground-up operating system designed specifically to run QT6 applica ## Design Principles -1. **Minimal by Design**: Only implement what's necessary to run QT6 applications +1. **Absolute Minimum**: If it's not needed for QT6 Hello World, it doesn't exist 2. **UEFI Native**: Boot directly via UEFI, no legacy BIOS support -3. **Hardware Specific**: Optimized for AMD64 + Radeon RX 6600 -4. **Modern Approach**: Learn from Linux but implement cleanly from scratch +3. **Hardware Specific**: AMD64 + Radeon RX 6600 only - no abstractions for other hardware +4. **Single Purpose**: One app, one GPU, one goal - nothing else matters ## System Architecture @@ -54,13 +54,13 @@ MetalOS is a ground-up operating system designed specifically to run QT6 applica - Transfer control to kernel ### 2. Kernel Core -- **Purpose**: Provide essential OS services -- **Language**: C/C++ with assembly for low-level operations +- **Purpose**: Absolute bare minimum OS services +- **Language**: C with assembly for critical parts - **Subsystems**: - - Memory Management (physical/virtual) - - Process/Thread Scheduler - - Interrupt Handling - - System Call Interface + - Memory Management (just enough for app + QT6) + - Single process support (no scheduler needed!) + - Interrupt handling (only what GPU/input needs) + - Direct syscall to kernel functions (no table/dispatch overhead) ### 3. Hardware Abstraction Layer (HAL) - **Purpose**: Abstract hardware specifics @@ -78,28 +78,29 @@ MetalOS is a ground-up operating system designed specifically to run QT6 applica - QT6 framework (statically linked into application) - No shell, no command line - direct boot to app -## Memory Layout +## Memory Layout (Simplified) ``` 0x0000000000000000 - 0x0000000000000FFF : NULL guard page -0x0000000000001000 - 0x00000000000FFFFF : Bootloader code/data -0x0000000000100000 - 0x00000000FFFFFFFF : Kernel space -0x0000000100000000 - 0x00007FFFFFFFFFFF : User space -0xFFFF800000000000 - 0xFFFFFFFFFFFFFFFF : Kernel heap/stacks +0x0000000000001000 - 0x00000000000FFFFF : Bootloader (temporary) +0x0000000000100000 - 0x0000000000FFFFFF : Kernel (small!) +0x0000000001000000 - 0x00000000FFFFFFFF : Application + QT6 +GPU VRAM: Separate, mapped via BAR ``` -## Boot Process +No complex memory regions - keep it simple! -1. **UEFI Firmware** loads bootloader from EFI System Partition -2. **Bootloader** initializes basic hardware and sets up memory -3. **Bootloader** locates and loads kernel binary -4. **Bootloader** exits UEFI boot services -5. **Kernel** initializes subsystems (memory, scheduler, interrupts) -6. **Kernel** loads HAL drivers (GPU, PCI, input) -7. **Kernel** directly launches QT6 Hello World application (no shell, no init) -8. **Application** runs full-screen until exit/reboot +## Boot Process (Minimal) -**Note**: No command line, no shell - the system boots directly into the single application. +1. **UEFI Firmware** loads bootloader +2. **Bootloader** gets framebuffer, loads kernel, jumps +3. **Kernel** maps memory, enables interrupts +4. **Kernel** initializes GPU (minimal) +5. **Kernel** sets up input (keyboard/mouse only) +6. **Kernel** jumps directly to QT6 app +7. **App** runs until halt + +**That's it. No filesystem, no daemons, no services, no nothing.** ## Development Phases diff --git a/docs/MINIMALISM.md b/docs/MINIMALISM.md new file mode 100644 index 0000000..fdab60e --- /dev/null +++ b/docs/MINIMALISM.md @@ -0,0 +1,225 @@ +# MetalOS - Extreme Minimalism Guide + +## What ABSOLUTE MINIMUM Means + +We're not building a general-purpose OS. We're building **the smallest possible software layer** that lets QT6 Hello World run on AMD64 + RX 6600. + +## Cut Everything + +### ❌ NO Scheduler +- **Why not?**: One app = one process = always running +- **Instead**: Direct execution, no context switching +- **Saves**: Scheduler code, process queues, timer interrupts for scheduling + +### ❌ NO Process Management +- **Why not?**: Only one process ever exists +- **Instead**: App runs in ring 0 (kernel mode) or simple ring 3 with static setup +- **Saves**: Process structures, fork/exec, process lifecycle + +### ❌ NO File System +- **Why not?**: Everything loaded at boot +- **Instead**: App binary embedded in boot image or loaded by bootloader once +- **Saves**: VFS, inode structures, file descriptors, read/write/open/close + +### ❌ NO Networking +- **Why not?**: Hello World doesn't need network +- **Instead**: Nothing +- **Saves**: TCP/IP stack, network drivers, sockets + +### ❌ NO Security +- **Why not?**: Single app, demo system +- **Instead**: Trust everything +- **Saves**: Permissions, user/group IDs, capabilities, security modules + +### ❌ NO Virtual Memory (maybe) +- **Why not?**: Could run everything with identity mapping +- **Instead**: Simple page tables just to keep CPU happy +- **Saves**: TLB management, page fault handling, swapping + +### ❌ NO Dynamic Linking +- **Why not?**: Complexity nightmare +- **Instead**: Static link everything into one blob +- **Saves**: ELF loader complexity, PLT/GOT, symbol resolution at runtime + +### ❌ NO Multi-core +- **Why not?**: One app on one core is plenty +- **Instead**: Use only bootstrap processor (BSP) +- **Saves**: SMP initialization, locks, atomic operations, IPI handling + +### ❌ NO ACPI (mostly) +- **Why not?**: Complex and usually not needed for basic operation +- **Instead**: Minimal ACPI just for GPU if absolutely required +- **Saves**: AML interpreter, ACPI tables parsing, power management + +### ❌ NO Signals/IPC +- **Why not?**: One process = nobody to talk to +- **Instead**: Nothing +- **Saves**: Signal handling, pipes, message queues, shared memory + +### ❌ NO Timers (mostly) +- **Why not?**: QT6 needs *some* time, but minimal +- **Instead**: Simple timer for QT event loop only +- **Saves**: Complex timer infrastructure, high-resolution timers + +## What We MUST Keep (Absolute Minimum) + +### ✅ Memory Allocator +- **Why**: QT6 needs malloc/free +- **Minimum**: Simple bump allocator or basic free list +- **No need for**: Fancy algorithms, defragmentation, memory pools + +### ✅ Interrupts +- **Why**: Keyboard/mouse input, timer for QT +- **Minimum**: + - Keyboard interrupt + - Mouse interrupt + - Timer interrupt (for QT event loop) + - GPU interrupt (if needed) +- **That's it!** Maybe 4-5 interrupt handlers total + +### ✅ GPU Driver +- **Why**: Need to display graphics +- **Minimum**: + - Initialize display pipeline + - Set up framebuffer + - Blit pixels to screen +- **No need for**: 3D acceleration, multiple displays, hot-plug + +### ✅ Input Drivers +- **Why**: Need keyboard/mouse for QT events +- **Minimum**: + - USB XHCI (or PS/2 if simpler!) + - HID keyboard + - HID mouse +- **No need for**: Other USB devices, complex HID parsing + +### ✅ PCI Enumeration +- **Why**: Find the GPU +- **Minimum**: + - Scan bus for our specific GPU + - Enable memory/IO access +- **No need for**: Full PCI tree, hot-plug, PCI-to-PCI bridges + +### ✅ System Calls (bare minimum) +- **Why**: User space needs to talk to kernel +- **Minimum**: + - `write()` - for debugging output + - `mmap()` - for memory + - `ioctl()` - for GPU/input + - Maybe 5-10 syscalls total +- **No need for**: POSIX compatibility, 300+ syscalls + +## Radical Simplifications + +### Framebuffer Over Everything +- **Skip**: Complex GPU 3D acceleration +- **Use**: Direct framebuffer blitting +- **QT6**: Can render to memory, we copy to VRAM +- **Trade-off**: Slower but WAY simpler + +### Identity Mapping (maybe) +- **Skip**: Complex virtual memory +- **Use**: Physical = Virtual (or simple offset) +- **Note**: x86-64 requires paging enabled, but can be trivial + +### PS/2 Over USB +- **Skip**: Complex USB stack if possible +- **Use**: PS/2 keyboard/mouse if hardware supports +- **Simpler**: Direct port I/O vs USB protocol + +### Polling Over Interrupts (where possible) +- **Skip**: Complex interrupt handling +- **Use**: Poll for events in tight loop +- **Trade-off**: CPU usage vs complexity + +### Hardcode Everything +- **Skip**: Configuration files, boot parameters +- **Use**: Compiled-in constants +- **Examples**: + - Screen resolution: 1920x1080 (hardcoded) + - GPU PCI ID: hardcoded + - Memory layout: hardcoded + +## Code Size Targets + +Aim for **minimal code size**: + +- **Bootloader**: < 10 KB +- **Kernel**: < 100 KB +- **GPU Driver**: < 50 KB (hardest part) +- **Input Drivers**: < 20 KB +- **QT6 + App**: ~10-20 MB (unavoidable - QT is big) + +**Total OS (without QT)**: ~200 KB or less! + +## Performance Targets + +We don't care about performance, we care about **working**: + +- Boot time: Don't care (< 30 seconds is fine) +- Frame rate: Don't care (30 FPS is plenty) +- Memory usage: Don't care (512 MB is plenty) +- CPU usage: Don't care (can peg one core) + +**Trade complexity for simplicity every time.** + +## Implementation Strategy + +### Phase 1 ✅ (Done) +- Project structure +- Documentation + +### Phase 2 (Bootloader) +- UEFI console output (for debugging) +- Load kernel blob +- Jump to kernel +- **Skip**: Complex file systems, just load from known location + +### Phase 3 (Kernel) +- Set up page tables (minimal) +- Set up interrupts (only what we need) +- Memory allocator (simple bump allocator) +- **Skip**: Complex memory management + +### Phase 4 (GPU) +- PCI scan for RX 6600 +- Enable BAR +- Initialize display (hardcode 1920x1080) +- Framebuffer blit +- **Skip**: Everything else GPU can do + +### Phase 5 (Input) +- Try PS/2 first (simpler!) +- If not available, minimal USB XHCI +- Keyboard scancodes -> QT key events +- Mouse packets -> QT mouse events +- **Skip**: Complex HID parsing, other devices + +### Phase 6 (QT6) +- Port minimal QT6 (Core + Gui + Widgets only) +- QPA plugin: just framebuffer blit + input events +- Static link everything +- **Skip**: All optional QT modules + +### Phase 7 (Integration) +- Link app with QT6 +- Embed in boot image +- Test and debug +- **Skip**: Anything that doesn't work - iterate + +## When in Doubt + +Ask these questions: + +1. **Does Hello World need this?** No → Cut it +2. **Can we hardcode this?** Yes → Hardcode it +3. **Can we do this simpler?** Yes → Do it simpler +4. **Does Linux do it complex?** Yes → Do it simpler anyway + +## Bottom Line + +**Build the smallest possible OS that boots QT6 Hello World.** + +If it doesn't directly contribute to that goal, it doesn't exist. + +No compromises. Maximum minimalism. diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 25ba407..7168da1 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -2,9 +2,11 @@ ## Vision -MetalOS is a **minimal operating system** built from the ground up with a single purpose: run a QT6 Hello World application full-screen on AMD64 hardware with a Radeon RX 6600 GPU, booting via UEFI. +MetalOS is **the absolute minimum operating system** needed to boot QT6 Hello World on AMD64 + RX 6600 via UEFI. -This is not a general-purpose OS. Every component is purpose-built to achieve this specific goal with minimal complexity. +**Target**: < 200 KB of OS code (excluding QT6) + +**Philosophy**: If it doesn't directly enable QT6 Hello World, it doesn't exist. ## Development Phases @@ -28,145 +30,136 @@ This is not a general-purpose OS. Every component is purpose-built to achieve th ### Phase 2: UEFI Bootloader (Next) -**Goal**: Boot from UEFI and load kernel +**Goal**: Load kernel and jump (< 10 KB code) **Tasks**: -1. Implement UEFI protocol interfaces - - Console I/O for early debugging - - Graphics Output Protocol - - Simple File System Protocol - - Memory allocation +1. Console output for debugging (UEFI OutputString) +2. Get framebuffer info from GOP (Graphics Output Protocol) +3. Load kernel blob from known location +4. Get minimal memory map +5. Exit boot services +6. Jump to kernel -2. Graphics initialization - - Query available video modes - - Set optimal resolution (1920x1080 or best available) - - Set up framebuffer +**Simplifications**: +- Don't enumerate all video modes, take default +- Don't parse filesystem, load from fixed location +- Skip ACPI (try without it first) +- No error recovery, just halt on failure -3. Kernel loading - - Read metalos.bin from disk - - Load into memory at 1MB mark - - Verify kernel integrity - -4. System information gathering - - Get memory map - - Find ACPI tables (RSDP) - - Detect CPU features - -5. Exit boot services and jump to kernel - - Call ExitBootServices() - - Pass BootInfo structure to kernel - - Jump to kernel_main() - -**Success Criteria**: Bootloader loads kernel and jumps to kernel code +**Success Criteria**: Bootloader prints messages and jumps to kernel ### Phase 3: Minimal Kernel -**Goal**: Initialize hardware and provide basic services +**Goal**: Initialize hardware (< 100 KB code) **Tasks**: -1. Early kernel initialization - - Set up GDT (Global Descriptor Table) - - Set up IDT (Interrupt Descriptor Table) - - Enable interrupts - - Initialize framebuffer console +1. Minimal paging setup + - Identity map or simple offset + - Just enough to keep CPU happy + - No fancy page fault handling -2. Memory management - - Physical memory allocator (buddy system or bitmap) - - Virtual memory setup (page tables) - - Kernel heap allocator - - *Minimal implementation - just enough for QT6* +2. Interrupt handling + - IDT with ~5 handlers max + - Timer, keyboard, mouse, GPU (if needed) + - No complex IRQ routing -3. Process/Thread support - - Simple round-robin scheduler - - Context switching (bare minimum) - - Single user process support - - *No multi-user, no fancy scheduling* +3. Memory allocator + - Bump allocator or simple free list + - No fancy algorithms + - Just malloc/free for QT6 -4. Basic I/O - - Serial port for debugging - - Framebuffer console - - *No disk I/O needed initially* +4. NO scheduler - one process, always running +5. NO process management - app is statically linked with kernel or simple jump -**Success Criteria**: Kernel boots, prints messages, can allocate memory +**Simplifications**: +- Skip GDT setup if not needed (UEFI might have set it up) +- Identity mapping instead of complex virtual memory +- Bump allocator instead of buddy/slab +- No TLB shootdown, no page fault handling -### Phase 4: Hardware Abstraction Layer +**Success Criteria**: Kernel boots, prints messages, mallocs work -**Goal**: Support minimal hardware needed for QT6 +### Phase 4: Hardware Support + +**Goal**: GPU + Input (< 70 KB code) **Tasks**: -1. PCI Bus enumeration - - Scan PCI devices - - Find Radeon RX 6600 GPU - - Basic configuration +1. PCI scan (minimal) + - Hardcode scan for vendor 0x1002 (AMD) + - Find RX 6600 device ID + - Enable memory access + - That's it! -2. GPU Driver (Radeon RX 6600) - - Initialize GPU - - Set up display pipeline - - Configure framebuffer - - *Minimal - no 3D acceleration initially* - - *Can use reference from Linux amdgpu driver* +2. GPU Driver (hardest part, < 50 KB) + - Map MMIO registers + - Initialize display controller (DCN) + - Hardcode 1920x1080 mode + - Set up framebuffer in VRAM + - Enable display output + - *Study Linux amdgpu driver, but keep it simple* -3. Input devices - - USB HID keyboard support - - USB HID mouse support - - PS/2 fallback (if needed) - - *Just enough for QT event handling* +3. Input devices (< 20 KB) + - **Try PS/2 first** (much simpler than USB!) + - If no PS/2: minimal USB XHCI for HID + - Keyboard: scancode → QT key events + - Mouse: packets → QT mouse events -4. Timer - - APIC timer or PIT - - For scheduling and timeouts +**Simplifications**: +- No PCI tree traversal, just scan for our GPU +- No GPU 3D, just 2D framebuffer +- No hot-plug, no multiple displays +- PS/2 over USB if possible (way simpler) +- No timer sophistication, PIT is fine -**Success Criteria**: Can detect and initialize GPU, receive keyboard/mouse input +**Success Criteria**: Display working, keyboard/mouse input working -### Phase 5: System Call Interface +### Phase 5: Minimal Syscalls -**Goal**: Provide user-kernel boundary +**Goal**: User-kernel boundary (< 10 KB code) **Tasks**: -1. System call mechanism - - syscall/sysret instructions - - System call table - - Parameter passing +1. Syscall mechanism (syscall/sysret or just direct calls) +2. Maybe 5-10 syscalls total: + - write() - debugging + - mmap() / munmap() - memory + - ioctl() - device control + - poll() - wait for input events + - exit() - halt system -2. Essential system calls - - exit() - terminate process - - write() - output to console/log - - mmap() - memory allocation - - open/read/close() - minimal file operations (if needed) - - ioctl() - device control (for GPU) - - poll/select() - event handling (for input) +**Simplifications**: +- No syscall table if app can directly call kernel functions +- No parameter validation (trust everything) +- No error handling (just panic) -3. User-kernel transitions - - Ring 3 to Ring 0 transitions - - Parameter validation - - Error handling +**Success Criteria**: App can call kernel functions -**Success Criteria**: User space can make system calls +### Phase 6: User Space & Application -### Phase 6: User Space Runtime - -**Goal**: Support C++ applications +**Goal**: Load and run app **Tasks**: -1. ELF loader - - Parse ELF headers - - Load program segments - - Set up entry point - - *Static linking initially - no dynamic loader* +1. Simple app loading + - Static-linked binary + - No ELF parsing if we can avoid it + - Just jump to known entry point -2. Minimal C/C++ runtime - - _start() function - - C++ global constructors/destructors - - Memory allocation (malloc/free) - - Basic string functions - - *Only what QT6 needs* +2. C++ minimal runtime + - Global constructors + - Basic new/delete (use kernel malloc) + - No exceptions (disable them) -3. Application launcher (no init/shell needed) - - Directly load QT6 hello world application - - No command line, no shell - - Single application until reboot +3. Direct boot to app + - No init, no shell + - Kernel calls app's main() directly + - App exits → kernel halts -**Success Criteria**: Can load and run the QT6 hello world application directly +**Simplifications**: +- Static link everything into one blob +- Skip ELF loader completely if possible +- No exceptions (compile with -fno-exceptions) +- App runs in ring 0 or simple ring 3 + +**Success Criteria**: Can run simple C++ program ### Phase 7: QT6 Port diff --git a/kernel/src/main.c b/kernel/src/main.c index 4d8b457..b981669 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -1,8 +1,9 @@ /* * MetalOS Kernel - Main Entry Point * - * Minimal kernel implementation for running QT6 applications. - * Only implements what's absolutely necessary. + * EXTREME MINIMAL kernel - only what's needed for QT6 Hello World. + * No scheduler, no process management, no filesystem, no nothing. + * Just: boot -> init GPU -> init input -> run app. */ #include "kernel/kernel.h" @@ -11,6 +12,9 @@ /* * Kernel main entry point * Called by bootloader with boot information + * + * This is it. The entire OS. No scheduler, no processes, no filesystem. + * Just set up hardware and jump to the QT6 app. */ void kernel_main(BootInfo* boot_info) { // Initialize basic console output using framebuffer @@ -22,41 +26,55 @@ void kernel_main(BootInfo* boot_info) { ); console_clear(); - console_print("MetalOS Kernel v0.1.0\n"); - console_print("=====================\n\n"); + console_print("MetalOS v0.1 - MINIMAL\n"); + console_print("======================\n\n"); - console_print("Initializing minimal kernel...\n"); + // TODO: Set up minimal page tables (identity mapped or simple offset) + console_print("[ ] Memory (identity map)\n"); - // TODO: Initialize memory management - console_print("[ ] Memory management\n"); + // TODO: Set up IDT with only interrupts we need: + // - Keyboard/mouse (USB or PS/2) + // - Timer (for QT event loop) + // - GPU (if needed) + // That's it! Maybe 5 interrupt handlers total. + console_print("[ ] Interrupts (minimal)\n"); - // TODO: Initialize interrupt handling - console_print("[ ] Interrupt handling\n"); + // TODO: Simple memory allocator (bump allocator is fine) + console_print("[ ] Heap (bump allocator)\n"); - // TODO: Initialize PCI bus - console_print("[ ] PCI enumeration\n"); + // TODO: Find RX 6600 GPU via PCI (hardcode vendor/device ID) + console_print("[ ] PCI (find GPU only)\n"); - // TODO: Initialize GPU driver - console_print("[ ] GPU driver (Radeon RX 6600)\n"); + // TODO: Initialize GPU - minimal + // - Enable BAR + // - Init display pipeline + // - Set up framebuffer at 1920x1080 (hardcoded) + console_print("[ ] GPU (RX 6600, 1920x1080)\n"); - // TODO: Initialize input devices - console_print("[ ] Input devices\n"); + // TODO: Initialize input + // Try PS/2 first (simpler!) + // Fall back to minimal USB XHCI if needed + console_print("[ ] Input (PS/2 or USB)\n"); - // TODO: Setup system calls - console_print("[ ] System call interface\n"); + // TODO: Jump directly to QT6 Hello World app + // No shell, no init, no fork/exec + // Just: jump to application entry point + console_print("[ ] Jump to QT6 app\n"); - // TODO: Load and run QT6 hello world application directly (no shell/init) - console_print("[ ] Loading QT6 Hello World application...\n"); + console_print("\nBooting app...\n"); - console_print("\nKernel initialization complete.\n"); - console_print("Booting directly into application (no shell)...\n"); + // TODO: Replace this with jump to QT6 app + // For now, halt + console_print("ERROR: App not linked yet\n"); - // TODO: Jump to QT6 hello world application entry point - // The application will run full-screen until exit - // No shell, no command line - just the one app - - // Halt - in real implementation, we'd start the application while(1) { __asm__ volatile("hlt"); } } + +/* + * That's the entire kernel. No scheduler. No processes. No filesystem. + * Just boot, initialize hardware, run app. + * + * Total kernel size target: < 100 KB + */