feat(gpu): universal NVIDIA lane — detect + install branch at boot (Sam & Claude)
Opt-in NVIDIA_UNIVERSAL lane (default NO; normal/single-branch builds unchanged): one ISO that adapts to an unknown NVIDIA target. - build.cfg: NVIDIA_UNIVERSAL flag. - build.sh: install_nvidia_universal_repo() stages an on-image pkg repo with all three branches (390/470/580 + settings), pkg-repo metadata, and a file:// repo conf; universal mode bakes no branch and sets clawdie_live_gpu_mode=nvidia-auto. - clawdie_live_gpu: nvidia-auto mode detects the device id (PR #30 fix) -> branch {390,470,590} -> pkg-name -> `pkg install -r clawdie-nvidia` -> kldload, all best-effort with fallback to integrated/scfb (never blocks boot). - doc/NVIDIA-UNIVERSAL-HANDOFF.md: Codex FreeBSD build + hardware validation plan. sh -n clean; detector+branch+pkg map unit-tested on Linux (1c8c->590->nvidia-driver-580, 0fc8->470, 0e22->390). The pkg fetch/repo layout, offline boot install, writable root, kernel ABI, and image size MUST be validated on the FreeBSD build host + real NVIDIA hardware (see handoff). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
49794906eb
commit
a9323aeddc
4 changed files with 194 additions and 0 deletions
|
|
@ -43,6 +43,14 @@ DEFAULT_DESKTOP="xfce" # operator USB desktop
|
|||
# intel | amd | nvidia-590 | nvidia-470 | nvidia-390 | vesa | "" (auto-detect)
|
||||
GPU_DRIVER=""
|
||||
|
||||
# Universal NVIDIA lane (opt-in). When YES, the image carries an on-image NVIDIA
|
||||
# pkg repo for all three branches (390/470/580), does NOT bake a single branch,
|
||||
# and clawdie_live_gpu runs in "nvidia-auto": at boot it detects the GPU, installs
|
||||
# the matching branch from the on-image repo, and kldloads it before SDDM. On any
|
||||
# failure it falls back to the integrated/scfb path (never worse than today).
|
||||
# Builds a larger image. Leave NO for single-branch GPU_DRIVER=nvidia-* builds.
|
||||
NVIDIA_UNIVERSAL="${NVIDIA_UNIVERSAL:-NO}"
|
||||
|
||||
# Deploy target
|
||||
TARGET="baremetal" # vps | baremetal
|
||||
|
||||
|
|
|
|||
53
build.sh
53
build.sh
|
|
@ -119,6 +119,7 @@ echo " Clawdie : ${CLAWDIE_REF}"
|
|||
echo " Desktop : ${DEFAULT_DESKTOP}"
|
||||
echo " Pkg : ${DEFAULT_PKG_BRANCH}"
|
||||
echo " GPU : ${GPU_DRIVER:-auto-detect}"
|
||||
echo " NVIDIA universal : ${NVIDIA_UNIVERSAL:-NO}"
|
||||
echo " Target : ${TARGET:-baremetal}"
|
||||
echo " Colibri : ${FEATURE_COLIBRI:-NO}"
|
||||
echo " Clawdie agent : ${FEATURE_CLAWDIE:-NO}"
|
||||
|
|
@ -906,6 +907,48 @@ install_clawdie_service() {
|
|||
fi
|
||||
}
|
||||
|
||||
# Stage an on-image NVIDIA pkg repo (all branches) so clawdie_live_gpu can
|
||||
# `pkg install` the detected branch at boot (NVIDIA_UNIVERSAL lane).
|
||||
#
|
||||
# FreeBSD-build-host step (authored on Linux; runs + must be validated on
|
||||
# FreeBSD). Verify on the build host: (1) the `pkg fetch -o` layout matches what
|
||||
# `pkg repo` expects, (2) the dependency closure is complete for offline boot
|
||||
# install, (3) image size headroom, (4) `pkg install -r clawdie-nvidia` resolves
|
||||
# from file:// at boot. See doc handoff.
|
||||
install_nvidia_universal_repo() {
|
||||
[ "${NVIDIA_UNIVERSAL:-NO}" = "YES" ] || {
|
||||
echo " NVIDIA universal repo staging disabled (NVIDIA_UNIVERSAL=${NVIDIA_UNIVERSAL:-NO})"
|
||||
return 0
|
||||
}
|
||||
|
||||
echo " Staging universal NVIDIA repo (all branches) into image..."
|
||||
_nv_repo="${MOUNT_POINT}/usr/local/share/clawdie/nvidia-repo"
|
||||
mkdir -p "${_nv_repo}"
|
||||
|
||||
# Fetch all three branches + deps into the on-image repo dir, then build repo
|
||||
# metadata. Uses pkg's own dependency resolution so the closure is complete.
|
||||
if ! env ASSUME_ALWAYS_YES=yes pkg fetch -y -o "${_nv_repo}" -d \
|
||||
nvidia-driver-390 nvidia-driver-470 nvidia-driver-580 nvidia-settings nvidia-xconfig; then
|
||||
echo "ERROR: failed to fetch NVIDIA packages for universal repo"
|
||||
exit 1
|
||||
fi
|
||||
if ! pkg repo "${_nv_repo}"; then
|
||||
echo "ERROR: failed to generate NVIDIA universal repo metadata"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "${MOUNT_POINT}/usr/local/etc/pkg/repos"
|
||||
cat > "${MOUNT_POINT}/usr/local/etc/pkg/repos/clawdie-nvidia.conf" <<'EOF'
|
||||
# On-image NVIDIA package repo for the universal GPU lane. Consumed at boot by
|
||||
# clawdie_live_gpu (nvidia-auto mode) via: pkg install -r clawdie-nvidia ...
|
||||
clawdie-nvidia: {
|
||||
url: "file:///usr/local/share/clawdie/nvidia-repo",
|
||||
enabled: yes
|
||||
}
|
||||
EOF
|
||||
echo " NVIDIA universal repo staged at /usr/local/share/clawdie/nvidia-repo"
|
||||
}
|
||||
|
||||
install_live_npm_globals() {
|
||||
echo " Installing bundled npm globals into live image..."
|
||||
|
||||
|
|
@ -1561,6 +1604,15 @@ EOF
|
|||
;;
|
||||
esac
|
||||
|
||||
# Universal NVIDIA lane: no branch is baked; clawdie_live_gpu installs the
|
||||
# matching one from the on-image repo at boot. Overrides the mode set above.
|
||||
# kld_list intentionally does NOT preload nvidia (it is not installed yet at
|
||||
# first boot); the rc.d service kldloads it after install.
|
||||
if [ "${NVIDIA_UNIVERSAL:-NO}" = "YES" ]; then
|
||||
set_config_line "${MOUNT_POINT}/etc/rc.conf" 'clawdie_live_gpu_mode="nvidia-auto"'
|
||||
set_config_line "${MOUNT_POINT}/etc/rc.conf" 'clawdie_live_gpu_nvidia_branch=""'
|
||||
fi
|
||||
|
||||
mkdir -p "${MOUNT_POINT}/etc/ssh/sshd_config.d"
|
||||
install -m 0644 "${LIVE_SESSION_DIR}/sshd-live.conf" \
|
||||
"${MOUNT_POINT}/etc/ssh/sshd_config.d/clawdie-live.conf"
|
||||
|
|
@ -2158,6 +2210,7 @@ install_live_runtime_packages
|
|||
configure_live_operator_session
|
||||
install_colibri_service
|
||||
install_clawdie_service
|
||||
install_nvidia_universal_repo
|
||||
|
||||
# Copy payload
|
||||
# Rebuild payload paths from scratch inside the reusable work image. A failed
|
||||
|
|
|
|||
74
doc/NVIDIA-UNIVERSAL-HANDOFF.md
Normal file
74
doc/NVIDIA-UNIVERSAL-HANDOFF.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# NVIDIA universal lane — Codex build + hardware validation handoff
|
||||
|
||||
**From:** Claude (Linux) · **To:** Codex ISO Builder (FreeBSD 15 host)
|
||||
**Goal:** one ISO that boots on any NVIDIA machine — detect the GPU pre-SDDM,
|
||||
install the matching branch from an on-image repo, kldload it, then SDDM/XFCE.
|
||||
|
||||
Authored on Linux (sh -n clean; detector + branch/pkg map unit-tested). The
|
||||
package/boot behavior **must be built and proven on FreeBSD + real NVIDIA
|
||||
hardware** — it cannot be validated from Linux.
|
||||
|
||||
## What landed (behind `NVIDIA_UNIVERSAL`, default NO — normal builds unaffected)
|
||||
|
||||
- `build.cfg`: `NVIDIA_UNIVERSAL` flag.
|
||||
- `build.sh`:
|
||||
- `install_nvidia_universal_repo()` — `pkg fetch -d` the three families
|
||||
(`nvidia-driver-390/470/580` + settings) into
|
||||
`/usr/local/share/clawdie/nvidia-repo`, `pkg repo` it, write
|
||||
`/usr/local/etc/pkg/repos/clawdie-nvidia.conf` (file:// , enabled).
|
||||
- In universal mode: no branch baked into the root; rc.conf
|
||||
`clawdie_live_gpu_mode="nvidia-auto"`.
|
||||
- `live/operator-session/clawdie-live-gpu` (`nvidia-auto` mode): detect device id
|
||||
→ branch {390,470,590} → `pkg install -r clawdie-nvidia nvidia-driver-<n>
|
||||
nvidia-settings` → kldload via existing select/load. **Best-effort:** any
|
||||
failure falls through to the integrated/scfb path — never worse than today.
|
||||
|
||||
## Must verify on the FreeBSD build host
|
||||
|
||||
1. **`pkg fetch -o` / `pkg repo` layout** — confirm `pkg fetch -y -o DIR -d ...`
|
||||
places archives where `pkg repo DIR` expects them; adjust if `pkg repo` needs
|
||||
`DIR/All`. Confirm the dependency closure is complete (offline boot install
|
||||
must not reach the network).
|
||||
2. **Boot install command** — `pkg install -y -r clawdie-nvidia nvidia-driver-470
|
||||
nvidia-settings` resolves purely from the file:// repo with no network.
|
||||
3. **Writable root at boot** — the USB-root install must allow `pkg install`
|
||||
before SDDM (it does on a real on-USB FreeBSD; confirm).
|
||||
4. **Kernel ABI** — the staged kmod packages must match the image's kernel.
|
||||
5. **Image size** — three branches + deps add several hundred MB; confirm
|
||||
headroom against `IMAGE_SIZE`.
|
||||
6. **Exactly one branch** installed at boot (no mixing).
|
||||
|
||||
## Build commands
|
||||
|
||||
```sh
|
||||
# colibri artifacts first (do NOT cargo clean after)
|
||||
cd /home/clawdie/colibri && git fetch origin && git reset --hard origin/main
|
||||
cargo build --workspace --release
|
||||
|
||||
# universal image (set COLIBRI_REPO explicitly if building from a tmp worktree)
|
||||
cd /home/clawdie/clawdie-iso && git fetch origin && git reset --hard origin/main
|
||||
sudo env NVIDIA_UNIVERSAL=YES FEATURE_CLAWDIE=YES \
|
||||
COLIBRI_REPO=/home/clawdie/colibri \
|
||||
CLAWDIE_ARTIFACT_DIR=/home/clawdie/colibri/target/release \
|
||||
./build.sh --skip-memstick-fetch --live-default-password
|
||||
```
|
||||
|
||||
## Hardware acceptance
|
||||
|
||||
1. Boot on the NVIDIA target.
|
||||
2. `cat /var/log/clawdie-live-gpu.log` — expect: detected device id, chosen
|
||||
branch + pkg, "installed nvidia-driver-<n>", selected/loaded modules.
|
||||
3. `kldstat | grep nvidia` and SDDM → XFCE comes up accelerated.
|
||||
4. If install/load failed, the log shows the fallback and the desktop still
|
||||
comes up on integrated/scfb (no hard failure).
|
||||
|
||||
## Deletion criteria
|
||||
|
||||
Delete this handoff once a `NVIDIA_UNIVERSAL=YES` image has, on real NVIDIA
|
||||
hardware, auto-installed the correct branch and reached XFCE — with the result
|
||||
recorded below.
|
||||
|
||||
## Results
|
||||
|
||||
_(Codex: build host, GPU model + device id, branch chosen, pkg install outcome,
|
||||
image size delta, SDDM/XFCE result.)_
|
||||
|
|
@ -79,6 +79,57 @@ clawdie_live_gpu_nvidia_branch_for_device()
|
|||
fi
|
||||
}
|
||||
|
||||
# Map a branch label {390,470,590} to the on-image pkg name. The "590" lane is
|
||||
# the current driver, which is the nvidia-driver-580 package.
|
||||
clawdie_live_gpu_nvidia_pkg_for_branch()
|
||||
{
|
||||
case "$1" in
|
||||
390) echo "nvidia-driver-390" ;;
|
||||
470) echo "nvidia-driver-470" ;;
|
||||
590) echo "nvidia-driver-580" ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# nvidia-auto mode: detect the GPU, install the matching branch from the on-image
|
||||
# clawdie-nvidia repo, and leave /boot/modules/nvidia.ko in place for select to
|
||||
# load. Fully best-effort: any failure just logs and returns, so the caller falls
|
||||
# back to the integrated/scfb path. Never blocks boot.
|
||||
clawdie_live_gpu_install_nvidia()
|
||||
{
|
||||
_blocks="$1"
|
||||
|
||||
# Already installed (e.g. a previous boot) — nothing to do.
|
||||
if [ -e /boot/modules/nvidia.ko ]; then
|
||||
clawdie_live_gpu_log "nvidia.ko already present; skipping auto-install"
|
||||
return 0
|
||||
fi
|
||||
|
||||
_device_id=$(clawdie_live_gpu_nvidia_device_id "$_blocks" || true)
|
||||
_branch=$(clawdie_live_gpu_nvidia_branch_for_device "$_device_id")
|
||||
_pkg=$(clawdie_live_gpu_nvidia_pkg_for_branch "$_branch") || {
|
||||
clawdie_live_gpu_log "WARN: no package mapping for branch ${_branch}; skipping NVIDIA auto-install"
|
||||
return 1
|
||||
}
|
||||
clawdie_live_gpu_log "nvidia-auto: device ${_device_id:-unknown} -> branch ${_branch} (${_pkg})"
|
||||
|
||||
if ! command -v pkg >/dev/null 2>&1; then
|
||||
clawdie_live_gpu_log "WARN: pkg not available; cannot auto-install NVIDIA"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Install only from the on-image repo so this works offline and never reaches
|
||||
# the network during boot.
|
||||
if env ASSUME_ALWAYS_YES=yes pkg install -y -r clawdie-nvidia "${_pkg}" nvidia-settings \
|
||||
>> "$LOG_FILE" 2>&1; then
|
||||
clawdie_live_gpu_log "nvidia-auto: installed ${_pkg}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
clawdie_live_gpu_log "WARN: nvidia-auto install of ${_pkg} failed; falling back to integrated/scfb"
|
||||
return 1
|
||||
}
|
||||
|
||||
clawdie_live_gpu_has_pci_vendor()
|
||||
{
|
||||
_blocks="$1"
|
||||
|
|
@ -190,6 +241,14 @@ clawdie_live_gpu_start()
|
|||
fi
|
||||
|
||||
clawdie_live_gpu_log "detected display devices: $(echo "$_blocks" | grep -i '^vgapci' | tr '\n' ' ')"
|
||||
|
||||
# Universal lane: install the matching NVIDIA branch before module selection.
|
||||
# Best-effort — on failure select_modules just falls through to integrated.
|
||||
if [ "${clawdie_live_gpu_mode:-auto}" = "nvidia-auto" ] &&
|
||||
clawdie_live_gpu_has_pci_vendor "$_blocks" "0x10de"; then
|
||||
clawdie_live_gpu_install_nvidia "$_blocks" || true
|
||||
fi
|
||||
|
||||
_modules=$(clawdie_live_gpu_select_modules "$_blocks")
|
||||
if [ -z "$_modules" ]; then
|
||||
clawdie_live_gpu_log "no live KMS module selected; using scfb/vesa fallback"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue