Initial commit: DarkForge Linux — Phases 0-12

Complete from-scratch Linux distribution targeting AMD Ryzen 9 9950X3D +
NVIDIA RTX 5090 on ASUS ROG CROSSHAIR X870E HERO.

Deliverables:
- dpack: custom package manager in Rust (3,800 lines)
  - TOML package parser, dependency resolver, build sandbox
  - CRUX Pkgfile and Gentoo ebuild converters
  - Shared library conflict detection
- 124 package definitions across 4 repos (core/extra/desktop/gaming)
- 34 toolchain bootstrap scripts (LFS 13.0 adapted for Zen 5)
- Linux 6.19.8 kernel config (hardware-specific, fully commented)
- SysVinit init system with rc.d service scripts
- Live ISO builder (UEFI-only, squashfs+xorriso)
- Interactive installer (GPT partitioning, EFISTUB boot)
- Integration test checklist (docs/TESTING.md)

No systemd. No bootloader. No display manager.
Kernel boots via EFISTUB → auto-login → dwl Wayland compositor.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-19 11:30:40 +01:00
commit 029642ae5b
206 changed files with 14696 additions and 0 deletions

57
src/iso/README.md Normal file
View File

@@ -0,0 +1,57 @@
# DarkForge ISO Builder
Builds a bootable live USB/CD image containing the DarkForge installer and a minimal live environment.
## Overview
The ISO builder compresses the base system into a squashfs image, creates a UEFI-bootable ISO via xorriso, and includes the installer scripts for deploying DarkForge to disk.
## Requirements
- `mksquashfs` (squashfs-tools) — filesystem compression
- `xorriso` — ISO9660 image creation
- `mkfs.fat` (dosfstools) — EFI partition image
- `mcopy` (mtools) — copy files into FAT images
- A completed base system build (Phase 3)
- A compiled kernel at `kernel/vmlinuz`
## Usage
```bash
bash src/iso/build-iso.sh
```
Output: `darkforge-live.iso` in the project root.
## ISO Layout
```
darkforge-live.iso
├── EFI/BOOT/BOOTX64.EFI # Kernel (EFISTUB boot)
├── boot/cmdline.txt # Kernel command line
├── LiveOS/rootfs.img # squashfs compressed root
└── install/ # Installer scripts
```
## Boot Method
The ISO boots via UEFI only (El Torito with EFI System Partition). No legacy BIOS support. The kernel loads directly via EFISTUB.
## Testing
Test the ISO in QEMU:
```bash
qemu-system-x86_64 \
-enable-kvm \
-m 4G \
-bios /usr/share/ovmf/OVMF.fd \
-cdrom darkforge-live.iso \
-boot d
```
## Repository
```
git@git.dannyhaslund.dk:danny8632/darkforge.git
```

215
src/iso/build-iso.sh Executable file
View File

