diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..25d4907 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,55 @@ +# Docker ignore file for MetalOS +# Excludes unnecessary files from Docker build context + +# Build artifacts +build/ +*.o +*.d +*.a +*.so +*.bin +*.efi +*.elf +*.img +*.iso +*.log + +# Git directory +.git/ +.gitignore +.gitattributes + +# Editor files +.vscode/ +.idea/ +*.swp +*.swo +*~ +*.sublime-* + +# OS specific +.DS_Store +Thumbs.db + +# Temporary files +tmp/ +*.tmp + +# GitHub workflows (not needed in container) +.github/ + +# Documentation (will be copied separately if needed) +docs/ + +# Test artifacts +tests/unit/test_* +!tests/unit/*.c + +# Qt specific build artifacts +*.pro.user +*.pro.user.* +moc_*.cpp +moc_*.h +qrc_*.cpp +ui_*.h +.qmake.stash diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e5e8365 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,61 @@ +# MetalOS Docker Build Environment +# This container includes all dependencies needed to build MetalOS + +FROM ubuntu:22.04 + +# Avoid interactive prompts during package installation +ENV DEBIAN_FRONTEND=noninteractive + +# Set working directory +WORKDIR /metalos + +# Install base build tools and dependencies +RUN apt-get update && apt-get install -y \ + # Build essentials + build-essential \ + gcc \ + g++ \ + nasm \ + make \ + cmake \ + ninja-build \ + meson \ + pkg-config \ + git \ + wget \ + curl \ + ca-certificates \ + # QEMU and UEFI firmware + qemu-system-x86 \ + ovmf \ + # Image creation tools + mtools \ + xorriso \ + dosfstools \ + # Python for build scripts + python3 \ + python3-pip \ + # Additional utilities + vim \ + less \ + file \ + && rm -rf /var/lib/apt/lists/* + +# Create directory structure for dependencies +RUN mkdir -p /metalos/deps/firmware \ + /metalos/deps/ovmf \ + /metalos/deps/mesa-radv \ + /metalos/deps/qt6 \ + /metalos/scripts + +# Set up OVMF firmware in deps directory +RUN cp /usr/share/OVMF/OVMF_CODE.fd /metalos/deps/ovmf/ 2>/dev/null || \ + cp /usr/share/ovmf/OVMF.fd /metalos/deps/ovmf/ 2>/dev/null || \ + echo "OVMF firmware will be installed by setup script" + +# Set environment variables +ENV PATH="/metalos/tools:${PATH}" +ENV METALOS_ROOT="/metalos" + +# Default command +CMD ["/bin/bash"] diff --git a/README.md b/README.md index b6123b7..8ac88be 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,19 @@ See [docs/ROADMAP.md](docs/ROADMAP.md) for detailed phase breakdown. ## Building +### Docker Build (Recommended) + +The easiest way to build MetalOS with all dependencies: + +```bash +./scripts/docker-build.sh # Build Docker image +./scripts/docker-run.sh scripts/setup-deps.sh # Setup dependencies +./scripts/docker-run.sh make all # Build everything +./scripts/docker-run.sh make qemu # Test in QEMU +``` + +### Native Build + ```bash make all # Build bootloader, kernel, and userspace make test # Run unit tests @@ -90,10 +103,12 @@ See [docs/BUILD.md](docs/BUILD.md) for detailed build instructions and [docs/TES MetalOS manages third-party dependencies in-house for reproducibility and offline development: - **GPU Firmware** - AMD Navi 23 firmware blobs (dimgrey_cavefish_*.bin) -- **Mesa RADV** - Vulkan driver for AMD GPUs -- **QT6** - Application framework (minimal static build) +- **Mesa RADV** - Vulkan driver for AMD GPUs (planned Phase 4) +- **QT6** - Application framework (minimal static build, planned Phase 7) - **OVMF** - UEFI firmware for QEMU testing +**Setup dependencies**: `./scripts/setup-deps.sh all` + See [deps/README.md](deps/README.md) for detailed dependency management instructions. ## Documentation diff --git a/docs/BUILD.md b/docs/BUILD.md index a67f278..518ea52 100644 --- a/docs/BUILD.md +++ b/docs/BUILD.md @@ -1,6 +1,56 @@ # Building MetalOS -## Prerequisites +MetalOS can be built either using Docker (recommended for consistent builds) or natively on your system. + +## Docker Build (Recommended) + +The easiest way to build MetalOS is using Docker, which provides a pre-configured environment with all dependencies. + +### Prerequisites + +- **Docker**: Docker Engine 20.10 or later + - [Install Docker](https://docs.docker.com/get-docker/) + +### Quick Start + +```bash +# 1. Build the Docker image +./scripts/docker-build.sh + +# 2. Setup dependencies (downloads AMD GPU firmware, etc.) +./scripts/docker-run.sh scripts/setup-deps.sh + +# 3. Build MetalOS +./scripts/docker-run.sh make all + +# 4. Test in QEMU (headless mode) +./scripts/docker-run.sh make qemu + +# 5. Optional: Interactive shell in container +./scripts/docker-run.sh /bin/bash +``` + +### What's Included in Docker + +The Docker image includes: +- **Build tools**: GCC, NASM, Make, CMake, Meson +- **QEMU**: For testing with UEFI firmware +- **OVMF**: UEFI firmware for QEMU +- **Dependency management**: Scripts to download AMD firmware, Mesa RADV, QT6 + +### Docker Build Benefits + +- ✅ Consistent build environment across all platforms +- ✅ No need to install cross-compiler manually +- ✅ Pre-configured QEMU and OVMF setup +- ✅ Isolated from host system +- ✅ Easy CI/CD integration + +## Native Build + +If you prefer to build natively without Docker: + +### Prerequisites ### Required Tools @@ -161,6 +211,46 @@ make qemu-uefi-test This boots directly to the UEFI shell, confirming your QEMU+OVMF setup works correctly. +## Managing Dependencies + +MetalOS requires several third-party dependencies for GPU support and application framework. + +### Dependency Setup Script + +Use the provided script to download and setup dependencies: + +```bash +# Setup all dependencies +./scripts/setup-deps.sh all + +# Or setup individually +./scripts/setup-deps.sh firmware # AMD GPU firmware blobs +./scripts/setup-deps.sh ovmf # UEFI firmware +./scripts/setup-deps.sh mesa # Mesa RADV (planned) +./scripts/setup-deps.sh qt6 # QT6 framework (planned) +``` + +### Required Dependencies + +1. **AMD GPU Firmware** (`deps/firmware/`) + - Radeon RX 6600 (Navi 23) firmware files + - Automatically downloaded from linux-firmware repository + - Files: `dimgrey_cavefish_*.bin` + +2. **OVMF UEFI Firmware** (`deps/ovmf/`) + - EDK II OVMF for QEMU testing + - Copied from system installation or downloaded + +3. **Mesa RADV** (`deps/mesa-radv/`) - Planned for Phase 4 + - Vulkan driver for AMD GPUs + - Will be configured to use custom kernel interface + +4. **QT6 Framework** (`deps/qt6/`) - Planned for Phase 7 + - Minimal static build for the single application + - QtCore, QtGui, QtWidgets modules only + +See [deps/README.md](../deps/README.md) for detailed dependency documentation. + ## Testing on Real Hardware ⚠️ **WARNING**: Testing on real hardware can be risky. Always backup your data. diff --git a/docs/DOCKER.md b/docs/DOCKER.md new file mode 100644 index 0000000..b0f028c --- /dev/null +++ b/docs/DOCKER.md @@ -0,0 +1,350 @@ +# Docker Build Environment for MetalOS + +This document explains how to use Docker to build MetalOS with all required dependencies pre-configured. + +## Why Docker? + +Building MetalOS natively requires: +- Cross-compiler toolchain setup +- QEMU and UEFI firmware installation +- Dependency management (firmware blobs, Mesa RADV, QT6) +- Platform-specific configurations + +Docker simplifies this by providing a pre-configured build environment that works consistently across: +- Linux (various distributions) +- macOS (with Docker Desktop) +- Windows (with Docker Desktop + WSL2) + +## Prerequisites + +Install Docker: +- **Linux**: [Docker Engine](https://docs.docker.com/engine/install/) +- **macOS/Windows**: [Docker Desktop](https://docs.docker.com/desktop/) + +Verify installation: +```bash +docker --version +# Should output: Docker version 20.10.x or later +``` + +## Quick Start + +### 1. Build the Docker Image + +From the MetalOS repository root: + +```bash +./scripts/docker-build.sh +``` + +This creates a `metalos-builder:latest` image with: +- Ubuntu 22.04 base +- Build tools (gcc, nasm, make, cmake, meson) +- QEMU with UEFI support +- OVMF firmware +- Python3 for build scripts + +Build time: ~5-10 minutes (one-time setup) + +### 2. Setup Dependencies + +Download required firmware and dependencies: + +```bash +# Setup all dependencies +./scripts/docker-run.sh scripts/setup-deps.sh all + +# Or setup individually +./scripts/docker-run.sh scripts/setup-deps.sh firmware # AMD GPU firmware +./scripts/docker-run.sh scripts/setup-deps.sh ovmf # UEFI firmware +``` + +This downloads: +- **AMD GPU firmware blobs** (dimgrey_cavefish_*.bin) from linux-firmware repository +- **OVMF UEFI firmware** for QEMU testing + +### 3. Build MetalOS + +Build the bootloader and kernel: + +```bash +./scripts/docker-run.sh make all +``` + +### 4. Test in QEMU + +Run MetalOS in QEMU with UEFI firmware: + +```bash +# Headless mode (serial console only) +./scripts/docker-run.sh make qemu + +# With debug output +./scripts/docker-run.sh make qemu-debug + +# Test UEFI firmware setup +./scripts/docker-run.sh make qemu-uefi-test +``` + +## Common Tasks + +### Interactive Shell + +Get a bash shell inside the container: + +```bash +./scripts/docker-run.sh /bin/bash +``` + +From the shell, you can run any commands: +```bash +# Inside container +make all +make test +make qemu +scripts/setup-deps.sh firmware +``` + +Exit with `exit` or Ctrl+D. + +### Clean Build + +```bash +./scripts/docker-run.sh make clean +``` + +### Run Unit Tests + +```bash +./scripts/docker-run.sh make test +``` + +### View Dependency Status + +```bash +./scripts/docker-run.sh ls -la deps/firmware/ +./scripts/docker-run.sh cat deps/firmware/VERSION +``` + +## Advanced Usage + +### Custom Docker Image Name + +Edit `scripts/docker-build.sh` and `scripts/docker-run.sh` to change: +```bash +IMAGE_NAME="my-custom-name" +IMAGE_TAG="v1.0" +``` + +### Rebuild Docker Image + +After updating Dockerfile: + +```bash +./scripts/docker-build.sh +``` + +Docker will cache layers and only rebuild changed parts. + +### Running Specific Commands + +The `docker-run.sh` script accepts any command: + +```bash +# Run specific make target +./scripts/docker-run.sh make kernel + +# Check QEMU version +./scripts/docker-run.sh qemu-system-x86_64 --version + +# List files +./scripts/docker-run.sh ls -la build/ + +# Run a script +./scripts/docker-run.sh ./scripts/create_image.sh +``` + +### Volume Mounts + +The source directory is mounted at `/metalos` inside the container: +- Changes made in the container are reflected on the host +- Build artifacts created in the container are accessible on the host +- No need to copy files in/out of the container + +### GPU Access (Future) + +For testing with host GPU (when GPU driver is implemented): + +```bash +docker run --rm -it \ + --device=/dev/dri \ + -v "$(pwd):/metalos" \ + metalos-builder:latest \ + /bin/bash +``` + +## Troubleshooting + +### Docker Permission Denied + +On Linux, add your user to the docker group: +```bash +sudo usermod -aG docker $USER +# Log out and back in +``` + +### Cannot Connect to Docker Daemon + +Ensure Docker daemon is running: +```bash +sudo systemctl start docker # Linux +# Or start Docker Desktop # macOS/Windows +``` + +### Build Fails with "No Space Left" + +Docker has run out of disk space. Clean up: +```bash +docker system prune -a +``` + +### Container Files Owned by Root + +This is normal. To change ownership: +```bash +sudo chown -R $USER:$USER build/ +``` + +Or use Docker with user mapping: +```bash +docker run --rm -it \ + --user $(id -u):$(id -g) \ + -v "$(pwd):/metalos" \ + metalos-builder:latest \ + /bin/bash +``` + +### QEMU Display Issues + +Docker containers run headless by default. For graphical QEMU: + +1. On Linux with X11: +```bash +docker run --rm -it \ + -e DISPLAY=$DISPLAY \ + -v /tmp/.X11-unix:/tmp/.X11-unix \ + -v "$(pwd):/metalos" \ + metalos-builder:latest \ + make qemu QEMU_DISPLAY=gtk +``` + +2. On macOS/Windows: Use VNC or serial console instead + +3. For now, use headless mode: +```bash +./scripts/docker-run.sh make qemu QEMU_DISPLAY=none +``` + +## CI/CD Integration + +### GitHub Actions + +Example workflow: + +```yaml +name: Docker Build + +on: [push, pull_request] + +jobs: + docker-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build Docker image + run: ./scripts/docker-build.sh + + - name: Setup dependencies + run: ./scripts/docker-run.sh scripts/setup-deps.sh all + + - name: Build MetalOS + run: ./scripts/docker-run.sh make all + + - name: Run tests + run: ./scripts/docker-run.sh make test +``` + +### GitLab CI + +```yaml +build: + image: docker:latest + services: + - docker:dind + script: + - ./scripts/docker-build.sh + - ./scripts/docker-run.sh make all + - ./scripts/docker-run.sh make test +``` + +## Docker Image Contents + +The `metalos-builder` image includes: + +### Build Tools +- gcc, g++, make, cmake, ninja, meson +- nasm (assembler) +- binutils (ld, as, objcopy, etc.) +- pkg-config + +### Testing Tools +- qemu-system-x86_64 +- OVMF UEFI firmware +- mtools, xorriso (image creation) + +### Utilities +- git, wget, curl +- Python3 +- vim, less, file + +### Directory Structure +``` +/metalos/ +├── deps/ # Dependencies (mounted from host) +│ ├── firmware/ # AMD GPU firmware blobs +│ ├── ovmf/ # UEFI firmware +│ ├── mesa-radv/ # Mesa RADV driver +│ └── qt6/ # QT6 framework +├── bootloader/ # UEFI bootloader source +├── kernel/ # Kernel source +├── scripts/ # Build scripts +└── build/ # Build artifacts +``` + +## Next Steps + +After setting up the Docker environment: + +1. Review [docs/BUILD.md](BUILD.md) for detailed build instructions +2. Check [docs/DEVELOPMENT.md](DEVELOPMENT.md) for development workflow +3. See [docs/TESTING.md](TESTING.md) for testing procedures +4. Read [deps/README.md](../deps/README.md) for dependency details + +## Comparison: Docker vs Native Build + +| Aspect | Docker Build | Native Build | +|--------|-------------|--------------| +| Setup Time | 5-10 minutes (one-time) | 1-2 hours (toolchain setup) | +| Platform Support | Linux, macOS, Windows | Linux (primary), macOS (limited) | +| Consistency | Identical across platforms | Platform-dependent | +| Isolation | Complete isolation | Uses system tools | +| Disk Space | ~2GB for image | ~500MB for tools | +| Performance | Slight overhead | Native speed | +| CI/CD | Easy integration | Platform-specific config | + +## Getting Help + +- **Documentation**: Check [docs/](.) directory +- **Issues**: [GitHub Issues](https://github.com/johndoe6345789/MetalOS/issues) +- **Discussions**: Use GitHub Discussions for questions diff --git a/scripts/docker-build.sh b/scripts/docker-build.sh new file mode 100755 index 0000000..122bae3 --- /dev/null +++ b/scripts/docker-build.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# Build MetalOS Docker image with all dependencies + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +METALOS_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +IMAGE_NAME="metalos-builder" +IMAGE_TAG="latest" + +echo "=== Building MetalOS Docker Image ===" +echo "Image: $IMAGE_NAME:$IMAGE_TAG" +echo "Context: $METALOS_ROOT" +echo "" + +cd "$METALOS_ROOT" + +# Build the Docker image +docker build \ + -t "$IMAGE_NAME:$IMAGE_TAG" \ + -f Dockerfile \ + . + +echo "" +echo "✓ Docker image built successfully: $IMAGE_NAME:$IMAGE_TAG" +echo "" +echo "Next steps:" +echo " 1. Run setup script: ./scripts/docker-run.sh setup-deps.sh" +echo " 2. Build MetalOS: ./scripts/docker-run.sh make all" +echo " 3. Test in QEMU: ./scripts/docker-run.sh make qemu" diff --git a/scripts/docker-run.sh b/scripts/docker-run.sh new file mode 100755 index 0000000..ac5f4bf --- /dev/null +++ b/scripts/docker-run.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Run commands in MetalOS Docker container + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +METALOS_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +IMAGE_NAME="metalos-builder" +IMAGE_TAG="latest" + +# Check if Docker image exists +if ! docker image inspect "$IMAGE_NAME:$IMAGE_TAG" >/dev/null 2>&1; then + echo "Error: Docker image $IMAGE_NAME:$IMAGE_TAG not found" + echo "Build it first with: ./scripts/docker-build.sh" + exit 1 +fi + +# Run command in container +# Mount the MetalOS source directory as a volume +docker run --rm -it \ + -v "$METALOS_ROOT:/metalos" \ + -w /metalos \ + "$IMAGE_NAME:$IMAGE_TAG" \ + "$@" diff --git a/scripts/setup-deps.sh b/scripts/setup-deps.sh new file mode 100755 index 0000000..cb01e0f --- /dev/null +++ b/scripts/setup-deps.sh @@ -0,0 +1,232 @@ +#!/bin/bash +# MetalOS Dependency Setup Script +# Downloads and sets up all required dependencies for building MetalOS + +set -e # Exit on error + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +METALOS_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +DEPS_DIR="$METALOS_ROOT/deps" + +echo "=== MetalOS Dependency Setup ===" +echo "Root directory: $METALOS_ROOT" +echo "Dependencies directory: $DEPS_DIR" +echo "" + +# Create deps directories if they don't exist +mkdir -p "$DEPS_DIR"/{firmware,ovmf,mesa-radv,qt6} + +# Function to download AMD GPU firmware blobs +setup_firmware() { + echo "=== Setting up AMD GPU Firmware Blobs ===" + + FIRMWARE_DIR="$DEPS_DIR/firmware" + TEMP_DIR=$(mktemp -d) + + cd "$TEMP_DIR" + + # Clone linux-firmware repository (shallow clone for speed) + echo "Downloading linux-firmware repository..." + git clone --depth 1 https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git + + # Copy required Navi 23 (dimgrey_cavefish) firmware files + echo "Copying Navi 23 firmware files..." + FIRMWARE_FILES=( + "dimgrey_cavefish_ce.bin" + "dimgrey_cavefish_me.bin" + "dimgrey_cavefish_mec.bin" + "dimgrey_cavefish_pfp.bin" + "dimgrey_cavefish_rlc.bin" + "dimgrey_cavefish_sdma.bin" + "dimgrey_cavefish_vcn.bin" + ) + + for file in "${FIRMWARE_FILES[@]}"; do + if [ -f "linux-firmware/amdgpu/$file" ]; then + cp "linux-firmware/amdgpu/$file" "$FIRMWARE_DIR/" + echo " ✓ Copied $file" + else + echo " ⚠ Warning: $file not found" + fi + done + + # Get commit hash for version tracking + cd linux-firmware + COMMIT_HASH=$(git rev-parse HEAD) + COMMIT_DATE=$(git log -1 --format=%cd --date=short) + + # Create VERSION file + cat > "$FIRMWARE_DIR/VERSION" <> "$FIRMWARE_DIR/VERSION" + fi + done + + cd "$METALOS_ROOT" + rm -rf "$TEMP_DIR" + + echo "✓ Firmware blobs setup complete" + echo "" +} + +# Function to setup OVMF UEFI firmware +setup_ovmf() { + echo "=== Setting up OVMF UEFI Firmware ===" + + OVMF_DIR="$DEPS_DIR/ovmf" + + # Check for OVMF in system locations + if [ -f /usr/share/OVMF/OVMF_CODE.fd ]; then + echo "Copying OVMF from /usr/share/OVMF/..." + cp /usr/share/OVMF/OVMF_CODE.fd "$OVMF_DIR/" 2>/dev/null || true + cp /usr/share/OVMF/OVMF_VARS.fd "$OVMF_DIR/" 2>/dev/null || true + elif [ -f /usr/share/ovmf/OVMF.fd ]; then + echo "Copying OVMF from /usr/share/ovmf/..." + cp /usr/share/ovmf/OVMF.fd "$OVMF_DIR/OVMF_CODE.fd" 2>/dev/null || true + elif [ -f /usr/share/edk2-ovmf/x64/OVMF_CODE.fd ]; then + echo "Copying OVMF from /usr/share/edk2-ovmf/..." + cp /usr/share/edk2-ovmf/x64/OVMF_CODE.fd "$OVMF_DIR/" 2>/dev/null || true + cp /usr/share/edk2-ovmf/x64/OVMF_VARS.fd "$OVMF_DIR/" 2>/dev/null || true + elif [ -f /usr/share/qemu/ovmf-x86_64.bin ]; then + echo "Copying OVMF from /usr/share/qemu/..." + cp /usr/share/qemu/ovmf-x86_64.bin "$OVMF_DIR/OVMF_CODE.fd" 2>/dev/null || true + else + echo "⚠ Warning: OVMF firmware not found in system paths" + echo " Install with: sudo apt-get install ovmf (Ubuntu/Debian)" + echo " sudo pacman -S edk2-ovmf (Arch Linux)" + fi + + # Create VERSION file + if [ -f "$OVMF_DIR/OVMF_CODE.fd" ]; then + cat > "$OVMF_DIR/VERSION" <> "$OVMF_DIR/VERSION" + fi + done + echo "✓ OVMF firmware setup complete" + else + echo "⚠ OVMF setup incomplete - no firmware files copied" + fi + + echo "" +} + +# Function to setup Mesa RADV (placeholder for now) +setup_mesa_radv() { + echo "=== Setting up Mesa RADV Driver ===" + + MESA_DIR="$DEPS_DIR/mesa-radv" + + cat > "$MESA_DIR/STATUS" < "$QT6_DIR/STATUS" <