#!/bin/sh # build-nvidia-module.sh — install NVIDIA proprietary driver into ISO overlay # # Downloads the official NVIDIA .run installer, extracts kernel modules and # userspace tools (nvidia-smi, libnvidia-ml). Everything is proprietary NVIDIA. # # Output is cached in DIST_DIR/nvidia--/ so subsequent builds # are instant unless NVIDIA_DRIVER_VERSION or kernel version changes. # # Output layout: # $CACHE_DIR/modules/ — nvidia*.ko files # $CACHE_DIR/bin/ — nvidia-smi, nvidia-debugdump # $CACHE_DIR/lib/ — libnvidia-ml.so*, libcuda.so* (for nvidia-smi) set -e NVIDIA_VERSION="$1" DIST_DIR="$2" [ -n "$NVIDIA_VERSION" ] || { echo "usage: $0 "; exit 1; } [ -n "$DIST_DIR" ] || { echo "usage: $0 "; exit 1; } # Detect kernel version from installed headers KVER=$(ls /usr/src/ 2>/dev/null | grep '^linux-headers-' | sed 's/linux-headers-//' | head -1) if [ -z "$KVER" ]; then echo "=== installing linux-lts-dev ===" apk add --quiet linux-lts-dev KVER=$(ls /usr/src/ | grep '^linux-headers-' | sed 's/linux-headers-//' | head -1) fi KDIR="/usr/src/linux-headers-${KVER}" echo "=== NVIDIA ${NVIDIA_VERSION} (proprietary) for kernel ${KVER} ===" CACHE_DIR="${DIST_DIR}/nvidia-${NVIDIA_VERSION}-${KVER}" if [ -d "$CACHE_DIR/modules" ] && [ -f "$CACHE_DIR/bin/nvidia-smi" ]; then echo "=== NVIDIA cached, skipping build ===" echo "cache: $CACHE_DIR" echo "modules: $(ls "$CACHE_DIR/modules/"*.ko 2>/dev/null | wc -l) .ko files" exit 0 fi # Install build dependencies apk add --quiet gcc make perl linux-lts-dev wget # Download official NVIDIA .run installer (proprietary) RUN_FILE="/var/tmp/NVIDIA-Linux-x86_64-${NVIDIA_VERSION}.run" if [ ! -f "$RUN_FILE" ]; then echo "=== downloading NVIDIA ${NVIDIA_VERSION} installer ===" wget -q --show-progress \ -O "$RUN_FILE" \ "https://download.nvidia.com/XFree86/Linux-x86_64/${NVIDIA_VERSION}/NVIDIA-Linux-x86_64-${NVIDIA_VERSION}.run" fi # Extract installer contents echo "=== extracting installer ===" chmod +x "$RUN_FILE" EXTRACT_DIR="/var/tmp/nvidia-extract-${NVIDIA_VERSION}" rm -rf "$EXTRACT_DIR" "$RUN_FILE" --extract-only --target "$EXTRACT_DIR" # Build kernel modules from extracted source echo "=== building kernel modules ($(nproc) cores) ===" cd "$EXTRACT_DIR/kernel" make -j$(nproc) KERNEL_UNAME="$KVER" SYSSRC="$KDIR" modules 2>&1 | tail -5 # Collect outputs mkdir -p "$CACHE_DIR/modules" "$CACHE_DIR/bin" "$CACHE_DIR/lib" find "$EXTRACT_DIR/kernel" -name '*.ko' -exec cp {} "$CACHE_DIR/modules/" \; for ko in "$CACHE_DIR/modules/"*.ko; do strip --strip-debug "$ko" 2>/dev/null || true done cp "$EXTRACT_DIR/nvidia-smi" "$CACHE_DIR/bin/" cp "$EXTRACT_DIR/libnvidia-ml.so."* "$CACHE_DIR/lib/" 2>/dev/null || true # libcuda stub needed by nvidia-smi at runtime cp "$EXTRACT_DIR/libcuda.so."* "$CACHE_DIR/lib/" 2>/dev/null || true echo "=== NVIDIA build complete ===" echo "cache: $CACHE_DIR" echo "modules: $(ls "$CACHE_DIR/modules/"*.ko | wc -l) .ko files" ls -lh "$CACHE_DIR/bin/"