Wip
This commit is contained in:
80
src/iso/build-initramfs.sh
Executable file
80
src/iso/build-initramfs.sh
Executable file
@@ -0,0 +1,80 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# DarkForge Linux — Build Initramfs for Live ISO
|
||||
# ============================================================================
|
||||
# Creates a minimal initramfs containing busybox and the init script.
|
||||
# The initramfs is used by the live ISO to mount the squashfs root.
|
||||
#
|
||||
# Output: src/iso/initramfs.cpio.gz (embedded in the ISO alongside the kernel)
|
||||
#
|
||||
# Usage:
|
||||
# bash src/iso/build-initramfs.sh
|
||||
# ============================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
|
||||
INITRAMFS_DIR=$(mktemp -d /tmp/darkforge-initramfs-XXXXX)
|
||||
OUTPUT="${SCRIPT_DIR}/initramfs.cpio.gz"
|
||||
|
||||
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; }
|
||||
|
||||
info "Building DarkForge initramfs..."
|
||||
|
||||
# Create directory structure
|
||||
mkdir -p "${INITRAMFS_DIR}"/{bin,sbin,dev,proc,sys,media,rootfs,overlay,tmpfs,newroot,etc,tmp}
|
||||
|
||||
# Find busybox
|
||||
BUSYBOX=""
|
||||
if command -v busybox >/dev/null 2>&1; then
|
||||
BUSYBOX="$(which busybox)"
|
||||
elif [ -f /usr/bin/busybox ]; then
|
||||
BUSYBOX="/usr/bin/busybox"
|
||||
fi
|
||||
|
||||
if [ -z "$BUSYBOX" ]; then
|
||||
die "busybox not found — install with: sudo pacman -S busybox"
|
||||
fi
|
||||
|
||||
# Copy busybox and create symlinks for all needed applets
|
||||
cp "$BUSYBOX" "${INITRAMFS_DIR}/bin/busybox"
|
||||
chmod +x "${INITRAMFS_DIR}/bin/busybox"
|
||||
|
||||
# Create symlinks for commands used by the init script
|
||||
for cmd in sh mount umount mkdir echo sleep cat switch_root exec \
|
||||
mount.squashfs losetup mdev modprobe; do
|
||||
ln -sf busybox "${INITRAMFS_DIR}/bin/$cmd"
|
||||
done
|
||||
|
||||
# switch_root is typically in /sbin
|
||||
ln -sf ../bin/busybox "${INITRAMFS_DIR}/sbin/switch_root"
|
||||
|
||||
# Copy the init script
|
||||
cp "${SCRIPT_DIR}/initramfs/init" "${INITRAMFS_DIR}/init"
|
||||
chmod +x "${INITRAMFS_DIR}/init"
|
||||
|
||||
# Create essential device nodes
|
||||
mknod -m 622 "${INITRAMFS_DIR}/dev/console" c 5 1 2>/dev/null || true
|
||||
mknod -m 666 "${INITRAMFS_DIR}/dev/null" c 1 3 2>/dev/null || true
|
||||
mknod -m 666 "${INITRAMFS_DIR}/dev/zero" c 1 5 2>/dev/null || true
|
||||
mknod -m 666 "${INITRAMFS_DIR}/dev/tty" c 5 0 2>/dev/null || true
|
||||
|
||||
# Create the cpio archive
|
||||
info "Creating cpio archive..."
|
||||
cd "${INITRAMFS_DIR}"
|
||||
find . -print0 | cpio --null --create --format=newc 2>/dev/null | gzip -9 > "$OUTPUT"
|
||||
|
||||
# Cleanup
|
||||
rm -rf "${INITRAMFS_DIR}"
|
||||
|
||||
SIZE=$(du -h "$OUTPUT" | cut -f1)
|
||||
ok "Initramfs created: ${OUTPUT} (${SIZE})"
|
||||
echo ""
|
||||
echo " To use with the ISO:"
|
||||
echo " The build-iso-arch.sh script will automatically include this initramfs."
|
||||
echo ""
|
||||
@@ -210,6 +210,19 @@ done
|
||||
chmod -R a+rX "${ROOTFS}/var/lib/dpack/repos/"
|
||||
ls -la "${ROOTFS}/var/lib/dpack/repos/" || true
|
||||
|
||||
# --- Build initramfs for live boot -------------------------------------------
|
||||
INITRAMFS_PATH="${SCRIPT_DIR}/initramfs.cpio.gz"
|
||||
if [ ! -f "$INITRAMFS_PATH" ]; then
|
||||
info "Building initramfs..."
|
||||
bash "${SCRIPT_DIR}/build-initramfs.sh"
|
||||
fi
|
||||
|
||||
if [ -f "$INITRAMFS_PATH" ]; then
|
||||
ok "Initramfs: ${INITRAMFS_PATH} ($(du -h "$INITRAMFS_PATH" | cut -f1))"
|
||||
else
|
||||
warn "No initramfs — live ISO will not be able to mount squashfs root"
|
||||
fi
|
||||
|
||||
# --- Install kernel ----------------------------------------------------------
|
||||
KERNEL_PATH=""
|
||||
for kp in "${PROJECT_ROOT}/kernel/vmlinuz" "${PROJECT_ROOT}/build/vmlinuz" /boot/vmlinuz-linux; do
|
||||
@@ -220,8 +233,15 @@ for kp in "${PROJECT_ROOT}/kernel/vmlinuz" "${PROJECT_ROOT}/build/vmlinuz" /boot
|
||||
done
|
||||
|
||||
if [ -n "$KERNEL_PATH" ]; then
|
||||
# Copy kernel to ISO
|
||||
cp "$KERNEL_PATH" "${ISO_DIR}/EFI/BOOT/BOOTX64.EFI"
|
||||
ok "Kernel: ${KERNEL_PATH}"
|
||||
|
||||
# Also copy initramfs alongside kernel in the ISO
|
||||
if [ -f "$INITRAMFS_PATH" ]; then
|
||||
cp "$INITRAMFS_PATH" "${ISO_DIR}/LiveOS/initramfs.img"
|
||||
ok "Initramfs copied to ISO"
|
||||
fi
|
||||
else
|
||||
warn "No kernel found — ISO will not be bootable!"
|
||||
warn "Build the kernel first (Phase 4) or copy vmlinuz to kernel/vmlinuz"
|
||||
@@ -241,12 +261,34 @@ ok "squashfs: $(du -sh "${ISO_DIR}/LiveOS/rootfs.img" | cut -f1)"
|
||||
info "Creating EFI boot image..."
|
||||
# efiboot.img MUST be inside ISO_DIR so xorriso can find it via -e flag
|
||||
ESP_IMG="${ISO_DIR}/efiboot.img"
|
||||
ESP_SIZE=8192 # 8MB
|
||||
# Size the ESP large enough for kernel + initramfs
|
||||
KERNEL_SIZE=$(stat -c%s "${ISO_DIR}/EFI/BOOT/BOOTX64.EFI" 2>/dev/null || echo "1048576")
|
||||
INITRD_SIZE=0
|
||||
if [ -f "${ISO_DIR}/LiveOS/initramfs.img" ]; then
|
||||
INITRD_SIZE=$(stat -c%s "${ISO_DIR}/LiveOS/initramfs.img")
|
||||
fi
|
||||
# ESP size: kernel + initramfs + 4MB padding, minimum 8MB
|
||||
ESP_SIZE=$(( (KERNEL_SIZE + INITRD_SIZE + 4194304) / 1024 ))
|
||||
[ "$ESP_SIZE" -lt 8192 ] && ESP_SIZE=8192
|
||||
|
||||
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 ::/EFI/BOOT
|
||||
mcopy -i "${ESP_IMG}" "${ISO_DIR}/EFI/BOOT/BOOTX64.EFI" ::/EFI/BOOT/BOOTX64.EFI
|
||||
|
||||
# Include initramfs in the EFI partition if available
|
||||
if [ -f "${ISO_DIR}/LiveOS/initramfs.img" ]; then
|
||||
mcopy -i "${ESP_IMG}" "${ISO_DIR}/LiveOS/initramfs.img" ::/EFI/BOOT/initramfs.img
|
||||
# Create a startup.nsh script for UEFI shell fallback
|
||||
STARTUP_NSH=$(mktemp)
|
||||
echo '\EFI\BOOT\BOOTX64.EFI initrd=\EFI\BOOT\initramfs.img' > "$STARTUP_NSH"
|
||||
mcopy -i "${ESP_IMG}" "$STARTUP_NSH" ::/startup.nsh
|
||||
rm -f "$STARTUP_NSH"
|
||||
ok "EFI boot image includes kernel + initramfs (ESP: $((ESP_SIZE/1024))MB)"
|
||||
else
|
||||
ok "EFI boot image: kernel only (no initramfs)"
|
||||
fi
|
||||
|
||||
# --- Build ISO ----------------------------------------------------------------
|
||||
info "Building ISO..."
|
||||
xorriso -as mkisofs \
|
||||
|
||||
101
src/iso/initramfs/init
Executable file
101
src/iso/initramfs/init
Executable file
@@ -0,0 +1,101 @@
|
||||
#!/bin/sh
|
||||
# ============================================================================
|
||||
# DarkForge Linux — Live ISO Initramfs Init Script
|
||||
# ============================================================================
|
||||
# This script runs as PID 1 from the initramfs during live ISO boot.
|
||||
# It finds the ISO media, mounts the squashfs, sets up an overlay, and
|
||||
# switch_roots into the live system.
|
||||
#
|
||||
# Boot flow:
|
||||
# UEFI → EFISTUB kernel → initramfs (this script) → switch_root → /sbin/init
|
||||
# ============================================================================
|
||||
|
||||
# Mount essential virtual filesystems
|
||||
mount -t proc none /proc
|
||||
mount -t sysfs none /sys
|
||||
mount -t devtmpfs none /dev
|
||||
|
||||
# Enable kernel messages on console
|
||||
echo 1 > /proc/sys/kernel/printk
|
||||
|
||||
echo ""
|
||||
echo " DarkForge Linux — Live Boot"
|
||||
echo " Searching for installation media..."
|
||||
echo ""
|
||||
|
||||
# Wait for devices to settle
|
||||
sleep 2
|
||||
|
||||
# Try to find the DarkForge ISO media
|
||||
# The ISO has a LiveOS/rootfs.img squashfs file
|
||||
MEDIA_FOUND=0
|
||||
MEDIA_MNT="/media"
|
||||
ROOTFS_MNT="/rootfs"
|
||||
OVERLAY_MNT="/overlay"
|
||||
|
||||
mkdir -p "$MEDIA_MNT" "$ROOTFS_MNT" "$OVERLAY_MNT"
|
||||
|
||||
# Check CD-ROM devices and USB drives
|
||||
for attempt in 1 2 3 4 5; do
|
||||
for dev in /dev/sr0 /dev/sr1 /dev/sda /dev/sda1 /dev/sdb /dev/sdb1 \
|
||||
/dev/nvme0n1p1 /dev/nvme1n1p1 /dev/vda /dev/vda1; do
|
||||
[ -b "$dev" ] || continue
|
||||
|
||||
if mount -o ro "$dev" "$MEDIA_MNT" 2>/dev/null; then
|
||||
if [ -f "$MEDIA_MNT/LiveOS/rootfs.img" ]; then
|
||||
echo " Found DarkForge media on ${dev}"
|
||||
MEDIA_FOUND=1
|
||||
break 2
|
||||
fi
|
||||
umount "$MEDIA_MNT" 2>/dev/null
|
||||
fi
|
||||
done
|
||||
echo " Attempt ${attempt}/5 — waiting for devices..."
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ "$MEDIA_FOUND" -eq 0 ]; then
|
||||
echo ""
|
||||
echo " ERROR: Could not find DarkForge installation media!"
|
||||
echo " Make sure the ISO is written to a USB drive or mounted as CD-ROM."
|
||||
echo ""
|
||||
echo " Dropping to emergency shell..."
|
||||
exec /bin/sh
|
||||
fi
|
||||
|
||||
# Mount the squashfs root filesystem
|
||||
echo " Mounting squashfs root filesystem..."
|
||||
if ! mount -t squashfs -o ro "$MEDIA_MNT/LiveOS/rootfs.img" "$ROOTFS_MNT" 2>/dev/null; then
|
||||
echo " ERROR: Failed to mount squashfs!"
|
||||
echo " Dropping to emergency shell..."
|
||||
exec /bin/sh
|
||||
fi
|
||||
|
||||
# Set up tmpfs overlay for writable root
|
||||
echo " Setting up writable overlay..."
|
||||
mkdir -p /tmpfs
|
||||
mount -t tmpfs -o size=75% tmpfs /tmpfs
|
||||
mkdir -p /tmpfs/upper /tmpfs/work
|
||||
|
||||
# Mount overlayfs: squashfs (read-only lower) + tmpfs (writable upper)
|
||||
mkdir -p /newroot
|
||||
if mount -t overlay overlay -o "lowerdir=${ROOTFS_MNT},upperdir=/tmpfs/upper,workdir=/tmpfs/work" /newroot 2>/dev/null; then
|
||||
echo " Overlay root mounted (squashfs + tmpfs)"
|
||||
else
|
||||
# Fallback: if overlay not available, bind-mount the squashfs directly
|
||||
echo " WARNING: overlayfs not available, root will be read-only"
|
||||
mount --bind "$ROOTFS_MNT" /newroot
|
||||
fi
|
||||
|
||||
# Move virtual filesystems into the new root
|
||||
mkdir -p /newroot/proc /newroot/sys /newroot/dev /newroot/media
|
||||
mount --move /proc /newroot/proc
|
||||
mount --move /sys /newroot/sys
|
||||
mount --move /dev /newroot/dev
|
||||
mount --move "$MEDIA_MNT" /newroot/media
|
||||
|
||||
echo " Switching to live root filesystem..."
|
||||
echo ""
|
||||
|
||||
# Switch to the real root and exec init
|
||||
exec switch_root /newroot /sbin/init
|
||||
Reference in New Issue
Block a user