8.7 KiB
MetalOS Roadmap
Vision
MetalOS is the absolute minimum operating system needed to boot QT6 Hello World on AMD64 + RX 6600 via UEFI.
Target: < 200 KB of OS code (excluding QT6)
Philosophy: If it doesn't directly enable QT6 Hello World, it doesn't exist.
Development Phases
Phase 1: Foundation ✓ (Current)
Goal: Establish project structure and documentation
- Create project directory structure
- Write architecture documentation
- Define build system
- Create bootloader skeleton
- Create kernel skeleton
- Create QT6 hello world application template
- Document development workflow
Deliverables:
- Project structure in place
- Documentation framework
- Skeleton code for bootloader and kernel
- Build system (Makefiles)
Phase 2: UEFI Bootloader (Next)
Goal: Load kernel and jump (< 10 KB code)
Tasks:
- Console output for debugging (UEFI OutputString)
- Get framebuffer info from GOP (Graphics Output Protocol)
- Load kernel blob from known location
- Get minimal memory map
- Exit boot services
- Jump to kernel
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
Success Criteria: Bootloader prints messages and jumps to kernel
Phase 3: Minimal Kernel
Goal: Initialize hardware (< 100 KB code)
Tasks:
-
Minimal paging setup
- Identity map or simple offset
- Just enough to keep CPU happy
- No fancy page fault handling
-
Interrupt handling
- IDT with ~5 handlers max
- Timer, keyboard, mouse, GPU (if needed)
- No complex IRQ routing
-
Memory allocator
- Bump allocator or simple free list
- No fancy algorithms
- Just malloc/free for QT6
-
NO scheduler - one process, always running
-
NO process management - app is statically linked with kernel or simple jump
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
Success Criteria: Kernel boots, prints messages, mallocs work
Phase 4: Hardware Support
Goal: GPU + Input (< 70 KB code)
Tasks:
-
PCI scan (minimal)
- Hardcode scan for vendor 0x1002 (AMD)
- Find RX 6600 device ID
- Enable memory access
- That's it!
-
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
-
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
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: Display working, keyboard/mouse input working
Phase 5: Minimal Syscalls
Goal: User-kernel boundary (< 10 KB code)
Tasks:
- Syscall mechanism (syscall/sysret or just direct calls)
- Maybe 5-10 syscalls total:
- write() - debugging
- mmap() / munmap() - memory
- ioctl() - device control
- poll() - wait for input events
- exit() - halt system
Simplifications:
- No syscall table if app can directly call kernel functions
- No parameter validation (trust everything)
- No error handling (just panic)
Success Criteria: App can call kernel functions
Phase 6: User Space & Application
Goal: Load and run app
Tasks:
-
Simple app loading
- Static-linked binary
- No ELF parsing if we can avoid it
- Just jump to known entry point
-
C++ minimal runtime
- Global constructors
- Basic new/delete (use kernel malloc)
- No exceptions (disable them)
-
Direct boot to app
- No init, no shell
- Kernel calls app's main() directly
- App exits → kernel halts
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
Goal: Port QT6 to MetalOS
Tasks:
-
QT6 dependencies
- Port minimal C++ standard library
- Port required libraries (zlib, png, freetype, etc.)
- Only what QT6 absolutely needs
-
QT Platform Abstraction (QPA) Plugin
- MetalOS platform plugin
- Framebuffer graphics backend
- Input event integration
- Event loop integration with kernel
-
Build QT6 for MetalOS
- Configure QT6 build system
- Cross-compile QT6
- Strip unnecessary modules
- QtCore, QtGui, QtWidgets only
-
Test infrastructure
- Simple QT apps for testing
- Verify widgets render
- Verify input works
Success Criteria: Simple QT6 applications can run
Phase 8: Integration & Polish
Goal: Get Hello World running perfectly
Tasks:
-
Build hello world application
- Compile against MetalOS QT6
- Static link everything
- Create bootable image
-
Full-screen rendering
- Ensure application fills screen
- Proper resolution handling
- Clean graphics output
-
Input handling
- Keyboard input works
- Mouse input works (if used by app)
- Clean event handling
-
Performance tuning
- Optimize critical paths
- Reduce boot time
- Smooth rendering
-
Testing
- Test on QEMU
- Test on real hardware (AMD64 + RX 6600)
- Fix any hardware-specific issues
Success Criteria: QT6 Hello World runs full-screen on target hardware
Timeline Estimates
These are rough estimates for a single developer
- Phase 1: 1 week ✓ (Complete)
- Phase 2: 2-3 weeks
- Phase 3: 3-4 weeks
- Phase 4: 4-6 weeks
- Phase 5: 1-2 weeks
- Phase 6: 2-3 weeks
- Phase 7: 6-8 weeks
- Phase 8: 2-3 weeks
Total: ~4-6 months of focused development
Technical Challenges
Major Challenges
-
GPU Initialization: Radeon RX 6600 is a modern GPU with complex initialization. May need to study Linux amdgpu driver extensively.
-
QT6 Dependencies: QT6 has many dependencies. Need to port or stub out non-essential ones.
-
QPA Plugin: Creating a QT Platform Abstraction plugin from scratch is non-trivial.
-
Memory Management: Need working virtual memory before user space.
-
USB Stack: If using USB input, need minimal USB stack (XHCI for modern systems).
Risk Mitigation
- Start with serial/VGA console before GPU
- Use PS/2 input before USB if easier
- Test incrementally in QEMU before hardware
- Study existing minimal OS implementations
- Reference Linux kernel code (but don't copy)
Success Metrics
Minimal Success
- Boots on target hardware
- Displays something via GPU
- Can be interacted with via keyboard
- QT6 hello world shows text
Full Success
- Boots reliably on AMD64 + RX 6600
- Full screen 1920x1080 rendering
- Clean QT6 widget rendering
- Responsive input handling
- Boot time < 10 seconds
Resources Needed
Hardware
- AMD64 system with Radeon RX 6600 GPU
- USB keyboard and mouse
- Serial port (optional, for debugging)
Software
- Cross-compiler toolchain (x86_64-elf-gcc)
- QEMU with UEFI support
- GDB for debugging
- QT6 source code
Knowledge
- UEFI specification
- x86_64 architecture
- PCI/PCIe protocol
- AMD GPU documentation
- QT6 architecture
- OS development fundamentals
Design Decisions
-
File System: ❌ Not needed
- Application embedded in boot image or loaded by bootloader
- Everything in RAM
-
Command Line / Shell: ❌ Not needed
- Boot directly into QT6 application
- No init process, no shell
-
Networking: ❌ Not needed
- Hello world doesn't need network
-
Dynamic Linking: ❌ Not needed
- Static link everything for simplicity
-
SMP: ❌ Not needed
- Single core is fine for hello world
-
ACPI: ⚠️ Minimal
- Just enough to work with GPU
-
Multiple Applications: ❌ Not needed
- One application only - the QT6 hello world
Contributing
This is a learning/demonstration project. Contributions welcome, but:
- Keep it minimal
- Every feature must justify its existence
- Ask "Does this help run QT6 hello world?" before adding anything
- Prefer simple over clever
- Document everything