Wip
This commit is contained in:
227
kernel/build-kernel.sh
Executable file
227
kernel/build-kernel.sh
Executable file
@@ -0,0 +1,227 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# DarkForge Linux — Kernel Build Script
|
||||
# ============================================================================
|
||||
# Downloads, configures, and compiles the Linux kernel for DarkForge.
|
||||
#
|
||||
# Prerequisites (Arch Linux):
|
||||
# sudo pacman -S base-devel bc flex bison libelf perl openssl
|
||||
#
|
||||
# Usage:
|
||||
# cd /path/to/project-root
|
||||
# bash kernel/build-kernel.sh
|
||||
#
|
||||
# Output:
|
||||
# kernel/vmlinuz — Compressed kernel (bzImage)
|
||||
# kernel/vmlinuz.efi — Copy with .efi extension for EFISTUB
|
||||
# kernel/System.map — Symbol map
|
||||
# kernel/modules/ — Kernel modules (if any)
|
||||
# build/linux-<version>/ — Full kernel source tree (for module builds)
|
||||
#
|
||||
# Notes:
|
||||
# - Runs as regular user (no sudo needed for compile)
|
||||
# - Uses the config at kernel/config
|
||||
# - Applies 'make olddefconfig' to fill in defaults for unspecified options
|
||||
# - Builds with -j32 (16C/32T)
|
||||
# ============================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
|
||||
# --- Configuration -----------------------------------------------------------
|
||||
KERNEL_VERSION="6.19.9"
|
||||
KERNEL_MAJOR="6.19"
|
||||
KERNEL_URL="https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${KERNEL_VERSION}.tar.xz"
|
||||
KERNEL_SIGN_URL="${KERNEL_URL}.sign"
|
||||
BUILD_DIR="${PROJECT_ROOT}/build"
|
||||
KERNEL_SRC="${BUILD_DIR}/linux-${KERNEL_VERSION}"
|
||||
CONFIG_FILE="${SCRIPT_DIR}/config"
|
||||
JOBS=32
|
||||
|
||||
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 ---------------------------------------------------------------
|
||||
info "DarkForge Kernel Builder — Linux ${KERNEL_VERSION}"
|
||||
echo ""
|
||||
|
||||
# Check required tools
|
||||
for tool in gcc make flex bison bc perl; do
|
||||
command -v "$tool" >/dev/null 2>&1 || die "Missing: $tool — install with pacman"
|
||||
done
|
||||
|
||||
# Check for libelf headers (needed for CONFIG_BPF_SYSCALL, etc.)
|
||||
if ! pkg-config --exists libelf 2>/dev/null; then
|
||||
warn "libelf not found — install with: sudo pacman -S libelf"
|
||||
warn "Continuing anyway (may fail if CONFIG_BPF_SYSCALL=y)"
|
||||
fi
|
||||
|
||||
# Check for openssl headers (needed for module signing)
|
||||
if ! pkg-config --exists openssl 2>/dev/null && ! [ -f /usr/include/openssl/opensslv.h ]; then
|
||||
warn "OpenSSL headers not found — install with: sudo pacman -S openssl"
|
||||
fi
|
||||
|
||||
# --- Download kernel source --------------------------------------------------
|
||||
mkdir -p "${BUILD_DIR}"
|
||||
|
||||
TARBALL="${BUILD_DIR}/linux-${KERNEL_VERSION}.tar.xz"
|
||||
if [ -f "$TARBALL" ]; then
|
||||
info "Kernel tarball already downloaded: ${TARBALL}"
|
||||
else
|
||||
info "Downloading Linux ${KERNEL_VERSION}..."
|
||||
# Try cdn.kernel.org first, then mirrors
|
||||
for url in \
|
||||
"https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${KERNEL_VERSION}.tar.xz" \
|
||||
"https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-${KERNEL_VERSION}.tar.xz" \
|
||||
"https://mirror.aarnet.edu.au/pub/ftp.kernel.org/linux/kernel/v6.x/linux-${KERNEL_VERSION}.tar.xz"; do
|
||||
if curl --connect-timeout 15 -fL# -o "$TARBALL" "$url" 2>&1; then
|
||||
ok "Downloaded from ${url}"
|
||||
break
|
||||
else
|
||||
warn "Failed: ${url}"
|
||||
rm -f "$TARBALL"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
[ -f "$TARBALL" ] || die "Failed to download kernel tarball"
|
||||
|
||||
# Verify tarball is valid
|
||||
if ! xz -t "$TARBALL" 2>/dev/null; then
|
||||
die "Kernel tarball is corrupt — delete ${TARBALL} and re-run"
|
||||
fi
|
||||
|
||||
# --- Extract kernel source ---------------------------------------------------
|
||||
if [ -d "$KERNEL_SRC" ] && [ -f "$KERNEL_SRC/Makefile" ]; then
|
||||
info "Kernel source already extracted: ${KERNEL_SRC}"
|
||||
else
|
||||
info "Extracting Linux ${KERNEL_VERSION}..."
|
||||
tar -xf "$TARBALL" -C "${BUILD_DIR}"
|
||||
[ -d "$KERNEL_SRC" ] || die "Expected directory ${KERNEL_SRC} not found after extraction"
|
||||
ok "Extracted to ${KERNEL_SRC}"
|
||||
fi
|
||||
|
||||
# --- Apply DarkForge config --------------------------------------------------
|
||||
info "Applying DarkForge kernel config..."
|
||||
|
||||
# Copy our config
|
||||
cp "$CONFIG_FILE" "${KERNEL_SRC}/.config"
|
||||
|
||||
# Update version target in config header comment (informational only)
|
||||
# The actual version comes from the kernel source, not the config
|
||||
|
||||
# Run olddefconfig to fill in all unspecified options with defaults
|
||||
# This is critical — our config only specifies ~176 options out of thousands
|
||||
cd "$KERNEL_SRC"
|
||||
make olddefconfig
|
||||
|
||||
ok "Config applied — $(grep -c '=y\|=m' .config) options enabled"
|
||||
|
||||
# Verify critical options survived olddefconfig
|
||||
CRITICAL_OPTS=(
|
||||
"CONFIG_EFI_STUB=y"
|
||||
"CONFIG_BLK_DEV_NVME=y"
|
||||
"CONFIG_EXT4_FS=y"
|
||||
"CONFIG_PREEMPT=y"
|
||||
"CONFIG_MODULES=y"
|
||||
"CONFIG_DRM=y"
|
||||
"CONFIG_R8169=y"
|
||||
"CONFIG_EFI=y"
|
||||
)
|
||||
FAIL=0
|
||||
for opt in "${CRITICAL_OPTS[@]}"; do
|
||||
key="${opt%%=*}"
|
||||
if ! grep -q "^${opt}$" .config; then
|
||||
warn "CRITICAL: ${opt} not set in final config!"
|
||||
FAIL=1
|
||||
fi
|
||||
done
|
||||
if [ "$FAIL" -eq 1 ]; then
|
||||
die "Critical config options missing after olddefconfig — review .config"
|
||||
fi
|
||||
ok "All critical config options verified"
|
||||
|
||||
# --- Compile -----------------------------------------------------------------
|
||||
info "Compiling Linux ${KERNEL_VERSION} with -j${JOBS}..."
|
||||
info "This will take a few minutes on 16C/32T..."
|
||||
echo ""
|
||||
|
||||
# Set DarkForge compiler flags for kernel build
|
||||
# Note: kernel has its own CFLAGS handling; -march is passed via KCFLAGS
|
||||
# The kernel's CONFIG_MZEN4 handles most CPU-specific codegen
|
||||
KCFLAGS="-march=znver4 -pipe"
|
||||
# znver4 because znver5 may not be fully supported by all kernel assembly
|
||||
# TODO: test znver5 when compiler+kernel support is confirmed
|
||||
|
||||
START_TIME=$(date +%s)
|
||||
|
||||
make -j${JOBS} KCFLAGS="$KCFLAGS" bzImage 2>&1 | tail -20
|
||||
|
||||
END_TIME=$(date +%s)
|
||||
ELAPSED=$((END_TIME - START_TIME))
|
||||
|
||||
if [ -f "arch/x86/boot/bzImage" ]; then
|
||||
ok "Kernel compiled in ${ELAPSED}s"
|
||||
else
|
||||
die "Kernel compilation failed — check output above"
|
||||
fi
|
||||
|
||||
# Build modules (for any =m options)
|
||||
info "Building kernel modules..."
|
||||
make -j${JOBS} modules 2>&1 | tail -5
|
||||
ok "Modules built"
|
||||
|
||||
# --- Install outputs ---------------------------------------------------------
|
||||
info "Installing kernel outputs..."
|
||||
|
||||
# Copy bzImage
|
||||
cp arch/x86/boot/bzImage "${SCRIPT_DIR}/vmlinuz"
|
||||
cp arch/x86/boot/bzImage "${SCRIPT_DIR}/vmlinuz.efi"
|
||||
ok "Kernel: ${SCRIPT_DIR}/vmlinuz ($(du -h "${SCRIPT_DIR}/vmlinuz" | cut -f1))"
|
||||
|
||||
# Copy System.map
|
||||
cp System.map "${SCRIPT_DIR}/System.map"
|
||||
|
||||
# Install modules to a staging directory
|
||||
MODULES_DIR="${SCRIPT_DIR}/modules"
|
||||
rm -rf "$MODULES_DIR"
|
||||
make INSTALL_MOD_PATH="$MODULES_DIR" modules_install 2>&1 | tail -3
|
||||
ok "Modules installed to ${MODULES_DIR}"
|
||||
|
||||
# Verify the kernel is a valid EFI application
|
||||
if file "${SCRIPT_DIR}/vmlinuz" | grep -q "bzImage"; then
|
||||
ok "Kernel is a valid bzImage"
|
||||
elif file "${SCRIPT_DIR}/vmlinuz" | grep -q "EFI\|PE32"; then
|
||||
ok "Kernel is a valid EFI binary"
|
||||
else
|
||||
warn "Kernel type: $(file "${SCRIPT_DIR}/vmlinuz")"
|
||||
warn "May not boot via EFISTUB — verify manually"
|
||||
fi
|
||||
|
||||
# --- Summary -----------------------------------------------------------------
|
||||
echo ""
|
||||
echo "============================================================================"
|
||||
echo -e "${GREEN} DarkForge Kernel Build Complete${NC}"
|
||||
echo "============================================================================"
|
||||
echo ""
|
||||
echo " Version: Linux ${KERNEL_VERSION}-darkforge"
|
||||
echo " Kernel: ${SCRIPT_DIR}/vmlinuz"
|
||||
echo " Kernel EFI: ${SCRIPT_DIR}/vmlinuz.efi"
|
||||
echo " System.map: ${SCRIPT_DIR}/System.map"
|
||||
echo " Modules: ${MODULES_DIR}/"
|
||||
echo " Source: ${KERNEL_SRC}/"
|
||||
echo ""
|
||||
echo " Compile time: ${ELAPSED}s"
|
||||
echo " Kernel size: $(du -h "${SCRIPT_DIR}/vmlinuz" | cut -f1)"
|
||||
echo ""
|
||||
echo " Next steps:"
|
||||
echo " 1. Rebuild ISO: sudo bash src/iso/build-iso-arch.sh"
|
||||
echo " 2. Test in QEMU: see tests/run-tests.sh"
|
||||
echo " 3. For real hardware: copy vmlinuz.efi to ESP as /EFI/Linux/vmlinuz.efi"
|
||||
echo ""
|
||||
echo "============================================================================"
|
||||
Reference in New Issue
Block a user