#!/usr/bin/env bash # make-generic-kernel.sh # # Build a minimal Firecracker-optimized vmlinux from upstream kernel.org # sources using the vendored Firecracker config. All essential drivers # (virtio_blk, virtio_net, ext4, vsock) are compiled in — no modules, # no initramfs needed. The result boots any OCI-pulled rootfs directly. # # Usage: # scripts/make-generic-kernel.sh [--version 6.12.8] # # Output: # build/manual/generic-kernel/boot/vmlinux- # build/manual/generic-kernel/metadata.json set -euo pipefail log() { printf '[make-generic-kernel] %s\n' "$*" >&2; } SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" OUT_DIR="${BANGER_MANUAL_DIR:-$REPO_ROOT/build/manual}/generic-kernel" CONFIG="$REPO_ROOT/configs/firecracker-x86_64-6.1.config" KERNEL_VERSION="${KERNEL_VERSION:-6.12.8}" KERNEL_MAJOR="${KERNEL_VERSION%%.*}" JOBS="${JOBS:-$(nproc)}" usage() { cat <] Downloads kernel from kernel.org, applies the vendored Firecracker config, and builds a minimal vmlinux. Default version: $KERNEL_VERSION Output: $OUT_DIR/boot/vmlinux- EOF } while [[ $# -gt 0 ]]; do case "$1" in --version) KERNEL_VERSION="$2"; KERNEL_MAJOR="${KERNEL_VERSION%%.*}"; shift 2;; -h|--help) usage; exit 0;; *) log "unknown arg: $1"; exit 1;; esac done for tool in curl tar make gcc; do command -v "$tool" >/dev/null 2>&1 || { log "missing required tool: $tool"; exit 1; } done [[ -f "$CONFIG" ]] || { log "config not found: $CONFIG"; exit 1; } TARBALL="linux-${KERNEL_VERSION}.tar.xz" URL="https://cdn.kernel.org/pub/linux/kernel/v${KERNEL_MAJOR}.x/$TARBALL" SRC_DIR="$(mktemp -d)" trap 'rm -rf "$SRC_DIR"' EXIT log "downloading kernel $KERNEL_VERSION from $URL" curl -fSL --progress-bar -o "$SRC_DIR/$TARBALL" "$URL" log "extracting" tar -xf "$SRC_DIR/$TARBALL" -C "$SRC_DIR" --strip-components=1 log "applying firecracker config" cp "$CONFIG" "$SRC_DIR/.config" # Adapt the 6.1 config to whatever version we're building. make olddefconfig # fills in any new symbols with defaults. make -C "$SRC_DIR" olddefconfig >/dev/null 2>&1 log "building vmlinux (jobs=$JOBS)" make -C "$SRC_DIR" -j"$JOBS" vmlinux 2>&1 | tail -5 VMLINUX="$SRC_DIR/vmlinux" if [[ ! -f "$VMLINUX" ]]; then log "vmlinux not found after build; check build output above" exit 1 fi mkdir -p "$OUT_DIR/boot" DEST="$OUT_DIR/boot/vmlinux-${KERNEL_VERSION}" cp "$VMLINUX" "$DEST" log "verifying: $(file -b "$DEST" | head -c 80)" cat > "$OUT_DIR/metadata.json" <