diff --git a/.gitattributes b/.gitattributes
index da7f4fe..d40969f 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1 @@
-*.sh linguist-language=Rust
-
+*.sh text eol=lf linguist-language=Shell
diff --git a/.github/workflows/shell-checks.yml b/.github/workflows/shell-checks.yml
new file mode 100644
index 0000000..5655989
--- /dev/null
+++ b/.github/workflows/shell-checks.yml
@@ -0,0 +1,26 @@
+name: Shell checks
+
+on:
+ push:
+ pull_request:
+
+permissions:
+ contents: read
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out repository
+ uses: actions/checkout@v4
+
+ - name: Check Bash syntax
+ run: bash -n install-nvidia-cuda.sh
+
+ - name: Install ShellCheck
+ run: |
+ sudo apt-get update
+ sudo apt-get install --no-install-recommends --yes shellcheck
+
+ - name: Run ShellCheck
+ run: shellcheck install-nvidia-cuda.sh
diff --git a/README.md b/README.md
index bff5fe4..d6976de 100644
--- a/README.md
+++ b/README.md
@@ -1,94 +1,120 @@
-# nvidia-driver
-NVIDIA Driver + CUDA Toolkit Installer for Debian 12/13
+# NVIDIA Driver + CUDA Toolkit Installer
-This script installs **NVIDIA GPU drivers** and the **CUDA Toolkit** on **Debian 12 (Bookworm)** and **Debian 13 (Trixie)** — automatically and reliably.
-It uses Debian’s own packages (APT-first, no NVIDIA repo by default) for a stable, Debian-managed setup.
+[](https://github.com/dennishilk/nvidia-driver/actions/workflows/shell-checks.yml)
----
+Interactive, APT-first installer for NVIDIA drivers and the optional CUDA Toolkit on Debian 12 (Bookworm) and Debian 13 (Trixie).
-## ✨ Features
-- ✅ Auto-detects Debian **12/13** and **amd64/arm64** architecture
-- ✅ Installs build tools: `build-essential`, `dkms`, `linux-headers-$(uname -r)`
-- ✅ Installs CUDA via the Debian package: `nvidia-cuda-toolkit`
-- ✅ Optionally blacklists **nouveau** to avoid conflicts
-- ✅ Warns if **Secure Boot** is enabled
+The recommended paths use Debian's own packages. The script does not add NVIDIA repositories, force an Xorg configuration, kill package-manager processes, or delete APT lock files.
+## Supported systems
-🛡️ Secure Boot
+- Debian 12 or 13
+- `amd64` or `arm64`
+- An NVIDIA PCI display device
+- Root access
+- APT sources with `main contrib non-free non-free-firmware`
-If Secure Boot is enabled, DKMS may fail to load unsigned modules. Options:
+The advanced NVIDIA `.run` installer is available only on `amd64` and is intentionally not recommended for normal Debian installations.
-Disable Secure Boot in firmware, or
+## Features
-Enroll a Machine Owner Key (MOK) and sign the module.
+- Installs `nvidia-driver` from Debian stable or an already configured backports suite
+- Installs the Debian `nvidia-cuda-toolkit` package on request
+- Installs both the architecture header metapackage and exact running-kernel headers when available
+- Understands classic `.list` files and modern deb822 `.sources` files
+- Detects Secure Boot when `mokutil` is available and explains MOK enrollment
+- Can switch back to nouveau or remove installed `nvidia-*` packages through APT
+- Fetches current `.run` installer metadata from NVIDIA instead of using a stale hardcoded version
+- Logs output to `/var/log/nvidia-optimizer.log`
-The script prints a note when Secure Boot appears enabled.
+## Installation
+```bash
+git clone https://github.com/dennishilk/nvidia-driver.git
+cd nvidia-driver
+chmod +x install-nvidia-cuda.sh
+sudo ./install-nvidia-cuda.sh
+```
-🚫 Nouveau (Open-Source Driver)
+Choose one of the five menu actions:
-The script blacklists nouveau to prevent conflicts:
+1. Install the Debian stable driver (recommended)
+2. Install the driver from an already enabled Debian backports suite
+3. Remove NVIDIA packages and enable nouveau
+4. Remove NVIDIA packages and clean unused dependencies
+5. Install NVIDIA's `.run` driver (advanced, `amd64` only)
-Config: /etc/modprobe.d/blacklist-nouveau.conf
+After a driver change, reboot and verify:
-Rebuilds initramfs automatically
+```bash
+nvidia-smi
+nvcc --version # only when the CUDA Toolkit was installed
+```
-If you prefer to keep nouveau, remove that file and run sudo update-initramfs -u.
+## APT source requirements
+The script accepts both `/etc/apt/sources.list` entries and deb822 files such as `/etc/apt/sources.list.d/debian.sources`.
-🧰 Troubleshooting
+For example, a classic Debian 13 source line contains:
-Black screen or login loop: Likely driver conflict or Secure Boot. Boot to recovery/TTY, remove conflicting drivers, verify blacklist, check mokutil --sb-state.
+```text
+deb http://deb.debian.org/debian trixie main contrib non-free non-free-firmware
+```
-DKMS build fails: Ensure headers match the running kernel:
+Replace `trixie` with `bookworm` on Debian 12. Backports option 2 additionally expects `${VERSION_CODENAME}-backports`, such as `trixie-backports`.
-uname -r
-apt-cache policy linux-headers-$(uname -r)
+## Secure Boot
+
+With Secure Boot enabled, the NVIDIA DKMS module may not load until its Machine Owner Key is enrolled. If Debian created `/var/lib/dkms/mok.pub`, enroll it with:
-Unable to locate package cuda: Debian repos do not ship the `cuda` meta-package. Use `nvidia-cuda-toolkit` (this script does) or add NVIDIA’s CUDA repo explicitly.
+```bash
+sudo mokutil --import /var/lib/dkms/mok.pub
+```
+Then reboot and complete enrollment in the firmware's MOK Manager. If `mokutil` is missing, install the Debian package of the same name first.
-nvidia-smi not found: Ensure driver packages are installed and reboot if needed.
+## Troubleshooting
+### `Unable to locate package nvidia-cuda-toolkit`
-🧩 Uninstall
+The Debian package is named `nvidia-cuda-toolkit`, not `cuda`. Confirm that `non-free` is enabled, then refresh APT:
-To remove CUDA & drivers:
+```bash
+sudo apt update
+apt-cache policy nvidia-cuda-toolkit
+```
-sudo apt remove --purge 'nvidia-cuda-toolkit*' 'nvidia*'
-sudo rm -f /etc/modprobe.d/blacklist-nouveau.conf
-sudo update-initramfs -u
-sudo apt autoremove -y
-sudo reboot
+### DKMS build fails
+Check whether headers exist for the running kernel:
+
+```bash
+uname -r
+apt-cache policy "linux-headers-$(uname -r)"
+```
+If only the newer architecture header metapackage was available, reboot into the newly installed Debian kernel and run the driver installation again.
-## 📦 Installation
+### Black screen or login loop
-1. Clone the repository or download the script:
- git clone https://github.com/dennishilk/nvidia-driver.git
-
- cd nvidia-driver
-
-3. Make the script executable:
- chmod +x install-nvidia-cuda.sh
+From a recovery shell or TTY, inspect:
-4. Run with root privileges:
- sudo ./install-nvidia-cuda.sh
+```bash
+cat /var/log/nvidia-optimizer.log
+dkms status
+sudo mokutil --sb-state
+```
-5. Reboot to load the NVIDIA kernel module:
- sudo reboot
+Secure Boot, a failed DKMS build, or an old manually installed `.run` driver are the usual causes.
-6. Check after reboot:
- nvidia-smi
- nvcc --version
+## Uninstall or return to nouveau
-
+Run the script again and choose option 3 or 4. Cleanup is performed through APT; the script does not manually erase `/var/lib/dkms` or user-owned NVIDIA configuration files.
+## License and warranty
+MIT License. See [LICENSE](LICENSE).
-No Warranty Disclaimer
+The software is provided "as is", without warranty of any kind. Use it at your own risk; the author is not responsible for damage, data loss, or other issues caused by its use.
-The software in this repository is provided "as is", without warranty of any kind.
-I make no guarantees regarding the functionality, correctness, or suitability of this code for any purpose.
-Use it at your own risk. I am not responsible for any damages, data loss, or issues that may arise from using this software.
+
diff --git a/install-nvidia-cuda.sh b/install-nvidia-cuda.sh
index 57c3a78..692df1a 100644
--- a/install-nvidia-cuda.sh
+++ b/install-nvidia-cuda.sh
@@ -1,20 +1,19 @@
#!/usr/bin/env bash
# ============================================================
-# NVIDIA Driver + (optional) CUDA Toolkit for Debian 13 (Trixie)
+# NVIDIA Driver + (optional) CUDA Toolkit for Debian 12/13
# "Debian-clean" edition (APT-first, no mixed installer by default)
# Author: Dennis Hilk
-# Version: 1.2.0
+# Version: 1.3.0
#
# Features:
# - Strict mode + logging
-# - Safe APT/dpkg lock handling (no blind killing)
+# - Safe APT/dpkg lock handling (never kills package managers or removes locks)
# - Detect NVIDIA GPU
-# - Checks non-free + non-free-firmware APT sources
+# - Checks .list and deb822 .sources files for required APT components
# - Stable driver install (Debian repo) or Backports install
# - Optional CUDA Toolkit (Debian package)
# - Nouveau enable, full clean remove
# - Secure Boot + Wayland hints
-# - Uses /etc/X11/xorg.conf.d (modular) instead of patching xorg.conf
# ============================================================
set -Eeuo pipefail
@@ -23,6 +22,7 @@ set -Eeuo pipefail
# Logging
# ----------------------------
LOGFILE="/var/log/nvidia-optimizer.log"
+SCRIPT_VERSION="1.3.0"
mkdir -p "$(dirname "$LOGFILE")"
exec > >(tee -a "$LOGFILE") 2>&1
@@ -62,9 +62,9 @@ if [[ ${EUID:-0} -ne 0 ]]; then
die "Please run as root: sudo $0"
fi
-clear
+clear 2>/dev/null || true
echo -e "${CYAN}──────────────────────────────────────────────────────────"
-echo -e " 🧠 NVIDIA Driver + CUDA Toolkit (Debian 13) v1.2.0"
+echo -e " 🧠 NVIDIA Driver + CUDA Toolkit (Debian 12/13) v${SCRIPT_VERSION}"
echo -e "──────────────────────────────────────────────────────────${NC}"
echo -e "Log file: ${YELLOW}${LOGFILE}${NC}"
echo
@@ -75,10 +75,12 @@ echo
need_cmd uname
need_cmd grep
need_cmd sed
-need_cmd lspci
+need_cmd awk
need_cmd apt
need_cmd dpkg
+need_cmd dpkg-query
need_cmd apt-cache
+need_cmd pgrep
need_cmd tee
# ----------------------------
@@ -88,11 +90,35 @@ KERNEL="$(uname -r)"
SESSION="${XDG_SESSION_TYPE:-unknown}"
ARCH="$(dpkg --print-architecture)"
SECURE_BOOT_ENABLED=0
+CODENAME="unknown"
+DEBIAN_VERSION="unknown"
+
+if [[ ! -r /etc/os-release ]]; then
+ die "Cannot identify the operating system: /etc/os-release is missing."
+fi
+
+# shellcheck disable=SC1091
+. /etc/os-release
+[[ "${ID:-}" == "debian" ]] || die "Unsupported distribution: ${PRETTY_NAME:-${ID:-unknown}}. This script supports Debian only."
+
+DEBIAN_VERSION="${VERSION_ID:-unknown}"
+CODENAME="${VERSION_CODENAME:-unknown}"
+case "${DEBIAN_VERSION}" in
+ 12|12.*|13|13.*) ;;
+ *) die "Unsupported Debian version: ${DEBIAN_VERSION}. Supported releases: Debian 12 and 13." ;;
+esac
+
+case "${ARCH}" in
+ amd64|arm64) ;;
+ *) die "Unsupported architecture: ${ARCH}. Supported architectures: amd64 and arm64." ;;
+esac
-info "Kernel: ${KERNEL}"
-info "Session: ${SESSION}"
+info "Debian: ${DEBIAN_VERSION} (${CODENAME})"
+info "Architecture: ${ARCH}"
+info "Kernel: ${KERNEL}"
+info "Session: ${SESSION}"
if [[ "$SESSION" == "wayland" ]]; then
- warn "Wayland session detected. Xorg config tweaks may be ignored (depends on DE)."
+ info "Wayland session detected."
fi
# Secure Boot hint (best-effort)
@@ -101,95 +127,109 @@ if command -v mokutil >/dev/null 2>&1; then
SECURE_BOOT_ENABLED=1
warn "Secure Boot appears ENABLED. Unsigned NVIDIA modules may fail to load."
warn "If the driver does not load: disable Secure Boot or enroll/sign modules (MOK)."
- warn "Tip: update-secureboot-policy --enroll-key (requires secureboot-policy package)."
fi
fi
echo
# ----------------------------
-# NVIDIA GPU detection
+# NVIDIA GPU detection (lspci first, sysfs fallback for minimal systems)
# ----------------------------
-GPU="$(lspci | grep -E "VGA|3D" | grep -i nvidia || true)"
+detect_nvidia_gpu() {
+ if command -v lspci >/dev/null 2>&1; then
+ lspci | grep -Ei 'VGA|3D|Display' | grep -i nvidia || true
+ return
+ fi
+
+ local device vendor class
+ for device in /sys/bus/pci/devices/*; do
+ [[ -r "${device}/vendor" && -r "${device}/class" ]] || continue
+ vendor="$(<"${device}/vendor")"
+ class="$(<"${device}/class")"
+ if [[ "${vendor,,}" == "0x10de" && "${class,,}" == 0x03* ]]; then
+ printf 'NVIDIA PCI display device %s (class %s)\n' "${device##*/}" "${class}"
+ fi
+ done
+}
+
+GPU="$(detect_nvidia_gpu)"
[[ -n "$GPU" ]] || die "No NVIDIA GPU detected."
ok "NVIDIA GPU detected:"
echo "$GPU"
echo
# ----------------------------
-# Debian release / codename
+# APT sources sanity (non-free + non-free-firmware)
# ----------------------------
-CODENAME="unknown"
-if [[ -r /etc/os-release ]]; then
- # shellcheck disable=SC1091
- . /etc/os-release
- CODENAME="${VERSION_CODENAME:-${CODENAME}}"
-fi
+collect_apt_source_files() {
+ APT_SOURCE_FILES=()
+ [[ -r /etc/apt/sources.list ]] && APT_SOURCE_FILES+=(/etc/apt/sources.list)
+
+ local file
+ shopt -s nullglob
+ for file in /etc/apt/sources.list.d/*.list /etc/apt/sources.list.d/*.sources; do
+ [[ -r "${file}" ]] && APT_SOURCE_FILES+=("${file}")
+ done
+ shopt -u nullglob
+}
-info "Debian codename: ${CODENAME}"
+apt_source_text() {
+ (( ${#APT_SOURCE_FILES[@]} > 0 )) || return 1
+ sed -e '/^[[:space:]]*#/d' -e '/^[[:space:]]*$/d' "${APT_SOURCE_FILES[@]}" 2>/dev/null
+}
+
+has_apt_source_token() {
+ local token="$1"
+ apt_source_text | grep -Eq "(^|[[:space:]])${token}([[:space:]]|$)"
+}
-# ----------------------------
-# APT sources sanity (non-free + non-free-firmware)
-# ----------------------------
check_nonfree_sources() {
- # Debian 12/13 typically need: main contrib non-free non-free-firmware
- local sources=()
- [[ -f /etc/apt/sources.list ]] && sources+=("/etc/apt/sources.list")
- if compgen -G "/etc/apt/sources.list.d/*.list" >/dev/null; then
- sources+=(/etc/apt/sources.list.d/*.list)
+ if (( ${#APT_SOURCE_FILES[@]} == 0 )); then
+ warn "No readable APT source files found."
+ warn "Checked /etc/apt/sources.list and /etc/apt/sources.list.d/*.{list,sources}."
+ return 1
fi
- if (( ${#sources[@]} == 0 )); then
- warn "No APT source files found in /etc/apt/sources.list or /etc/apt/sources.list.d."
+ if ! has_apt_source_token "non-free"; then
+ warn "APT sources do not seem to include: non-free"
+ warn "Enable it in your .list or deb822 .sources configuration."
return 1
fi
- local all_text
- all_text="$(cat "${sources[@]}" 2>/dev/null || true)"
-
- if ! echo "$all_text" | grep -Eq '^[[:space:]]*deb[[:space:]].*(non-free)'; then
- warn "APT sources do not seem to include: non-free"
- warn "Enable it in your sources.list (recommended for NVIDIA)."
+ if ! has_apt_source_token "contrib"; then
+ warn "APT sources do not seem to include: contrib"
+ warn "Enable it in your .list or deb822 .sources configuration."
return 1
fi
- if ! echo "$all_text" | grep -Eq '^[[:space:]]*deb[[:space:]].*(non-free-firmware)'; then
+ if ! has_apt_source_token "non-free-firmware"; then
warn "APT sources do not seem to include: non-free-firmware"
- warn "Debian 13 typically needs it for firmware packages."
+ warn "Debian 12/13 use it for firmware packages."
return 1
fi
return 0
}
+APT_SOURCE_FILES=()
+collect_apt_source_files
+
if ! check_nonfree_sources; then
echo
warn "Fix your APT sources first, then re-run this script."
- echo "Example (Debian 13 Trixie):"
- echo " deb http://deb.debian.org/debian trixie main contrib non-free non-free-firmware"
- echo " deb http://security.debian.org/debian-security trixie-security main contrib non-free non-free-firmware"
- echo " deb http://deb.debian.org/debian trixie-updates main contrib non-free non-free-firmware"
+ echo "Example for ${CODENAME}:"
+ echo " deb http://deb.debian.org/debian ${CODENAME} main contrib non-free non-free-firmware"
+ echo " deb http://security.debian.org/debian-security ${CODENAME}-security main contrib non-free non-free-firmware"
+ echo " deb http://deb.debian.org/debian ${CODENAME}-updates main contrib non-free non-free-firmware"
echo
die "APT sources missing required components."
fi
-ok "APT sources look good (non-free + non-free-firmware detected)."
+ok "APT sources look good (contrib + non-free + non-free-firmware detected)."
echo
has_suite_sources() {
local suite="$1"
- local sources=()
- [[ -f /etc/apt/sources.list ]] && sources+=("/etc/apt/sources.list")
- if compgen -G "/etc/apt/sources.list.d/*.list" >/dev/null; then
- sources+=(/etc/apt/sources.list.d/*.list)
- fi
-
- if (( ${#sources[@]} == 0 )); then
- return 1
- fi
-
- local all_text
- all_text="$(cat "${sources[@]}" 2>/dev/null || true)"
- echo "$all_text" | grep -Eq "^[[:space:]]*deb[[:space:]].*\\b${suite}\\b"
+ has_apt_source_token "${suite}"
}
# ----------------------------
@@ -200,18 +240,11 @@ check_locks() {
local timeout=120
local waited=0
- while pgrep -x apt >/dev/null 2>&1 || pgrep -x dpkg >/dev/null 2>&1; do
+ while pgrep -x apt >/dev/null 2>&1 ||
+ pgrep -x apt-get >/dev/null 2>&1 ||
+ pgrep -x dpkg >/dev/null 2>&1; do
if (( waited >= timeout )); then
- warn "APT/dpkg still running after ${timeout}s."
- warn "Killing package manager processes can BREAK your system."
- if confirm "Do you want to attempt killing apt/dpkg anyway?"; then
- warn "Attempting to kill apt/dpkg..."
- pkill -9 apt 2>/dev/null || true
- pkill -9 dpkg 2>/dev/null || true
- break
- else
- die "Please wait until apt/dpkg finishes, then re-run."
- fi
+ die "APT/dpkg is still running after ${timeout}s. Let it finish, then re-run this script."
fi
echo -ne "${YELLOW}⏳ Waiting for package manager... (${waited}s)\r${NC}"
sleep 3
@@ -219,17 +252,7 @@ check_locks() {
done
echo
- # Do NOT rm lock files blindly unless user confirms (can be dangerous)
- if [[ -e /var/lib/dpkg/lock-frontend || -e /var/lib/dpkg/lock || -e /var/cache/apt/archives/lock ]]; then
- warn "Lock files detected."
- warn "Removing lock files while apt is running can corrupt dpkg state."
- if confirm "Remove lock files now? (only do this if you are sure apt is NOT running)"; then
- rm -f /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock /var/cache/apt/archives/lock || true
- ok "Lock files removed."
- else
- warn "Keeping lock files."
- fi
- fi
+ ok "No active APT/dpkg process detected."
}
# ----------------------------
@@ -243,35 +266,6 @@ else
fi
echo
-# ----------------------------
-# Xorg config (modular)
-# ----------------------------
-ensure_xorg_conf_d() {
- mkdir -p /etc/X11/xorg.conf.d
-}
-
-write_xorg_driver_snippet() {
- # $1: driver name
- local driver="$1"
- ensure_xorg_conf_d
- cat > /etc/X11/xorg.conf.d/10-gpu-driver.conf </dev/null 2>&1; then
+ packages+=("${header_meta}")
+ else
+ warn "No architecture header metapackage found: ${header_meta}"
fi
+
if apt-cache show "linux-headers-${KERNEL}" >/dev/null 2>&1; then
packages+=("linux-headers-${KERNEL}")
else
warn "No exact headers for running kernel found: linux-headers-${KERNEL}"
- warn "Consider rebooting into the newest kernel or installing linux-headers-${ARCH}."
+ warn "The ${header_meta} metapackage will install headers for Debian's current kernel."
+ warn "Reboot into that kernel before expecting the NVIDIA DKMS module to load."
fi
apt install -y --no-install-recommends "${packages[@]}"
}
@@ -313,32 +313,29 @@ unblacklist_nouveau() {
# NVIDIA remove/clean
# ----------------------------
remove_nvidia() {
- local installed
- installed="$(dpkg-query -W -f='${Package}\n' 'nvidia-*' 2>/dev/null || true)"
- if [[ -n "${installed}" ]]; then
- warn "Installed NVIDIA-related packages that may be removed:"
- echo "${installed}"
- warn "This includes CUDA-related packages that match nvidia-*."
+ local installed=()
+ mapfile -t installed < <(
+ dpkg-query -W -f='${binary:Package}\t${db:Status-Status}\n' 2>/dev/null |
+ awk '$2 == "installed" && $1 ~ /^nvidia-/ { print $1 }'
+ )
+
+ if (( ${#installed[@]} > 0 )); then
+ warn "Installed nvidia-* packages that will be removed:"
+ printf ' %s\n' "${installed[@]}"
+ progress "Purging NVIDIA packages"
+ apt purge -y "${installed[@]}"
else
- info "No installed NVIDIA-related packages detected."
+ info "No installed nvidia-* packages detected."
fi
- progress "Purging NVIDIA packages"
- apt purge -y 'nvidia-*' || true
-
progress "Autoremoving unused deps"
- apt autoremove -y || true
+ apt autoremove -y
- progress "Cleaning DKMS remnants (best-effort)"
- rm -rf /var/lib/dkms/nvidia* 2>/dev/null || true
-
- progress "Removing old modprobe snippets (best-effort)"
- rm -f /etc/modprobe.d/nvidia*.conf 2>/dev/null || true
+ unblacklist_nouveau
progress "Updating initramfs"
update-initramfs -u
- remove_xorg_driver_snippet
ok "NVIDIA removed."
}
@@ -350,6 +347,9 @@ install_cuda_toolkit_debian() {
warn "Note: This may not be the newest CUDA version, but it is Debian-managed and stable."
warn "If you need the newest CUDA, consider NVIDIA's official repo:"
warn "https://developer.nvidia.com/cuda-downloads (use with caution on Debian)."
+ if ! apt-cache show nvidia-cuda-toolkit >/dev/null 2>&1; then
+ die "nvidia-cuda-toolkit is unavailable. Verify that non-free is enabled and apt update succeeded."
+ fi
apt install -y nvidia-cuda-toolkit
ok "CUDA Toolkit installed (Debian package)."
echo
@@ -377,33 +377,18 @@ check_locks
handle_secure_boot() {
if (( SECURE_BOOT_ENABLED == 1 )); then
warn "Secure Boot is enabled. NVIDIA DKMS modules may require MOK enrollment."
- if confirm "Install secureboot-policy and enroll MOK now?"; then
- apt update
- apt install -y secureboot-policy kmod
- if command -v update-secureboot-policy >/dev/null 2>&1; then
- update-secureboot-policy --enroll-key || true
- else
- warn "update-secureboot-policy not found. Please enroll MOK manually."
- fi
- warn "You may be prompted to set a MOK password and reboot to enroll."
+ warn "Debian DKMS normally stores its enrollment certificate at /var/lib/dkms/mok.pub."
+ warn "After installation, import it with mokutil --import /var/lib/dkms/mok.pub, then reboot and enroll it in MOK Manager."
+ if ! confirm "Continue with Secure Boot enabled?"; then
+ die "Aborted."
fi
fi
}
-should_write_xorg_snippet() {
- if [[ "${SESSION}" == "wayland" || "${SESSION}" == "unknown" ]]; then
- warn "Wayland/unknown session detected. Xorg snippets may be ignored."
- confirm "Write Xorg driver snippet anyway?"
- return $?
- fi
- return 0
-}
-
case "${CHOICE}" in
1)
info "Installing NVIDIA driver from Debian stable repo..."
handle_secure_boot
- remove_nvidia
unblacklist_nouveau
install_common_deps
@@ -414,17 +399,12 @@ case "${CHOICE}" in
progress "Updating initramfs"
update-initramfs -u
- if should_write_xorg_snippet; then
- write_xorg_driver_snippet "nvidia"
- fi
-
ok "Driver installation finished (Debian stable repo)."
;;
2)
info "Installing NVIDIA driver from Debian backports..."
handle_secure_boot
- remove_nvidia
unblacklist_nouveau
install_common_deps
@@ -449,10 +429,6 @@ case "${CHOICE}" in
progress "Updating initramfs"
update-initramfs -u
- if should_write_xorg_snippet; then
- write_xorg_driver_snippet "nvidia"
- fi
-
ok "Driver installation finished (backports)."
;;
@@ -463,24 +439,16 @@ case "${CHOICE}" in
progress "Installing nouveau Xorg driver"
apt install -y xserver-xorg-video-nouveau
- unblacklist_nouveau
progress "Updating initramfs"
update-initramfs -u
- if should_write_xorg_snippet; then
- write_xorg_driver_snippet "nouveau"
- fi
-
ok "Nouveau enabled."
;;
4)
info "Removing NVIDIA driver and cleaning system..."
remove_nvidia
-
- # Prefer modesetting: no explicit snippet needed
- remove_xorg_driver_snippet
- ok "System cleaned. Using default modesetting (no forced Xorg driver)."
+ ok "System cleaned. Nouveau is no longer blacklisted by this script."
;;
5)
@@ -490,6 +458,8 @@ case "${CHOICE}" in
die "Aborted."
fi
+ [[ "${ARCH}" == "amd64" ]] || die "The advanced .run installer option currently supports amd64 only."
+
need_cmd curl
need_cmd wget
@@ -503,24 +473,20 @@ case "${CHOICE}" in
handle_secure_boot
remove_nvidia
- unblacklist_nouveau
install_common_deps
mkdir -p /root/nvidia-install
cd /root/nvidia-install
- warn "Fetching latest driver version (best-effort)..."
- # Keep a safe fallback; API endpoints can change.
- LATEST="$(curl -fsSL https://api.nvidia.com/v1/driver-latest-version/linux 2>/dev/null | grep -oP '"version":"\K[0-9.]+' || true)"
- if [[ -z "${LATEST}" ]]; then
- LATEST="580.95.05"
- warn "Could not fetch latest version. Using fallback: ${LATEST}"
- else
- ok "Latest NVIDIA version detected: ${LATEST}"
- fi
+ warn "Fetching NVIDIA's current Linux x86_64 driver metadata..."
+ LATEST_LINE="$(curl -fsSL https://download.nvidia.com/XFree86/Linux-x86_64/latest.txt)" || die "Could not fetch NVIDIA driver metadata."
+ read -r LATEST RUN_PATH _ <<<"${LATEST_LINE}"
+ [[ "${LATEST}" =~ ^[0-9]+(\.[0-9]+)+$ ]] || die "NVIDIA returned an invalid driver version: ${LATEST:-empty}"
+ [[ "${RUN_PATH}" == "${LATEST}/NVIDIA-Linux-x86_64-${LATEST}.run" ]] || die "NVIDIA returned an unexpected download path."
+ ok "Latest NVIDIA version detected: ${LATEST}"
progress "Downloading NVIDIA-Linux-x86_64-${LATEST}.run"
- wget -O NVIDIA-Linux.run "https://us.download.nvidia.com/XFree86/Linux-x86_64/${LATEST}/NVIDIA-Linux-x86_64-${LATEST}.run"
+ wget -O NVIDIA-Linux.run "https://download.nvidia.com/XFree86/Linux-x86_64/${RUN_PATH}"
chmod +x NVIDIA-Linux.run
@@ -535,10 +501,6 @@ case "${CHOICE}" in
progress "Updating initramfs"
update-initramfs -u
- if should_write_xorg_snippet; then
- write_xorg_driver_snippet "nvidia"
- fi
-
ok ".run driver installation finished (advanced)."
;;