@@ -0,0 +1,215 @@
#!/bin/bash
# ============================================================================
# DarkForge Linux — ISO Builder
# ============================================================================
# Purpose: Build a bootable live USB/CD image containing the DarkForge
# installer and a minimal live environment.
# Inputs: A completed base system (Phase 3 packages installed)
# Outputs: darkforge-live.iso
#
# Requirements: squashfs-tools, xorriso, mtools, dosfstools
#
# The ISO layout:
# /EFI/BOOT/BOOTX64.EFI — The kernel (EFISTUB boot)
# /boot/cmdline.txt — Kernel command line
# /LiveOS/rootfs.img — squashfs compressed root filesystem
# /install/ — Installer scripts
# ============================================================================
set -euo pipefail
# --- Configuration ----------------------------------------------------------
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
BUILD_DIR="/tmp/darkforge-iso-build"
ISO_OUTPUT="${PROJECT_ROOT}/darkforge-live.iso"
ISO_LABEL="DARKFORGE"
KERNEL_PATH="${PROJECT_ROOT}/kernel/vmlinuz"
# If no pre-built kernel, this will be built during the ISO build process
# squashfs compression algorithm
SQFS_COMP="zstd"
SQFS_OPTS="-comp ${SQFS_COMP} -Xcompression-level 19 -b 1M"
# --- Colors -----------------------------------------------------------------
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
info() { echo -e "${CYAN}>>> ${1}${NC}"; }
ok() { echo -e "${GREEN}>>> ${1}${NC}"; }
warn() { echo -e "${YELLOW}!!! ${1}${NC}"; }
die() { echo -e "${RED}!!! ${1}${NC}"; exit 1; }
# --- Preflight checks -------------------------------------------------------
info "DarkForge Linux ISO Builder"
echo ""
for tool in mksquashfs xorriso mkfs.fat mcopy; do
command -v "${tool}" >/dev/null 2>&1 || die "Required tool not found: ${tool}"
done
# --- Clean previous builds --------------------------------------------------
info "Cleaning previous build artifacts..."
rm -rf "${BUILD_DIR}"
mkdir -p "${BUILD_DIR}"/{iso,rootfs,efi}
# --- Build the live root filesystem -----------------------------------------
info "Preparing live root filesystem..."
ROOTFS="${BUILD_DIR}/rootfs"
# Create essential directory structure
mkdir -p "${ROOTFS}"/{bin,boot,dev,etc,home,lib,lib64,mnt,opt,proc,root,run}
mkdir -p "${ROOTFS}"/{sbin,srv,sys,tmp,usr/{bin,include,lib,sbin,share},var}
mkdir -p "${ROOTFS}"/var/{cache,lib,log,tmp}
mkdir -p "${ROOTFS}"/etc/{rc.d,sysconfig}
mkdir -p "${ROOTFS}"/usr/share/{man,doc}
# Copy base system (installed via dpack or direct copy from the chroot)
# This expects the base system to exist in a staging area
BASE_SYSTEM="${PROJECT_ROOT}/build/base-system"
if [ -d "${BASE_SYSTEM}" ]; then
info "Copying base system from ${BASE_SYSTEM}..."
cp -a "${BASE_SYSTEM}"/* "${ROOTFS}"/
else
warn "No base system found at ${BASE_SYSTEM}"
warn "The ISO will contain a minimal skeleton only."
warn "Build the base system first (Phase 3), then re-run."
# Create minimal skeleton for testing
# These would normally come from the base system packages
cp -a /bin/busybox "${ROOTFS}/bin/" 2>/dev/null || true
fi
# --- Install DarkForge configuration ----------------------------------------
info "Installing DarkForge configuration..."
cp "${PROJECT_ROOT}/configs/rc.conf" "${ROOTFS}/etc/rc.conf"
cp "${PROJECT_ROOT}/configs/inittab" "${ROOTFS}/etc/inittab"
cp "${PROJECT_ROOT}/configs/fstab.template" "${ROOTFS}/etc/fstab"
cp -a "${PROJECT_ROOT}/configs/rc.d/"* "${ROOTFS}/etc/rc.d/"
# Live-specific: override inittab for installer mode
cat > "${ROOTFS}/etc/inittab.live" << 'INITTAB'
# DarkForge Live — boots to installer prompt
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l3:3:wait:/etc/rc.d/rc.multi
1:2345:respawn:/sbin/agetty --autologin root --noclear 38400 tty1 linux
2:2345:respawn:/sbin/agetty 38400 tty2 linux
ca::ctrlaltdel:/sbin/shutdown -r now
INITTAB
cp "${ROOTFS}/etc/inittab.live" "${ROOTFS}/etc/inittab"
# Live-specific: auto-launch installer on login
cat > "${ROOTFS}/root/.bash_profile" << 'PROFILE'
echo ""
echo " ╔══════════════════════════════════════════╗"
echo " ║ DarkForge Linux Installer ║"
echo " ║ ║"
echo " ║ Type 'install' to begin installation ║"
echo " ║ Type 'shell' for a live shell ║"
echo " ╚══════════════════════════════════════════╝"
echo ""
alias install='/install/install.sh'
alias shell='exec /bin/bash --login'
PROFILE
# --- Copy installer scripts -------------------------------------------------
info "Copying installer scripts..."
mkdir -p "${ROOTFS}/install"
cp -a "${PROJECT_ROOT}/src/install/"* "${ROOTFS}/install/" 2>/dev/null || true
# Copy dpack binary and repos (for base package installation during install)
mkdir -p "${ROOTFS}/var/lib/dpack/repos"
cp -a "${PROJECT_ROOT}/src/repos/"* "${ROOTFS}/var/lib/dpack/repos/" 2>/dev/null || true
# --- Create the squashfs image ----------------------------------------------
info "Creating squashfs image (${SQFS_COMP})..."
mksquashfs "${ROOTFS}" "${BUILD_DIR}/iso/LiveOS/rootfs.img" \
${SQFS_OPTS} \
-noappend \
-wildcards \
-e 'proc/*' 'sys/*' 'dev/*' 'run/*' 'tmp/*'
ok "squashfs image created: $(du -sh "${BUILD_DIR}/iso/LiveOS/rootfs.img" | cut -f1)"
# --- Prepare EFI boot -------------------------------------------------------
info "Preparing UEFI boot..."
# Create the EFI boot directory structure
mkdir -p "${BUILD_DIR}/iso/EFI/BOOT"
# Copy the kernel as the EFI boot binary
if [ -f "${KERNEL_PATH}" ]; then
cp "${KERNEL_PATH}" "${BUILD_DIR}/iso/EFI/BOOT/BOOTX64.EFI"
ok "Kernel copied to EFI/BOOT/BOOTX64.EFI"
else
warn "No kernel found at ${KERNEL_PATH}"
warn "You'll need to copy the kernel manually before the ISO is bootable."
# Create a placeholder
echo "PLACEHOLDER — replace with real kernel" > "${BUILD_DIR}/iso/EFI/BOOT/BOOTX64.EFI"
fi
# Kernel command line embedded via EFISTUB
# The kernel reads its cmdline from a built-in or from the EFI boot entry
mkdir -p "${BUILD_DIR}/iso/boot"
echo "root=live:LABEL=${ISO_LABEL} rd.live.image rd.live.overlay.overlayfs=1 quiet" \
> "${BUILD_DIR}/iso/boot/cmdline.txt"
# --- Create the EFI System Partition image (for El Torito boot) -------------
info "Creating EFI boot image for ISO..."
ESP_IMG="${BUILD_DIR}/efi/efiboot.img"
# Calculate size needed (kernel + overhead)
KERNEL_SIZE=$(stat -c%s "${BUILD_DIR}/iso/EFI/BOOT/BOOTX64.EFI" 2>/dev/null || echo "1048576")
ESP_SIZE=$(( (KERNEL_SIZE / 1024 + 2048) )) # Add 2MB overhead
[ ${ESP_SIZE} -lt 4096 ] && ESP_SIZE=4096 # Minimum 4MB
dd if=/dev/zero of="${ESP_IMG}" bs=1K count=${ESP_SIZE} 2>/dev/null
mkfs.fat -F 12 "${ESP_IMG}" >/dev/null
mmd -i "${ESP_IMG}" ::/EFI
mmd -i "${ESP_IMG}" ::/EFI/BOOT
mcopy -i "${ESP_IMG}" "${BUILD_DIR}/iso/EFI/BOOT/BOOTX64.EFI" ::/EFI/BOOT/BOOTX64.EFI
ok "EFI boot image created (${ESP_SIZE}K)"
# --- Build the ISO ----------------------------------------------------------
info "Building ISO image..."
xorriso -as mkisofs \
-o "${ISO_OUTPUT}" \
-iso-level 3 \
-full-iso9660-filenames \
-joliet \
-rational-rock \
-volid "${ISO_LABEL}" \
-eltorito-alt-boot \
-e efi/efiboot.img \
-no-emul-boot \
-isohybrid-gpt-basdat \
-append_partition 2 0xef "${ESP_IMG}" \
"${BUILD_DIR}/iso"
# --- Summary ----------------------------------------------------------------
echo ""
ok "═══════════════════════════════════════════════"
ok " DarkForge Linux ISO built successfully!"
ok ""
ok " Output: ${ISO_OUTPUT}"
ok " Size: $(du -sh "${ISO_OUTPUT}" | cut -f1)"
ok ""
ok " Boot: UEFI only (EFISTUB)"
ok " Root: squashfs (${SQFS_COMP})"
ok "═══════════════════════════════════════════════"
echo ""
# --- Cleanup ----------------------------------------------------------------
info "Cleaning up build directory..."
rm -rf "${BUILD_DIR}"
ok "Done."