diff --git a/README.md b/README.md index 8185855..a33ebe1 100755 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Reference harness (auto-cloned into `harness/` by preflight): - **sudo privileges** — precondition for `--preflight` package installation and for privileged checks (PCI rescan, link retrain, sysfs ROM, `dmesg`, `verify.sh`) - `pciutils` (`lspci`, `setpci`), `git` — installed automatically by preflight - NVIDIA driver with `nvidia-smi` (nvidia-open 610.xx+, see cmpunlocker) for unlock verification — preflight can install it for you (asks first) -- `nvflash` (not packaged for Ubuntu — manual install, see [Installing nvflash](#installing-nvflash-manual--not-packaged-for-ubuntu) below; or pass `--nvflash /path/to/nvflash`) for VBIOS backup and serial auto-read +- `nvflash` — **bundled in this repo** (`nvflash_5.867_linux/x64/nvflash`), used directly by the script; no system install needed (see [nvflash](#nvflash-bundled-in-this-repo)) - Optional: `vkmark` or `vulkan-tools` for the 5-minute VRAM stress test ## Preflight (setup step) @@ -28,46 +28,46 @@ On Ubuntu 26.04 this: 2. Installs required packages via `apt-get update && apt-get install`: `git`, `pciutils`, `vulkan-tools`, `vkmark` 3. Offers to install the **NVIDIA driver** (`ubuntu-drivers install`, falling back to the `nvidia-driver` metapackage) when `nvidia-smi` is missing — reboot afterwards 4. Clones the two harness repos into `harness/` -5. Prints a tool status table; `nvflash` is reported with manual-install instructions (not packaged) +5. Prints a tool status table — the bundled `nvflash` is detected automatically and its path is shown Skip installation with `--no-install` (no sudo needed at all). -## Installing nvflash (manual — not packaged for Ubuntu) +## nvflash (bundled in this repo) -`nvflash` ships no `.deb` for Ubuntu/Debian. Install NVIDIA's official Linux build -(TechPowerUp hosts it): +The Linux build of NVIDIA's `nvflash` 5.867 is committed to this repo at +`nvflash_5.867_linux/x64/nvflash` (plus `aarch64`/`ppc64`/`x86` variants) — the script +uses it **directly**, no system-wide installation required. + +Binary resolution order: + +1. `--nvflash /path/to/nvflash` (explicit override) +2. repo copy: `nvflash_*_linux//nvflash`, then `./nvflash` +3. `nvflash` on `PATH` (optional system install) + +Preflight reports `nvflash OK` and prints the resolved path. ```bash -# 1. deps + download -sudo apt install -y unzip -cd ~/Downloads -# get it from: https://www.techpowerup.com/download/nvidia-nvflash/ -# (Linux build: nvflash_5.867_linux.zip) - -# 2. verify integrity (SHA256 for the 5.867 linux zip) -echo "73ab51e121129059f1377b3bf21a8001f6649d64af2471455499c803a9c80301 nvflash_5.867_linux.zip" | sha256sum -c - -# 3. extract + install system-wide -unzip -o nvflash_5.867_linux.zip -d /tmp/nvflash -sudo install -m 755 "$(find /tmp/nvflash -type f -name 'nvflash' | head -1)" /usr/local/bin/nvflash - -# 4. sanity check -nvflash --version # or: nvflash --help -sudo nvflash --list # must show the 170HX -``` - -Then re-run preflight — the tool table should show `nvflash OK`: - -```bash -python3 check_cards.py --preflight +python3 check_cards.py --preflight # shows: nvflash OK / nvflash: /nvflash_5.867_linux/x64/nvflash ``` Notes: -- The script invokes nvflash through `sudo` — cache credentials first (`sudo -v`) or run the script as root. +- nvflash requires root: the script invokes it via `sudo` — cache credentials with `sudo -v` first, or run the script as root. - Only `--save` (read-only backup) is used; if it fails while the NVIDIA driver is bound, the script automatically falls back to the sysfs ROM method. - Do **not** use the AUR nvflash package (known broken), and ignore Windows `.exe` builds. -- Alternative: point the script at a custom location with `--nvflash /path/to/nvflash`. + +Optional — install it system-wide anyway: + +```bash +sudo install -m 755 nvflash_5.867_linux/x64/nvflash /usr/local/bin/nvflash +nvflash --version +sudo nvflash --list # must show the 170HX +``` + +Refreshing the bundled copy: download `nvflash_5.867_linux.zip` from +https://www.techpowerup.com/download/nvidia-nvflash/ , verify SHA256 +`73ab51e121129059f1377b3bf21a8001f6649d64af2471455499c803a9c80301`, extract and replace +the files (keep the executable bit: `chmod +x`). ## Usage (one card per run) diff --git a/cxlib.py b/cxlib.py index 37bfec7..3edae21 100755 --- a/cxlib.py +++ b/cxlib.py @@ -102,6 +102,23 @@ def which(name): return shutil.which(name) +def find_nvflash(): + """nvflash binary: repo-bundled copy first (no system install needed), then PATH.""" + import platform + arch_map = {"x86_64": "x64", "amd64": "x64", "aarch64": "aarch64", + "ppc64le": "ppc64", "ppc64": "ppc64", "i686": "x86", "i386": "x86"} + arch = arch_map.get(platform.machine(), "x64") + candidates = [ + *sorted(SCRIPT_DIR.glob(f"nvflash_*_linux/{arch}/nvflash")), + *sorted(SCRIPT_DIR.glob("nvflash_*_linux/x64/nvflash")), + SCRIPT_DIR / "nvflash", + ] + for p in candidates: + if p.is_file() and os.access(p, os.X_OK): + return str(p) + return which("nvflash") + + def have_root(): return os.geteuid() == 0 or bool(shutil.which("sudo")) @@ -159,7 +176,7 @@ TOOL_CHECKS = { "lspci": ("critical", "PCIe checks (package: pciutils)"), "setpci": ("critical", "link generation probe (package: pciutils)"), "nvidia-smi": ("critical-if-card-present", "GPU state / cmpunlocker verify"), - "nvflash": ("critical", "VBIOS backup + serial (not packaged: manual install)"), + "nvflash": ("critical", "VBIOS backup + serial (bundled in repo, or on PATH)"), "dmesg": ("optional", "kernel log scrape"), "journalctl": ("optional", "kernel log scrape fallback"), "vulkaninfo": ("optional", "vulkan presence (package: vulkan-tools)"), @@ -230,7 +247,7 @@ def preflight(auto_install=True, do_clone=True): info(f"OS: {report['os']['pretty']}") for tool, (level, why) in TOOL_CHECKS.items(): - path = which(tool) + path = find_nvflash() if tool == "nvflash" else which(tool) report["tools"][tool] = {"found": bool(path), "path": path, "level": level, "why": why} if not path: (critical_missing if level.startswith("critical") else optional_missing).append(tool) @@ -300,10 +317,12 @@ def preflight(auto_install=True, do_clone=True): mark = f"{C.YELLOW}missing (optional){C.RESET}" print(f" {t:<14} {mark} {C.DIM}{st['why']}{C.RESET}") - if not which("nvflash"): - warn("nvflash missing - VBIOS backup will fall back to sysfs ROM, serial to manual entry") - print(" Download Linux x64 nvflash from https://www.nvidia.com/en-us/drivers/nvflash/") - print(" and pass --nvflash /path/to/nvflash, or place it on PATH.") + if not find_nvflash(): + warn("nvflash not found - VBIOS backup will fall back to sysfs ROM, serial to manual entry") + print(" Bundle it in the repo: nvflash__linux/x64/nvflash (chmod +x),") + print(" or pass --nvflash /path/to/nvflash, or place it on PATH.") + else: + info(f"nvflash: {find_nvflash()}") if not which("nvidia-smi"): warn("nvidia-smi missing - cmpunlocker verify will be skipped (install nvidia-open driver)") if not report["root"]: @@ -512,7 +531,9 @@ def dmesg_capture(bdf): # ---------------------------------------------------------------- BIOS / serial def nvflash_bin(args): - return args.nvflash if getattr(args, "nvflash", None) else which("nvflash") + if getattr(args, "nvflash", None): + return args.nvflash + return find_nvflash() def nvflash_list(nf):