Files
MetalOS/docs/QEMU_TESTING.md
2025-12-28 18:32:04 +00:00

463 lines
9.2 KiB
Markdown

# QEMU UEFI Testing Guide
This guide covers testing MetalOS in QEMU with UEFI firmware (OVMF).
## Overview
MetalOS uses QEMU with OVMF (Open Virtual Machine Firmware) to test UEFI boot functionality without requiring physical hardware. This enables rapid development and testing of the bootloader and kernel.
## Prerequisites
### Required Software
1. **QEMU** (version 6.0 or later recommended)
- Provides x86_64 virtualization
- Supports UEFI firmware
2. **OVMF** (UEFI firmware for QEMU)
- Open-source UEFI implementation
- Required for UEFI boot in QEMU
3. **mtools** (for disk image creation)
- Creates FAT32 filesystems
- Manipulates MS-DOS filesystems
### Installation
**Ubuntu/Debian**:
```bash
sudo apt-get update
sudo apt-get install qemu-system-x86 ovmf mtools xorriso
```
**Arch Linux**:
```bash
sudo pacman -S qemu-full edk2-ovmf mtools xorriso
```
**Fedora**:
```bash
sudo dnf install qemu-system-x86 edk2-ovmf mtools xorriso
```
**macOS**:
```bash
brew install qemu mtools xorriso
# Note: OVMF may need manual installation
```
## Quick Start
### Basic QEMU Boot
```bash
# Build and boot MetalOS in QEMU
make qemu
```
This command:
1. Builds the bootloader and kernel (or uses placeholders)
2. Creates a FAT32 disk image with UEFI boot structure
3. Launches QEMU with OVMF firmware
4. Boots the system in headless mode
**Expected Output**:
```
Building bootloader...
Building kernel...
Creating bootable image...
Using mtools to create FAT32 disk image...
Success! Created build/metalos.img
Starting QEMU with UEFI firmware...
Using OVMF firmware: /usr/share/ovmf/OVMF.fd
Display mode: none (set QEMU_DISPLAY=gtk for graphical)
[UEFI boot messages...]
```
### Verify UEFI Setup
To verify that QEMU and OVMF are properly installed:
```bash
make qemu-uefi-test
```
This boots directly to the UEFI shell without any OS image, confirming your setup works.
## Display Modes
MetalOS supports multiple display modes for different use cases:
### Headless Mode (Default)
```bash
make qemu
# or explicitly
make qemu QEMU_DISPLAY=none
```
**Use cases**:
- CI/CD pipelines
- Headless servers
- Automated testing
- Serial console debugging
**Characteristics**:
- No graphical window
- Serial output only
- Works in any environment
### Graphical Mode - GTK
```bash
make qemu QEMU_DISPLAY=gtk
```
**Use cases**:
- Interactive development
- Visual debugging
- UI testing
**Characteristics**:
- Native GTK window
- Full graphics support
- Requires X11/Wayland
### Graphical Mode - SDL
```bash
make qemu QEMU_DISPLAY=sdl
```
**Use cases**:
- Cross-platform development
- Alternative to GTK
**Characteristics**:
- SDL window
- Good compatibility
- Lighter than GTK
### Text Mode - Curses
```bash
make qemu QEMU_DISPLAY=curses
```
**Use cases**:
- SSH sessions
- Text-only environments
**Characteristics**:
- Terminal-based UI
- No X11 required
- Works over SSH
## Advanced Testing
### Debug Mode
Boot with CPU interrupt and reset debugging:
```bash
make qemu-debug
```
**Additional debug output includes**:
- CPU interrupts
- CPU resets
- Exception handling
- Hardware events
### GDB Debugging
Debug the kernel with GDB:
**Terminal 1** - Start QEMU with GDB server:
```bash
make qemu-gdb
```
QEMU will wait for GDB connection on `localhost:1234`.
**Terminal 2** - Connect GDB:
```bash
gdb kernel/metalos.bin
(gdb) target remote localhost:1234
(gdb) break kernel_main
(gdb) continue
```
**Useful GDB commands**:
```gdb
# Set breakpoints
break *0x100000 # Break at address
break kernel_main # Break at function
# Examine memory
x/10i $rip # Disassemble 10 instructions
x/10x 0x100000 # Show 10 hex values
# Step through code
stepi # Step one instruction
nexti # Step over calls
continue # Continue execution
# Register inspection
info registers # Show all registers
print $rax # Print specific register
```
## Disk Image Details
### Image Structure
The `build/metalos.img` file contains:
```
metalos.img (64 MB FAT32 disk)
├── EFI/
│ └── BOOT/
│ └── bootx64.efi # UEFI bootloader
└── metalos.bin # Kernel binary
```
### Inspecting the Image
View the disk image contents:
```bash
# List files in the image
mdir -i build/metalos.img ::/
# List EFI boot directory
mdir -i build/metalos.img ::/EFI/BOOT/
# Extract a file
mcopy -i build/metalos.img ::/metalos.bin extracted_kernel.bin
# Get image info
file build/metalos.img
```
### Manual Image Creation
If you need to manually create or modify the image:
```bash
# Create empty 64MB image
dd if=/dev/zero of=disk.img bs=1M count=64
# Format as FAT32
mformat -i disk.img -F -v "METALOS" ::
# Create directory structure
mmd -i disk.img ::/EFI
mmd -i disk.img ::/EFI/BOOT
# Copy files
mcopy -i disk.img bootloader/bootx64.efi ::/EFI/BOOT/
mcopy -i disk.img kernel/metalos.bin ::/
```
## OVMF Firmware
### Firmware Locations
The Makefile automatically detects OVMF firmware in these locations:
- `/usr/share/OVMF/OVMF_CODE.fd` (Ubuntu/Debian)
- `/usr/share/ovmf/OVMF.fd` (Ubuntu/Debian alternative)
- `/usr/share/edk2-ovmf/x64/OVMF_CODE.fd` (Arch Linux)
- `/usr/share/qemu/ovmf-x86_64.bin` (Other systems)
### Firmware Variants
**OVMF_CODE.fd**: Code-only firmware (read-only)
- Used with `-drive if=pflash,readonly=on`
- Best for testing
- Variables stored separately
**OVMF.fd**: Combined code and variables
- Single file for firmware
- Simpler setup
- Variables reset on each boot
**OVMF.secboot.fd**: Secure Boot enabled
- For secure boot testing
- Requires signed bootloader
## Troubleshooting
### QEMU Won't Start
**Issue**: `gtk initialization failed` or `Could not initialize SDL`
**Solution**: Use headless mode:
```bash
make qemu QEMU_DISPLAY=none
```
### OVMF Not Found
**Issue**: `Error: OVMF UEFI firmware not found!`
**Solution**: Install OVMF package:
```bash
# Ubuntu/Debian
sudo apt-get install ovmf
# Arch Linux
sudo pacman -S edk2-ovmf
```
### Image Creation Fails
**Issue**: `mformat: command not found`
**Solution**: Install mtools:
```bash
# Ubuntu/Debian
sudo apt-get install mtools
# Arch Linux
sudo pacman -S mtools
```
### Boots to UEFI Shell
**Expected Behavior**: During development, booting to UEFI shell is normal until the bootloader is complete.
**What it means**:
- ✅ QEMU and OVMF working correctly
- ✅ Disk image recognized (shows as FS0)
- ⚠️ Bootloader not yet functional (expected in Phase 1)
**Next steps**: Implement Phase 2 (UEFI Bootloader)
### Serial Output Missing
**Issue**: No serial console output
**Solution**: Ensure serial port is configured correctly:
- Output goes to stdio by default
- Check that `-serial stdio` is in QEMU command
- Verify kernel writes to serial port
### QEMU Hangs
**Issue**: QEMU appears to hang during boot
**Possible causes**:
1. Bootloader infinite loop
2. Waiting for input
3. Hardware initialization issue
**Debug steps**:
```bash
# Use debug mode
make qemu-debug
# Use GDB to inspect state
make qemu-gdb
# In another terminal: gdb kernel/metalos.bin
```
## CI/CD Integration
### GitHub Actions
Example workflow for QEMU testing:
```yaml
name: QEMU Boot Test
on: [push, pull_request]
jobs:
qemu-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y qemu-system-x86 ovmf mtools
- name: Build and test in QEMU
run: |
make qemu QEMU_DISPLAY=none &
QEMU_PID=$!
sleep 10
kill $QEMU_PID || true
```
### Docker Testing
Run QEMU tests in Docker:
```dockerfile
FROM ubuntu:latest
RUN apt-get update && apt-get install -y \
build-essential nasm qemu-system-x86 ovmf mtools
WORKDIR /metalos
COPY . .
CMD ["make", "qemu", "QEMU_DISPLAY=none"]
```
## Performance Tuning
### Memory Allocation
Default: 512 MB
Adjust memory:
```bash
# Edit Makefile QEMU command
qemu-system-x86_64 ... -m 1024M # Use 1GB
```
### CPU Configuration
Use multiple cores:
```bash
qemu-system-x86_64 ... -smp 2 # 2 cores
```
### KVM Acceleration
Enable KVM for faster emulation (Linux only):
```bash
qemu-system-x86_64 ... -enable-kvm
```
**Note**: Requires KVM kernel module and permissions.
## Best Practices
1. **Always test in headless mode first** - Ensures CI/CD compatibility
2. **Use serial output for debugging** - More reliable than graphics
3. **Keep disk images small** - 64 MB is sufficient for development
4. **Test with different OVMF versions** - Ensures compatibility
5. **Document boot behavior changes** - Track progress in commits
6. **Use GDB for serious debugging** - More powerful than printf
7. **Test on multiple systems** - Catch compatibility issues early
## Resources
- [QEMU Documentation](https://www.qemu.org/docs/master/)
- [OVMF Wiki](https://github.com/tianocore/tianocore.github.io/wiki/OVMF)
- [UEFI Specification](https://uefi.org/specifications)
- [OSDev Wiki - UEFI](https://wiki.osdev.org/UEFI)
## Related Documentation
- [BUILD.md](BUILD.md) - Build system and toolchain
- [TESTING.md](TESTING.md) - Complete testing guide
- [ROADMAP.md](ROADMAP.md) - Development phases
- [DEVELOPMENT.md](DEVELOPMENT.md) - Development workflow