From 0ec96390307a0d3c5e0f82d6a4698a105083caf4 Mon Sep 17 00:00:00 2001 From: stornic56 <71296607+stornic56@users.noreply.github.com> Date: Wed, 5 Aug 2026 01:25:26 -0500 Subject: [PATCH] nvidia driver stability & version menu - Refactored NVIDIA installation with robust DKMS verification (`_verify_nvidia_dkms_build`). Automatically detects build failures for the current kernel and repairs them via `dpkg-reconfigure`, ensuring modules compile against active kernels without manual intervention. - Added Secure Boot detection (`_nvidia_secure_boot_enabled`) to warn users if the NVIDIA module is compiled but unsigned, preventing boot issues on systems with UEFI security enabled. - Implemented `_configure_nvidia_wayland()` for Wayland support. Detects hybrid laptops (Optimus) vs desktops using DMI chassis types and battery presence. Configures `NVreg_PreserveVideoMemoryAllocations` only for desktops to avoid Optimus conflicts, and adds architecture-specific guards (e.g., Kepler warnings). - Introduced version selection menu (`_show_nvidia_version_menu`). Users can select driver versions (470/535/550/590/595) based on Debian release. Parametrized CUDA repo installation for 590/595 with post-install DKMS branch verification. - Fixed state inconsistency bugs in `NVIDIA_DRIVER_MODE`. Added guards to ensure configuration files are only written upon successful installation, preventing partial setups after failures (e.g., backports, CUDA repo). - Improved hardware detection helpers (`_is_hybrid_laptop`, `_get_nvidia_arch_family`). Prevents false positives on multi-GPU desktops by verifying iGPU presence alongside dGPU. - Updated Java/Minecraft support in `modules/extras/java.sh`. Added Temurin 25 ("Minecraft 26+") to the runtime selection menu and updated documentation. - Enhanced utility robustness (`_run_cmd`, `_configure_lightdm`). Properly propagates exit codes from commands and handles failures gracefully (yellow warnings + skip) instead of crashing under `set -e`. --- debianito.sh | 1 + docs/gaming.md | 9 +- modules/extras/java.sh | 5 +- modules/gpu.sh | 140 +++++++++++----- modules/gpu/_helpers.sh | 36 +++++ modules/gpu/nvidia.sh | 348 ++++++++++++++++++++++++++++++---------- modules/utils.sh | 12 +- 7 files changed, 415 insertions(+), 136 deletions(-) diff --git a/debianito.sh b/debianito.sh index 0aa5c22..ae2a47b 100644 --- a/debianito.sh +++ b/debianito.sh @@ -5,6 +5,7 @@ set -euo pipefail RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' +CYAN='\033[0;36m' NC='\033[0m' # TUI dimensions — fixed centered size for whiptail dialogs diff --git a/docs/gaming.md b/docs/gaming.md index 7de9b6f..1eb95da 100644 --- a/docs/gaming.md +++ b/docs/gaming.md @@ -106,15 +106,16 @@ This approach eliminates the security risk of running OpenRGB as root while main --- -### 5. Java Runtimes (Eclipse Temurin 8 / 17 / 21) +### 5. Java Runtimes (Eclipse Temurin 8 / 17 / 21 / 25) -**Multi-Version Support:** The gaming module provides three specific Eclipse Temurin versions to accommodate different game requirements: +**Multi-Version Support:** The gaming module provides four specific Eclipse Temurin versions to accommodate different game requirements: | Version | Use Case | Justification | |---------|----------|---------------| | **Temurin 8** | Legacy Minecraft mods, older Java games | Maintains compatibility with mods written for Java 8 (2014-2019 era) | | **Temurin 17** | Modern Minecraft servers, newer game clients | Balances performance and compatibility for post-1.16+ game versions | | **Temurin 21** | Latest game engines, cutting-edge mods | Provides best performance for modern Java applications | +| **Temurin 25** | Minecraft 26+ and latest game engines | Best performance for the newest Java applications | **Repository Management via extrepo:** The script leverages the `extrepo` utility to manage external repositories cleanly rather than manually injecting repository URLs into system files. This approach offers several advantages: @@ -122,13 +123,13 @@ This approach eliminates the security risk of running OpenRGB as root while main 2. **Dependency Resolution:** The utility checks for its own installation and handles the enabling of the Adoptium Temurin repository before proceeding with package installation. 3. **Maintenance Safety:** Updates to the upstream repository are reflected through `extrepo` without requiring direct edits to system configuration files, reducing the risk of breakage during OS updates. -**Version Selection Logic:** Users can choose which Temurin version to install based on their specific game requirements via a TUI menu (`install_minecraft_java()`). The module justifies offering all three versions because: +**Version Selection Logic:** Users can choose which Temurin version to install based on their specific game requirements via a TUI menu (`install_minecraft_java()`). The module justifies offering all four versions because: 1. **Backward Compatibility:** Java 8 remains in use by many Minecraft mods and older game clients that haven't been updated for newer JVMs 2. **Performance Optimization:** Java 21 provides the best performance characteristics for modern games with heavy multithreading requirements 3. **Security Updates:** All Temurin versions receive regular security patches from the Eclipse Foundation community -The installation process ensures clean repository management without polluting the system with multiple conflicting JRE installations, maintaining Debian's package integrity while providing flexibility for different gaming scenarios. It automatically installs `extrepo` if not present and enables the Adoptium source before proceeding with version-specific packages (e.g., `temurin-8-jre`, `temurin-17-jre`). +The installation process ensures clean repository management without polluting the system with multiple conflicting JRE installations, maintaining Debian's package integrity while providing flexibility for different gaming scenarios. It automatically installs `extrepo` if not present and enables the Adoptium source before proceeding with version-specific packages (e.g., `temurin-8-jre`, `temurin-17-jre`, `temurin-25-jre`). ### References: diff --git a/modules/extras/java.sh b/modules/extras/java.sh index 90f0c7c..e9c215a 100644 --- a/modules/extras/java.sh +++ b/modules/extras/java.sh @@ -16,10 +16,11 @@ _enable_temurin_repo() { install_minecraft_java() { local choices choices=$(_checklist "Java Runtimes for Minecraft" \ - "Select Java version(s) to install:" 14 65 3 \ + "Select Java version(s) to install:" 15 65 4 \ "8" "Java 8 — Classic mods & Minecraft <= 1.16.5" OFF \ "17" "Java 17 — Minecraft 1.17 to 1.20.4" ON \ - "21" "Java 21 — Modern Minecraft >= 1.20.5 & 1.21+" OFF) + "21" "Java 21 — Modern Minecraft >= 1.20.5 & 1.21+" OFF \ + "25" "Java 25 — Minecraft 26+" OFF) [ -z "$choices" ] && { echo "No Java version selected."; return; } _enable_temurin_repo local cleaned diff --git a/modules/gpu.sh b/modules/gpu.sh index 2fd7fc1..cdc87fb 100644 --- a/modules/gpu.sh +++ b/modules/gpu.sh @@ -8,6 +8,8 @@ source "${_GPU_DIR}/nvidia.sh" # Consumed by gaming.sh to know which NVIDIA driver path was taken NVIDIA_DRIVER_MODE="" +# Set by _show_nvidia_version_menu(): "470" | "535" | "550" | "590" | "595" | "auto" +NVIDIA_SELECTED_VERSION="" _install_amd_intel_stack() { if [ "$GPU_TYPE" = "unknown" ] || [ -z "$GPU_TYPE" ]; then @@ -179,67 +181,117 @@ _install_nvidia_stack() { if [ "$DEBIAN_VERSION" = "11" ]; then install_nvidia_bullseye - elif [ "$DEBIAN_VERSION" = "12" ]; then - if [ "$(is_nvidia_kepler)" = "true" ]; then - _install_nvidia_bookworm_kepler - elif [ "$(is_nvidia_fermi)" = "true" ]; then - _msg "NVIDIA Fermi — Bookworm" \ - "Fermi GPUs (GF1xx) are not supported\nin Debian 12 (Bookworm).\nThe nvidia-legacy-390xx driver is\nnot available in this version.\n\nNo NVIDIA driver will be installed." - NVIDIA_DRIVER_MODE="" - elif [ "$(is_backports_kernel)" = "true" ]; then - _install_nvidia_bookworm_bpo - else - _install_nvidia_standard + else + if ! _show_nvidia_version_menu; then + echo "Skipping NVIDIA driver installation." + return fi - elif [ "$DEBIAN_VERSION" = "13" ]; then - local nv_arch - nv_arch=$(detect_nvidia_arch "$NVIDIA_GPU_DEVICE_ID") - case "$nv_arch" in - legacy) - _msg "NVIDIA — Trixie" \ - "Kepler and Fermi GPUs are not supported\nin Debian 13 (Trixie).\n\nThe nvidia-legacy drivers are not available\nin this version of Debian.\n\nNo NVIDIA driver will be installed." - NVIDIA_DRIVER_MODE="" + local nv_arch="" + case "$NVIDIA_SELECTED_VERSION" in + 470) + # Legacy 470 (Kepler/Tesla) — forced, regardless of auto-detection + _install_nvidia_bookworm_kepler ;; - blackwell) - _install_nvidia_cuda_repo + 535) + if [ "$(is_nvidia_kepler)" = "true" ]; then + _install_nvidia_bookworm_kepler + elif [ "$(is_nvidia_fermi)" = "true" ]; then + _msg "NVIDIA Fermi — Bookworm" \ + "Fermi GPUs (GF1xx) are not supported\nin Debian 12 (Bookworm).\nThe nvidia-legacy-390xx driver is\nnot available in this version.\n\nNo NVIDIA driver will be installed." + NVIDIA_DRIVER_MODE="" + elif [ "$(is_backports_kernel)" = "true" ]; then + _install_nvidia_bookworm_bpo + else + _install_nvidia_standard + fi ;; - maxwell|pascal|volta) - if [ "$(is_backports_kernel)" = "true" ]; then - local gpu_gen="Maxwell" - [ "$nv_arch" = "pascal" ] && gpu_gen="Pascal" - [ "$nv_arch" = "volta" ] && gpu_gen="Volta" - _msg "NVIDIA — Trixie + Backports" \ - "INCOMPATIBILITY DETECTED: Your NVIDIA ${gpu_gen} GPU\n\ + 550) + nv_arch=$(detect_nvidia_arch "$NVIDIA_GPU_DEVICE_ID") + case "$nv_arch" in + legacy) + _msg "NVIDIA — Trixie" \ + "Kepler and Fermi GPUs are not supported\nin Debian 13 (Trixie).\n\nThe nvidia-legacy drivers are not available\nin this version of Debian.\n\nNo NVIDIA driver will be installed." + NVIDIA_DRIVER_MODE="" + ;; + blackwell) + _install_nvidia_cuda_repo + ;; + maxwell|pascal|volta) + if [ "$(is_backports_kernel)" = "true" ]; then + local gpu_gen="Maxwell" + [ "$nv_arch" = "pascal" ] && gpu_gen="Pascal" + [ "$nv_arch" = "volta" ] && gpu_gen="Volta" + _msg "NVIDIA — Trixie + Backports" \ + "INCOMPATIBILITY DETECTED: Your NVIDIA ${gpu_gen} GPU\n\ is NOT supported by the modern v590 driver.\n\n\ To run NVIDIA safely on Debian 13 (Trixie), you MUST use\n\ the official Debian v550 driver, which requires the\n\ standard STABLE Kernel.\n\n\ Forcing the stable driver path." 14 70 - _install_nvidia_standard - NVIDIA_DRIVER_MODE="stable" - else - _install_nvidia_standard - fi + if ! _install_nvidia_standard; then + NVIDIA_DRIVER_MODE="" + return 1 + fi + NVIDIA_DRIVER_MODE="stable" + else + _install_nvidia_standard + fi + ;; + turing|ampere|ada) + _install_nvidia_standard open + ;; + *) + if [ "$(is_backports_kernel)" = "true" ]; then + _install_nvidia_cuda_repo + else + _install_nvidia_standard + fi + ;; + esac ;; - turing|ampere|ada) - NVIDIA_DRIVER_MODE="open" - _install_nvidia_standard + 590|595) + nv_arch=$(detect_nvidia_arch "$NVIDIA_GPU_DEVICE_ID") + if [ "$nv_arch" = "maxwell" ] || [ "$nv_arch" = "pascal" ] || [ "$nv_arch" = "legacy" ]; then + local gpu_gen="Kepler/Fermi" + [ "$nv_arch" = "maxwell" ] && gpu_gen="Maxwell" + [ "$nv_arch" = "pascal" ] && gpu_gen="Pascal" + _msg "NVIDIA — v${NVIDIA_SELECTED_VERSION}" \ + "Your NVIDIA ${gpu_gen} GPU is NOT supported by\nNVIDIA driver v${NVIDIA_SELECTED_VERSION}.\n\n\ +Only Turing, Ampere, Ada and Blackwell GPUs are supported.\n\n\ +No NVIDIA driver will be installed." 14 65 + NVIDIA_DRIVER_MODE="" + else + if ! _is_cuda_repo_ready; then + if ! _confirm "CUDA Repository" \ + "The official NVIDIA CUDA repository is not enabled.\n\n\ +Enable it now via extrepo? (Required for NVIDIA v${NVIDIA_SELECTED_VERSION}.)"; then + echo "Skipping NVIDIA driver installation." + NVIDIA_DRIVER_MODE="" + return + fi + fi + if _install_nvidia_cuda_repo "$NVIDIA_SELECTED_VERSION"; then + NVIDIA_DRIVER_MODE="extrepo" + else + NVIDIA_DRIVER_MODE="" + fi + fi ;; *) - if [ "$(is_backports_kernel)" = "true" ]; then - _install_nvidia_cuda_repo - else - _install_nvidia_standard - fi + _install_nvidia_standard ;; esac - - else - _install_nvidia_standard fi if [ -n "$NVIDIA_DRIVER_MODE" ]; then + _configure_nvidia_wayland "$NVIDIA_SELECTED_VERSION" + if _is_hybrid_laptop; then + echo -e "${CYAN}[INFO] Hybrid GPU (Optimus) detected.${NC}" + echo -e "PRIME offload is auto-configured by X.Org 1.20.7+ when using X11." + echo -e "After reboot, verify with: ${YELLOW}xrandr --listproviders | grep NVIDIA-G0${NC}" + echo -e "If not found, ensure BIOS boots on iGPU and nvidia-drm is loaded." + fi offer_generic_tools local summary="NVIDIA: ${NVIDIA_DRIVER_MODE}\n" summary+="Tools: nvtop + vainfo" diff --git a/modules/gpu/_helpers.sh b/modules/gpu/_helpers.sh index ddb5e25..57374f6 100644 --- a/modules/gpu/_helpers.sh +++ b/modules/gpu/_helpers.sh @@ -23,6 +23,7 @@ declare -A NVIDIA_FAMILY_MAP=( ) detect_nvidia_arch() { + [ -z "$1" ] && { echo "unknown"; return; } local pci_id="${1^^}" local prefix="${pci_id:0:2}" echo "${NVIDIA_FAMILY_MAP[$prefix]:-unknown}" @@ -39,6 +40,22 @@ _is_nvidia_kepler_id() { return 1 } +# Normaliza la familia de arquitectura NVIDIA desambiguando Kepler/Fermi +# (detect_nvidia_arch los agrupa como "legacy" vía rango de device IDs) +_get_nvidia_arch_family() { + local fam + fam=$(detect_nvidia_arch "$NVIDIA_GPU_DEVICE_ID") + if [ "$fam" = "legacy" ]; then + if _is_nvidia_kepler_id "$NVIDIA_GPU_DEVICE_ID"; then + echo "kepler" + else + echo "fermi" + fi + else + echo "$fam" + fi +} + is_nvidia_kepler() { [ -n "$NVIDIA_GPU_DEVICE_ID" ] && [[ "$(detect_nvidia_arch "$NVIDIA_GPU_DEVICE_ID")" == "legacy" ]] && _is_nvidia_kepler_id "$NVIDIA_GPU_DEVICE_ID" && echo true || echo false; } is_nvidia_fermi() { [ -n "$NVIDIA_GPU_DEVICE_ID" ] && [[ "$(detect_nvidia_arch "$NVIDIA_GPU_DEVICE_ID")" == "legacy" ]] && ! _is_nvidia_kepler_id "$NVIDIA_GPU_DEVICE_ID" && echo true || echo false; } is_nvidia_legacy() { [ -n "$NVIDIA_GPU_DEVICE_ID" ] && [[ "$(detect_nvidia_arch "$NVIDIA_GPU_DEVICE_ID")" == "legacy" ]] && echo true || echo false; } @@ -156,3 +173,22 @@ offer_generic_tools() { echo "Skipping GPU monitoring tools." fi } + +_is_hybrid_laptop() { + local gpu_count nvidia_count chassis + gpu_count=$(lspci -nn 2>/dev/null | grep -ciE "VGA compatible|3D controller") || true + [ "$gpu_count" -lt 2 ] && return 1 + + # Defensa en profundidad: si TODAS las GPUs son NVIDIA (SLI o + # dual-GPU desktop), no hay iGPU Intel/AMD → no es híbrida. + nvidia_count=$(lspci -nn 2>/dev/null | grep -iE "VGA compatible|3D controller" | grep -c "10de:") || true + [ "$nvidia_count" -ge "$gpu_count" ] && return 1 + + chassis=$(cat /sys/class/dmi/id/chassis_type 2>/dev/null || echo "0") + case "$chassis" in + 8|9|10|11|14|30|31|32) return 0 ;; + esac + + ls /sys/class/power_supply/ 2>/dev/null | grep -q "^BAT" && return 0 + return 1 +} diff --git a/modules/gpu/nvidia.sh b/modules/gpu/nvidia.sh index 75ecce5..f2def6d 100644 --- a/modules/gpu/nvidia.sh +++ b/modules/gpu/nvidia.sh @@ -64,68 +64,245 @@ The script will enable the official NVIDIA CUDA\nrepository and install the v590 # Shared helper: enable NVIDIA CUDA repo via extrepo # ------------------------------------------------------------------- _enable_cuda_repo() { - if [ ! -f /etc/apt/sources.list.d/extrepo_nvidia-cuda.sources ] && \ - ! grep -qr 'developer.download.nvidia.com' /etc/apt/sources.list.d/ 2>/dev/null; then + if ! _is_cuda_repo_ready; then if ! command -v extrepo &>/dev/null; then - _run_cmd "extrepo" "sudo apt install -y extrepo" "Installing extrepo..." + _run_cmd "extrepo" "sudo apt install -y extrepo" "Installing extrepo..." || return 1 fi _run_cmd "CUDA Repo" \ "sudo extrepo enable nvidia-cuda" \ - "Enabling official NVIDIA CUDA repository..." + "Enabling official NVIDIA CUDA repository..." || return 1 fi - _run_cmd "APT Update" "sudo apt update" "Updating package lists..." +} + +# ------------------------------------------------------------------- +# Shared DKMS helpers: verify the NVIDIA module compiled for the +# currently running kernel; repair via dpkg-reconfigure if not +# ------------------------------------------------------------------- +# Returns: 0 if the NVIDIA DKMS module shows "installed" for $(uname -r) +_nvidia_dkms_installed() { + local kernel line + kernel=$(uname -r) + line=$(dkms status 2>/dev/null | grep "^nvidia" | grep -F "$kernel" | grep ": installed" | head -1) + [ -n "$line" ] +} + +# Returns 0 if Secure Boot is active (mokutil present and enabled) +_nvidia_secure_boot_enabled() { + command -v mokutil &>/dev/null || return 1 + mokutil --sb-state 2>/dev/null | grep -q "SecureBoot enabled" +} + +# Aviso no fatal: el módulo DKMS está compilado pero NO firmado. +# El usuario avanzado puede firmarlo con MOK; el novato necesita saber +# por qué verá pantalla negra tras reiniciar. Si mokutil falta, no se +# muestra nada (mokutil no viene preinstalado en Debian). +_warn_secure_boot() { + if _nvidia_secure_boot_enabled; then + echo -e "${RED}WARNING: Secure Boot is enabled. The NVIDIA DKMS module is compiled but NOT signed.${NC}" + echo -e "${RED}You MUST sign the module with MOK or disable Secure Boot in BIOS before rebooting.${NC}" + echo -e "${RED}See: https://wiki.debian.org/SecureBoot#Signing_kernel_modules${NC}" + fi +} + +# Verify the DKMS build for the current kernel and repair it if needed. +# $@ = candidate dkms packages to reconfigure, in priority order +# (the first installed one is used for dpkg-reconfigure). +_verify_nvidia_dkms_build() { + local kernel + kernel=$(uname -r) + + echo "" + echo "──────────────────────────────────────────────" + echo "Verifying DKMS module compilation for ${kernel}:" + + if ! command -v dkms &>/dev/null; then + echo -e "${RED}(dkms not installed — DKMS build cannot be verified)${NC}" + echo "──────────────────────────────────────────────" + return 1 + fi + + dkms status 2>/dev/null | grep "^nvidia" || echo "(no nvidia DKMS module found)" + + if _nvidia_dkms_installed; then + _warn_secure_boot + echo -e "${GREEN}DKMS module compiled for ${kernel}. Reboot required.${NC}" + echo "──────────────────────────────────────────────" + return 0 + fi + + echo -e "${YELLOW}DKMS module NOT compiled for ${kernel}. Repairing...${NC}" + local pkg repaired=false + for pkg in "$@"; do + if dpkg -l "$pkg" 2>/dev/null | grep -q "^ii"; then + _run_cmd "NVIDIA" "sudo dpkg-reconfigure $pkg" "Reconfiguring $pkg..." + repaired=true + break + fi + done + if ! $repaired; then + echo -e "${RED}No DKMS package found to reconfigure.${NC}" + fi + + if _nvidia_dkms_installed; then + _warn_secure_boot + echo -e "${GREEN}DKMS module compiled successfully for ${kernel}. Reboot required.${NC}" + echo "──────────────────────────────────────────────" + return 0 + else + echo -e "${RED}DKMS module still not compiled for ${kernel}.${NC}" + echo "Check the build log manually:" + echo " /var/lib/dkms/nvidia*/.../build/make.log" + echo " dmesg | grep nvidia" + echo "──────────────────────────────────────────────" + return 1 + fi +} + +# ------------------------------------------------------------------- +# NVIDIA driver version selection (Debian 12/13) +# Sets the global NVIDIA_SELECTED_VERSION; first option is the default. +# Returns: 0 if a version was chosen, 1 if the user cancelled +# ------------------------------------------------------------------- +_is_cuda_repo_ready() { + [ -f /etc/apt/sources.list.d/extrepo_nvidia-cuda.sources ] || \ + grep -qr 'developer.download.nvidia.com' /etc/apt/sources.list.d/ 2>/dev/null +} + +_show_nvidia_version_menu() { + local choice + if [ "$DEBIAN_VERSION" = "12" ]; then + choice=$(_menu "NVIDIA Driver Version" "Select the NVIDIA driver version for Debian 12 (Bookworm):" 12 70 3 \ + "535" "Official NVIDIA driver (Recommended)" \ + "470" "Legacy 470 (Kepler/Tesla GPUs)") + elif [ "$DEBIAN_VERSION" = "13" ]; then + choice=$(_menu "NVIDIA Driver Version" "Select the NVIDIA driver version for Debian 13 (Trixie):" 14 70 5 \ + "550" "Official Debian driver (Recommended)" \ + "590" "NVIDIA Repo v590 (Turing/Ampere/Ada/Blackwell)" \ + "595" "NVIDIA Repo v595 (Latest)") + else + NVIDIA_SELECTED_VERSION="auto" + return 0 + fi + [ -z "$choice" ] && return 1 + NVIDIA_SELECTED_VERSION="$choice" + return 0 +} + +# ------------------------------------------------------------------- +# NVIDIA Wayland/KMS base configuration (/etc/modprobe.d/nvidia-wayland.conf) +# Applies on Debian 12/13, any driver version (535/550/590/595). +# Arquitectura y detección híbrida son ORTOGONALES: +# - Arquitectura → afecta SOLO fbdev (kepler: el 470 no lo soporta) +# y el color/mensaje informativo. +# - Híbrida vs desktop → afecta NVreg (Preserve / kernel suspend +# notifier), INDEPENDIENTE de la arquitectura. +# 590/595 añaden el kernel suspend notifier (complementa, nunca +# reemplaza, NVreg_PreserveVideoMemoryAllocations). +# ------------------------------------------------------------------- +_configure_nvidia_wayland() { + local ver="${1:-$NVIDIA_SELECTED_VERSION}" + local conf="/etc/modprobe.d/nvidia-wayland.conf" + local arch + local content="" + local color="${GREEN}" + local msg="Wayland config (desktop): KMS + video memory preservation enabled." + arch=$(_get_nvidia_arch_family) + + # ── Arquitectura: solo fbdev y mensaje de color ── + case "$arch" in + kepler) + color="${RED}" + msg="WARNING: Wayland not supported on Kepler. Use X11 (Xorg)." + ;; + maxwell|pascal) + color="${YELLOW}" + msg="Wayland support on ${arch} is experimental. X11 recommended." + ;; + esac + + # ── Híbrida vs desktop: NVreg independiente de la arquitectura ── + if _is_hybrid_laptop; then + content="options nvidia-drm modeset=1"$'\n' + [ "$arch" != "kepler" ] && content+="options nvidia-drm fbdev=1"$'\n' + color="${GREEN}" + msg="Wayland config (hybrid laptop): KMS enabled — NVreg omitted." + else + content="options nvidia NVreg_PreserveVideoMemoryAllocations=1"$'\n' + case "$ver" in + 590|595) content+="options nvidia NVreg_UseKernelSuspendNotifiers=1"$'\n' ;; + esac + content+="options nvidia-drm modeset=1"$'\n' + [ "$arch" != "kepler" ] && content+="options nvidia-drm fbdev=1"$'\n' + fi + + printf "%b" "$content" | sudo tee "$conf" >/dev/null + echo -e "${color}${msg}${NC}" } # ------------------------------------------------------------------- # CASE A: Trixie + Backports Kernel → Official CUDA Repo (Pinned v590) # ------------------------------------------------------------------- _install_nvidia_cuda_repo() { - local warn="WARNING: Official Debian NVIDIA driver (v550)\n" - warn+="fails to compile on Trixie Backports Kernels.\n\n" - warn+="The script will enable the official NVIDIA CUDA\n" - warn+="repository and install the production branch v590\n" - warn+="using NVIDIA's unified driver pinning packages.\n\n" - warn+="Source: Official NVIDIA CUDA Repo (Pinned v590.*)\n" - warn+="Driver: Production Branch v590 (unified metapackage)\n" + local ver="${1:-590}" + local warn="WARNING: You are about to install NVIDIA v${ver} from\n" + warn+="the official NVIDIA CUDA repository.\n\n" + warn+="Source: Official NVIDIA CUDA Repo (Pinned v${ver}.*)\n" + warn+="Driver: Production Branch v${ver} (unified metapackage)\n" warn+="[+] nvidia-driver (full 64-bit compute + graphics)\n" + warn+="[+] nvidia-kernel-dkms / nvidia-kernel-open-dkms (vía metapaquete)\n" warn+="[+] firmware-nvidia-gsp\n" - warn+="[+] nvidia-driver-pinning-590 (branch locking)\n" - warn+="[+] APT Pinning (version 590.*)\n\n" + warn+="[+] nvidia-driver-pinning-${ver} (if available)\n" + warn+="[+] APT Pinning (version ${ver}.*)\n\n" warn+="Do you want to proceed at your own risk?" - if ! _confirm_custom "NVIDIA Driver — Trixie + Backports" "$warn" "Proceed" "Abort" 18 70; then + if ! _confirm_custom "NVIDIA Driver — v${ver}" "$warn" "Proceed" "Abort" 18 70; then echo -e "${YELLOW}NVIDIA installation aborted by user.${NC}" return 1 fi # Step 1: Enable CUDA repo via extrepo - _enable_cuda_repo + if ! _enable_cuda_repo; then + _msg "CUDA Repo — Error" "Failed to enable the official NVIDIA CUDA repository.\n\nNo NVIDIA driver was installed." 10 60 + return 1 + fi - # Step 2: Create APT pinning to lock v590 - _run_cmd "APT Pinning" \ - 'printf "%s\n" "Package: *nvidia*" "Package: *cuda*" "Package: libcuda1" "Package: firmware-nvidia-gsp" "Pin: version 590.*" "Pin-Priority: 1001" | sudo tee /etc/apt/preferences.d/block-nvidia > /dev/null' \ - "Creating APT pinning to lock NVIDIA to v590 branch..." + # Step 2: Create APT pinning to lock to the selected branch + if ! _run_cmd "APT Pinning" \ + "printf '%s\n' \"Package: *nvidia*\" \"Package: *cuda*\" \"Package: libcuda1\" \"Package: firmware-nvidia-gsp\" \"Pin: version ${ver}.*\" \"Pin-Priority: 1001\" | sudo tee /etc/apt/preferences.d/block-nvidia > /dev/null" \ + "Creating APT pinning to lock NVIDIA to v${ver} branch..."; then + _msg "APT Pinning — Error" "Failed to write APT pinning.\n\nNo NVIDIA driver was installed." 10 60 + return 1 + fi # Step 3: Install NVIDIA unified metapackages (driver pinning) - _run_cmd "NVIDIA CUDA" \ - "sudo apt install -y nvidia-driver-pinning-590 nvidia-driver firmware-nvidia-gsp" \ - "Installing NVIDIA v590 production driver via unified metapackages..." + local pin_meta="nvidia-driver-pinning-${ver}" + local install_cmd="nvidia-driver firmware-nvidia-gsp" + if apt-cache policy "$pin_meta" 2>/dev/null | grep -q "Candidate: [^ (none)]"; then + install_cmd="$pin_meta $install_cmd" + else + echo -e "${YELLOW}${pin_meta} not available in the NVIDIA repo — using APT pinning only.${NC}" + fi + if ! _run_cmd "NVIDIA CUDA" \ + "sudo apt install -y $install_cmd" \ + "Installing NVIDIA v${ver} production driver via unified metapackages..."; then + NVIDIA_DRIVER_MODE="" + _msg "NVIDIA — Error" "NVIDIA v${ver} installation FAILED.\n\nNo NVIDIA driver was installed." 10 60 + return 1 + fi + + # Post-install: el módulo DKMS instalado debe coincidir con la rama ${ver} + local dkms_ver + dkms_ver=$(dpkg -l nvidia-kernel-dkms nvidia-kernel-open-dkms 2>/dev/null | awk '$1=="ii" {print $3; exit}') + if [[ "$dkms_ver" == ${ver}.* ]]; then + echo -e "${GREEN}DKMS module ${dkms_ver} matches branch v${ver}.${NC}" + else + echo -e "${RED}WARNING: DKMS package (${dkms_ver:-none}) does not match v${ver}.*${NC}" + fi NVIDIA_DRIVER_MODE="cuda-repo" - echo -e "${GREEN}NVIDIA Production Driver v590 installed from CUDA repo. Reboot required.${NC}" + echo -e "${GREEN}NVIDIA Production Driver v${ver} installed from CUDA repo. Reboot required.${NC}" - echo "" - echo "──────────────────────────────────────────────" - echo "Verifying DKMS module compilation:" - if command -v dkms &>/dev/null; then - dkms status 2>/dev/null | grep nvidia || echo "(no nvidia DKMS module found)" - else - echo "(dkms not installed)" - fi - echo "" - echo "If the line ends with 'installed' → module is OK." - echo "Otherwise check: dmesg | grep nvidia" - echo "──────────────────────────────────────────────" + _verify_nvidia_dkms_build nvidia-kernel-open-dkms nvidia-kernel-dkms || true } # ------------------------------------------------------------------- @@ -174,24 +351,17 @@ _install_nvidia_bookworm_bpo() { return 0 fi - _run_cmd "NVIDIA" "sudo apt install -y -t bookworm-backports $nv_pkg firmware-misc-nonfree nvidia-vaapi-driver" \ - "Installing NVIDIA driver from backports..." + if ! _run_cmd "NVIDIA" "sudo apt install -y -t bookworm-backports $nv_pkg firmware-misc-nonfree nvidia-vaapi-driver" \ + "Installing NVIDIA driver from backports..."; then + NVIDIA_DRIVER_MODE="" + _msg "NVIDIA — Error" "NVIDIA backports installation FAILED.\n\nNo NVIDIA driver was installed." 10 60 + return 1 + fi NVIDIA_DRIVER_MODE="backports" echo -e "${GREEN}NVIDIA driver installed from backports. Reboot required.${NC}" - echo "" - echo "──────────────────────────────────────────────" - echo "Verifying DKMS module compilation:" - if command -v dkms &>/dev/null; then - dkms status 2>/dev/null | grep nvidia || echo "(no nvidia DKMS module found)" - else - echo "(dkms not installed)" - fi - echo "" - echo "If the line ends with 'installed' → module is OK." - echo "Otherwise check: dmesg | grep nvidia" - echo "──────────────────────────────────────────────" + _verify_nvidia_dkms_build nvidia-kernel-dkms nvidia-tesla-470-kernel-dkms || true } # ------------------------------------------------------------------- @@ -212,6 +382,7 @@ _install_nvidia_bookworm_kepler() { msg+="para evitar fallos de pantalla negra.\n\n" msg+=" [SKIP] nvidia-detect (omitido — evita rama 535)\n" msg+=" [USE] ${nv_pkg}\n" + msg+=" [+] linux-headers-amd64\n" msg+=" [+] firmware-misc-nonfree\n" msg+=" [+] nvidia-settings\n\n" msg+="Instalar driver legacy para Kepler?" @@ -222,9 +393,13 @@ _install_nvidia_bookworm_kepler() { return 0 fi - _run_cmd "NVIDIA Kepler" \ - "sudo apt install -y $nv_pkg firmware-misc-nonfree nvidia-settings" \ - "Instalando nvidia-legacy-470xx-driver..." + if ! _run_cmd "NVIDIA Kepler" \ + "sudo apt install -y linux-headers-amd64 $nv_pkg firmware-misc-nonfree nvidia-settings" \ + "Instalando nvidia-legacy-470xx-driver..."; then + NVIDIA_DRIVER_MODE="" + _msg "NVIDIA Kepler — Error" "Kepler driver installation FAILED.\n\nNo NVIDIA driver was installed." 10 60 + return 1 + fi # Si backports está habilitado, ofrecer actualización if [ "$(is_backports_enabled)" == "true" ]; then @@ -235,11 +410,14 @@ _install_nvidia_bookworm_kepler() { local msg="Hay una versión en backports: ${bpo_ver}\n" msg+="Instalar desde bookworm-backports?" if _confirm "Kepler Backports" "$msg"; then - _run_cmd "NVIDIA Kepler" \ + if _run_cmd "NVIDIA Kepler" \ "sudo apt install -y -t bookworm-backports $nv_pkg" \ - "Actualizando Kepler driver desde backports..." - NVIDIA_DRIVER_MODE="backports" - echo -e "${GREEN}Kepler driver actualizado desde backports.${NC}" + "Actualizando Kepler driver desde backports..."; then + NVIDIA_DRIVER_MODE="backports" + echo -e "${GREEN}Kepler driver actualizado desde backports.${NC}" + else + echo -e "${RED}Kepler backports upgrade failed — keeping the stable version.${NC}" + fi fi fi fi @@ -247,18 +425,7 @@ _install_nvidia_bookworm_kepler() { NVIDIA_DRIVER_MODE="${NVIDIA_DRIVER_MODE:-stable}" echo -e "${GREEN}Kepler driver (${nv_pkg}) installed. Reboot required.${NC}" - echo "" - echo "──────────────────────────────────────────────" - echo "Verifying DKMS module compilation:" - if command -v dkms &>/dev/null; then - dkms status 2>/dev/null | grep nvidia || echo "(no nvidia DKMS module found)" - else - echo "(dkms not installed)" - fi - echo "" - echo "If the line ends with 'installed' → module is OK." - echo "Otherwise check: dmesg | grep nvidia" - echo "──────────────────────────────────────────────" + _verify_nvidia_dkms_build nvidia-tesla-470-kernel-dkms || true } # ------------------------------------------------------------------- @@ -266,11 +433,14 @@ _install_nvidia_bookworm_kepler() { # ------------------------------------------------------------------- _install_nvidia_standard() { # --- 1. DETERMINAR PAQUETES BASADO EN LA SEÑAL --- + # $1 = modo solicitado por el dispatcher ("open" para 550+Turing+); + # si no se pasa, se usa NVIDIA_DRIVER_MODE o auto-detección. + local requested_mode="${1:-${NVIDIA_DRIVER_MODE:-auto}}" local nv_pkg="nvidia-driver" local kernel_pkg="" local use_bpo=false - case "${NVIDIA_DRIVER_MODE:-auto}" in + case "$requested_mode" in open) kernel_pkg="nvidia-open-kernel-dkms" ;; @@ -312,9 +482,10 @@ _install_nvidia_standard() { msg="Source: ${src_label}\n" msg+="NVIDIA Driver: ${nv_pkg} ${stable_nv_ver:-unknown}\n" msg+="Kernel Module: ${kernel_pkg} ${kernel_ver:-unknown}\n" + msg+="[+] linux-headers-amd64\n" msg+="[+] firmware-misc-nonfree (o firmware-nvidia-gsp en Trixie)\n" - msg+="[+] nvidia-vaapi-driver\n" - msg+="[+] mesa-vdpau-drivers" + msg+="[+] nvidia-vaapi-driver" + [ "$DEBIAN_VERSION" = "12" ] && msg+="\n[+] mesa-vdpau-drivers" if ! _confirm "NVIDIA Driver" "$msg" 14 70; then echo "Skipping NVIDIA driver installation." @@ -322,24 +493,35 @@ _install_nvidia_standard() { fi # --- 4. EJECUCIÓN --- - local extra_pkgs="firmware-misc-nonfree nvidia-vaapi-driver mesa-vdpau-drivers" + local extra_pkgs="linux-headers-amd64 firmware-misc-nonfree nvidia-vaapi-driver" + [ "$DEBIAN_VERSION" = "12" ] && extra_pkgs+=" mesa-vdpau-drivers" local install_pkgs="$kernel_pkg $nv_pkg $extra_pkgs" if $use_bpo; then - _run_cmd "NVIDIA" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports $install_pkgs" \ - "Installing NVIDIA driver from backports..." + if ! _run_cmd "NVIDIA" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports $install_pkgs" \ + "Installing NVIDIA driver from backports..."; then + NVIDIA_DRIVER_MODE="" + _msg "NVIDIA — Error" "NVIDIA driver installation from backports FAILED.\n\nNo NVIDIA driver was installed." 10 60 + return 1 + fi NVIDIA_DRIVER_MODE="backports" else - _run_cmd "NVIDIA" "sudo apt install -y $install_pkgs" \ - "Installing NVIDIA driver from stable..." + if ! _run_cmd "NVIDIA" "sudo apt install -y $install_pkgs" \ + "Installing NVIDIA driver from stable..."; then + NVIDIA_DRIVER_MODE="" + _msg "NVIDIA — Error" "NVIDIA driver installation FAILED.\n\nNo NVIDIA driver was installed." 10 60 + return 1 + fi NVIDIA_DRIVER_MODE="stable" fi - # --- 5. VERIFICACIÓN DKMS --- + # Fix obligatorio para Debian 12 con módulo abierto + if [ "$DEBIAN_VERSION" = "12" ] && [[ "$kernel_pkg" == *"open"* ]]; then + echo "options nvidia NVreg_OpenRmEnableUnsupportedGpus=1" | sudo tee /etc/modprobe.d/nvidia-open.conf > /dev/null + echo "Applied required Open RM parameter for Debian 12." + fi + + # --- 5. VERIFICACIÓN DKMS POST-INSTALL --- echo -e "${GREEN}NVIDIA driver installed. Reboot required.${NC}" - echo "──────────────────────────────────────────────" - echo "Verifying DKMS module compilation:" - command -v dkms &>/dev/null && dkms status 2>/dev/null | grep nvidia || echo "(no nvidia DKMS module found)" - echo "If the line ends with 'installed' → module is OK." - echo "──────────────────────────────────────────────" + _verify_nvidia_dkms_build "$kernel_pkg" || true } diff --git a/modules/utils.sh b/modules/utils.sh index f5d07a4..8d6eca1 100644 --- a/modules/utils.sh +++ b/modules/utils.sh @@ -628,12 +628,14 @@ _pause() { } # Blocks 2-4: run → pause +# Returns the exit code of the executed command so callers can abort +# or adjust state (e.g. NVIDIA_DRIVER_MODE) when a step fails. _run_cmd() { local title="$1" command="$2" success_msg="${3:-Running...}" echo -e "${GREEN}[+]${NC} $success_msg" echo "──────────────────────────────────────────────" - bash -c "$command" - local rc=$? + local rc=0 + bash -c "$command" || rc=$? echo "──────────────────────────────────────────────" if [ $rc -eq 0 ]; then echo -e "${GREEN}[+]${NC} Done." @@ -641,6 +643,7 @@ _run_cmd() { echo -e "${RED}[-]${NC} Failed (exit code: $rc)." fi _pause + return "$rc" } # Blocks 1-4: confirm → run → pause @@ -757,7 +760,10 @@ _check_network() { if _confirm "LightDM" "Configure LightDM to show the user list on the login screen?\n\nThis disables greeter-hide-users."; then if ! is_installed lightdm-gtk-greeter-settings; then echo -e "${YELLOW}Installing lightdm-gtk-greeter-settings...${NC}" - sudo DEBIAN_FRONTEND=noninteractive apt install -y lightdm-gtk-greeter-settings + if ! sudo DEBIAN_FRONTEND=noninteractive apt install -y lightdm-gtk-greeter-settings; then + echo -e "${YELLOW}lightdm-gtk-greeter-settings could not be installed — LightDM configuration skipped.${NC}" + return 0 + fi fi local conf_dir="/etc/lightdm/lightdm.conf.d"