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:
57
src/iso/README.md
Normal file
57
src/iso/README.md
Normal 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
215
src/iso/build-iso.sh
Executable 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."
|
||||
Reference in New Issue
Block a user