Hardware

Linux eGPU Startup Script Reference (Sonnet 850T5)

The recovered egpu.sh for an RTX PRO 5000 Blackwell in a Sonnet 850T5 under Linux, block by block — runtime power control, the Link Control 2 poke, persistence mode, power cap, audio unbind — with what each step does and how its rationale is sourced.

Run it as root, after hot-plugging the enclosure and before any CUDA workload (full workflow: the eGPU setup guide).

What this page answers: what each block of the recovered eGPU startup script does, and how far each rationale is verified — captured on the machine or stated in the recovery notes.

Provenance and evidence labels

The script below was recovered from the host’s file library and reproduced verbatim. For every “why”, this page labels the source:

  • (captured) — stated in a comment in the recovered script, or measured on the machine.
  • (author-stated, assumed) — the rationale recorded with the recovery notes; no without-test has been run to prove the failure it prevents.

The script

#!/usr/bin/env bash
set -euo pipefail

GPU="${GPU:-0000:63:00.0}"
AUDIO="${AUDIO:-0000:63:00.1}"
POWER_LIMIT="${POWER_LIMIT:-275}"

PCIE_PATH=("0000:00:01.2" "0000:61:00.0" "0000:62:00.0" "$GPU" "$AUDIO")
SHORT_PCIE_SETPCI=("00:01.2" "61:00.0" "62:00.0" "63:00.0")

# Detection and verification
lspci -nn -s "$GPU"
lspci -nn -s "$AUDIO" || true

# Runtime power and link behavior
for dev in "${PCIE_PATH[@]}"; do echo on | sudo tee "/sys/bus/pci/devices/$dev/power/control"; done
for dev in "${SHORT_PCIE_SETPCI[@]}"; do sudo setpci -s "$dev" CAP_EXP+30.w=0020:0020; done

sudo nvidia-smi -pm 1
sudo nvidia-smi -pl "$POWER_LIMIT"

# Optional compute-focused cleanup
if [[ -e "/sys/bus/pci/devices/$AUDIO/driver/unbind" ]]; then
  echo "$AUDIO" | sudo tee "/sys/bus/pci/devices/$AUDIO/driver/unbind"
fi

nvidia-smi
lspci -vv -s "$GPU" | grep -Ei "LnkCap|LnkSta|LnkCtl" || true

Block by block

1. Parameters with recovered defaults (not dynamic discovery)

GPU="${GPU:-0000:63:00.0}"
AUDIO="${AUDIO:-0000:63:00.1}"
POWER_LIMIT="${POWER_LIMIT:-275}"

The script is parameterized, not auto-discovering: defaults are aibox1’s recovered addresses and power cap, overridable via environment. The GPU BDF was found with lspci -nn | grep -Ei "10de|nvidia|vga|3d|display"; the audio function is its sibling (63:00.1, PCI ID 10de:22e8 on this card). To use the pattern elsewhere, set GPU/AUDIO to your own values first.

2. Detection gate (fails fast if the eGPU isn’t there)

lspci -nn -s "$GPU"
lspci -nn -s "$AUDIO" || true

Under set -euo pipefail, a missing GPU aborts the script immediately — so running it while the enclosure is unplugged is a safe, fast error instead of a silent mis-configuration. The audio check tolerates absence. (captured)

3. Runtime power control = on, across the whole path

PCIE_PATH=("0000:00:01.2" "0000:61:00.0" "0000:62:00.0" "$GPU" "$AUDIO")
for dev in "${PCIE_PATH[@]}"; do echo on | sudo tee "/sys/bus/pci/devices/$dev/power/control"; done

Sets sysfs power/control to on on five devices: the host Thunderbolt root port (00:01.2), the Sonnet’s upstream “Barlow Ridge” bridge (61:00.0), the downstream bridge to the slot (62:00.0), the GPU and its audio function — keeping the entire chain out of PCI runtime autosuspend while CUDA workloads are prepared. (author-stated, assumed) No without-test has recorded what exactly degrades when this is skipped.

SHORT_PCIE_SETPCI=("00:01.2" "61:00.0" "62:00.0" "63:00.0")
for dev in "${SHORT_PCIE_SETPCI[@]}"; do sudo setpci -s "$dev" CAP_EXP+30.w=0020:0020; done

CAP_EXP+30.w is the PCIe Link Control 2 register (offset 0x30); the write sets bit 5 (value 0x0020, mask 0x0020) on the root port, both bridges and the GPU itself — not just the downstream bridge. Per the recovery notes this is the same workaround seen in RTX PRO 6000 eGPU reports: it disables problematic link-speed auto behavior while still allowing the GPU to ramp under load. (author-stated, assumed; cross-referenced with PRO 6000 eGPU reports) No without-test has recorded the concrete symptom it prevents.

5. Persistence mode

sudo nvidia-smi -pm 1

Keeps the NVIDIA driver initialized between CUDA workloads, reducing reinitialization time and hot-plug sensitivity. (author-stated, assumed)

6. Power cap at 275 W

POWER_LIMIT="${POWER_LIMIT:-275}"
sudo nvidia-smi -pl "$POWER_LIMIT"

Deliberately below the RTX PRO 5000 Blackwell’s 300 W default class, to keep the eGPU enclosure and transient behavior conservative. The stock default is confirmed by nvidia-smi on a directly attached 48 GB card (the aibox2 baseline: current/requested 250 W idle, default 300 W). Callers can pass POWER_LIMIT=... to experiment. (captured: 275 < 300 W stock; the “conservative for enclosure” rationale is author-stated)

7. Unbind the GPU audio function (conditional)

if [[ -e "/sys/bus/pci/devices/$AUDIO/driver/unbind" ]]; then
  echo "$AUDIO" | sudo tee "/sys/bus/pci/devices/$AUDIO/driver/unbind"
fi

The HDMI/DP audio endpoint is not needed for compute and can complicate suspend/hot-plug behavior, so the script unbinds it — but only when a bound driver is actually present (the -e guard makes the step conditional rather than fatal). (author-stated, assumed) The exact failure this prevents has not been recorded.

8. Verify before workloads

nvidia-smi
lspci -vv -s "$GPU" | grep -Ei "LnkCap|LnkSta|LnkCtl" || true

Healthy state: nvidia-smi lists the card with the cap applied, and the link lines show the negotiated speed/width. Note the idle expectation on this chain: LnkCap 32GT/s x16 (Gen5-capable) but LnkSta 2.5GT/s x4 at idle — idle downshifts are normal; verify under load, not from a cold snapshot. (captured: the link values)

Notes on running it

  • Workflow (recovered): boot with the Sonnet disconnected → log in → hot-plug the enclosure → run this script before any CUDA workload. It is a manual step, not a systemd unit, in everything recovered so far.
  • Re-running after re-plug: the script reapplies all state from scratch (power control, link poke, persistence, cap, audio unbind), so running it again after an unplug/re-plug cycle is the expected flow; observed unplug behavior has not been recorded separately.
  • The full script is reproduced above from the recovery document (notes/aibox-egpu-recovery-guide-updated.docx in the project notes); keep any edits to the on-host copy and this page in sync.

Sources and upstream documentation

  • bolt — the Thunderbolt host service the workflow depends on.
  • setpci(8) — the register-level command used for the Link Control 2 workaround.
  • nvidia-smi documentation — power-limit and persistence-mode fields the script sets.