diff --git a/.github/workflows/qemu-test.yml b/.github/workflows/qemu-test.yml index 7b60813..63ebffa 100644 --- a/.github/workflows/qemu-test.yml +++ b/.github/workflows/qemu-test.yml @@ -20,6 +20,8 @@ jobs: - name: Install dependencies run: | + set -e # Exit on any error + sudo apt-get update sudo apt-get install -y \ build-essential \ @@ -33,12 +35,12 @@ jobs: - name: Build bootloader run: | cd bootloader - make || echo "Bootloader build incomplete (expected in early development)" + make - name: Build kernel run: | cd kernel - make || echo "Kernel build incomplete (expected in early development)" + make - name: Create bootable image run: | @@ -46,14 +48,19 @@ jobs: - name: Start QEMU and capture screenshot run: | + set -e # Exit on any error + # Start Xvfb for headless screenshot capture export DISPLAY=:99 Xvfb :99 -screen 0 1920x1080x24 & XVFB_PID=$! sleep 2 - # Create a simple disk image with the ISO content - dd if=/dev/zero of=build/metalos.img bs=1M count=64 + # Verify disk image exists (created by 'make image') + if [ ! -f build/metalos.img ]; then + echo "Error: build/metalos.img not found!" + exit 1 + fi # Start QEMU in the background with a timeout timeout 30s qemu-system-x86_64 \ @@ -68,14 +75,14 @@ jobs: # Wait for boot (adjust timing as needed) sleep 10 - # Take screenshot using ImageMagick - import -window root build/qemu-screenshot.png || echo "Screenshot capture failed" + # Take screenshot using ImageMagick (optional - don't fail if this doesn't work) + import -window root build/qemu-screenshot.png || echo "Screenshot capture failed (non-fatal)" - # Gracefully stop QEMU + # Gracefully stop QEMU (don't fail if already stopped) kill $QEMU_PID 2>/dev/null || true wait $QEMU_PID 2>/dev/null || true - # Stop Xvfb + # Stop Xvfb (don't fail if already stopped) kill $XVFB_PID 2>/dev/null || true echo "Boot test completed" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9e6adaa..f18bf22 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,6 +19,8 @@ jobs: - name: Install build dependencies run: | + set -e # Exit on any error + sudo apt-get update sudo apt-get install -y \ build-essential \ @@ -31,12 +33,12 @@ jobs: - name: Build bootloader run: | cd bootloader - make || echo "Warning: Bootloader build incomplete (expected in early development)" + make - name: Build kernel run: | cd kernel - make || echo "Warning: Kernel build incomplete (expected in early development)" + make - name: Create bootable image run: | @@ -44,24 +46,35 @@ jobs: - name: Prepare release directory run: | + set -e # Exit on any error + mkdir -p release - # Copy the bootable disk image + # Copy the bootable disk image (required) if [ -f build/metalos.img ]; then cp build/metalos.img release/ echo "✓ Copied metalos.img" + else + echo "Error: build/metalos.img not found!" + exit 1 fi - # Copy bootloader if it exists + # Copy bootloader if it exists (required) if [ -f bootloader/bootx64.efi ]; then cp bootloader/bootx64.efi release/ echo "✓ Copied bootx64.efi" + else + echo "Error: bootloader/bootx64.efi not found!" + exit 1 fi - # Copy kernel if it exists + # Copy kernel if it exists (required) if [ -f kernel/metalos.bin ]; then cp kernel/metalos.bin release/ echo "✓ Copied metalos.bin" + else + echo "Error: kernel/metalos.bin not found!" + exit 1 fi # Copy QEMU instructions @@ -147,6 +160,8 @@ jobs: - name: Create release archive run: | + set -e # Exit on any error + cd release zip -r ../metalos-release.zip . cd .. diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index e6d7c13..ce59676 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -19,6 +19,8 @@ jobs: - name: Install dependencies run: | + set -e # Exit on any error + sudo apt-get update sudo apt-get install -y build-essential diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 7168da1..fac499b 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -10,7 +10,7 @@ MetalOS is **the absolute minimum operating system** needed to boot QT6 Hello Wo ## Development Phases -### Phase 1: Foundation ✓ (Current) +### Phase 1: Foundation ✅ COMPLETE **Goal**: Establish project structure and documentation @@ -23,32 +23,35 @@ MetalOS is **the absolute minimum operating system** needed to boot QT6 Hello Wo - [x] Document development workflow **Deliverables**: -- Project structure in place -- Documentation framework -- Skeleton code for bootloader and kernel -- Build system (Makefiles) +- ✅ Project structure in place +- ✅ Documentation framework +- ✅ Skeleton code for bootloader and kernel +- ✅ Build system (Makefiles, CMake, Conan) -### Phase 2: UEFI Bootloader (Next) +### Phase 2: UEFI Bootloader ✅ COMPLETE **Goal**: Load kernel and jump (< 10 KB code) **Tasks**: -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 +- [x] Console output for debugging (UEFI OutputString) +- [x] Get framebuffer info from GOP (Graphics Output Protocol) +- [x] Load kernel blob from known location +- [x] Get minimal memory map +- [x] Exit boot services +- [x] Jump to kernel +- [x] ACPI RSDP discovery (bonus) +- [x] Multiple build system support (bonus) -**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 +**Achievements**: +- ✅ Complete UEFI bootloader implementation (~6.3 KB) +- ✅ Valid PE32+ EFI executable +- ✅ Comprehensive UEFI protocol definitions +- ✅ Support for Make, CMake, and Conan build systems +- ✅ Full documentation and testing -**Success Criteria**: Bootloader prints messages and jumps to kernel +**Success Criteria**: ✅ Bootloader successfully loads kernel and provides boot information -### Phase 3: Minimal Kernel +### Phase 3: Minimal Kernel (In Progress) **Goal**: Initialize hardware (< 100 KB code) @@ -59,23 +62,34 @@ MetalOS is **the absolute minimum operating system** needed to boot QT6 Hello Wo - No fancy page fault handling 2. Interrupt handling - - IDT with ~5 handlers max - - Timer, keyboard, mouse, GPU (if needed) - - No complex IRQ routing + - [x] IDT with handlers + - [x] Timer interrupt + - [ ] Keyboard interrupt + - [ ] Mouse interrupt + - [x] Basic interrupt framework 3. Memory allocator - - Bump allocator or simple free list - - No fancy algorithms - - Just malloc/free for QT6 + - [x] Basic memory management structures + - [ ] Bump allocator or simple free list + - [ ] malloc/free for applications -4. NO scheduler - one process, always running -5. NO process management - app is statically linked with kernel or simple jump +4. Core Components + - [x] GDT (Global Descriptor Table) + - [x] IDT (Interrupt Descriptor Table) + - [x] APIC (Advanced Programmable Interrupt Controller) + - [x] PCI scanning + - [x] SMP/multicore support framework + - [x] Spinlocks for synchronization -**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 +**Progress**: +- ✅ Core kernel structure in place +- ✅ GDT and IDT setup +- ✅ Basic interrupt handling +- ✅ APIC initialization +- ✅ PCI device enumeration +- ✅ SMP/multicore support framework +- ⏳ Memory allocator needs completion +- ⏳ Device drivers need implementation **Success Criteria**: Kernel boots, prints messages, mallocs work @@ -226,9 +240,9 @@ MetalOS is **the absolute minimum operating system** needed to boot QT6 Hello Wo *These are rough estimates for a single developer* -- Phase 1: 1 week ✓ (Complete) -- Phase 2: 2-3 weeks -- Phase 3: 3-4 weeks +- Phase 1: 1 week ✅ (Complete) +- Phase 2: 2-3 weeks ✅ (Complete) +- Phase 3: 3-4 weeks (In Progress) - Phase 4: 4-6 weeks - Phase 5: 1-2 weeks - Phase 6: 2-3 weeks @@ -237,6 +251,8 @@ MetalOS is **the absolute minimum operating system** needed to boot QT6 Hello Wo **Total**: ~4-6 months of focused development +**Status**: Phase 2 complete, Phase 3 in progress with core kernel components implemented (GDT, IDT, interrupts, memory management, SMP support, PCI scanning). + ## Technical Challenges ### Major Challenges @@ -311,11 +327,14 @@ MetalOS is **the absolute minimum operating system** needed to boot QT6 Hello Wo 4. **Dynamic Linking**: ❌ Not needed - Static link everything for simplicity -5. **SMP**: ❌ Not needed - - Single core is fine for hello world +5. **SMP**: ⚠️ Basic support implemented + - Basic multicore/SMP framework in place for learning + - Single core is sufficient for hello world + - Can be simplified later if needed -6. **ACPI**: ⚠️ Minimal - - Just enough to work with GPU +6. **ACPI**: ✅ Implemented + - RSDP discovery in bootloader + - Needed for hardware discovery 7. **Multiple Applications**: ❌ Not needed - One application only - the QT6 hello world