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)
|
# intel | amd | nvidia-590 | nvidia-470 | nvidia-390 | vesa | "" (auto-detect)
|
||||||
GPU_DRIVER=""
|
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
|
# Deploy target
|
||||||
TARGET="baremetal" # vps | baremetal
|
TARGET="baremetal" # vps | baremetal
|
||||||
|
|
||||||
|
|
|
||||||
53
build.sh
53
build.sh
|
|
@ -119,6 +119,7 @@ echo " Clawdie : ${CLAWDIE_REF}"
|
||||||
echo " Desktop : ${DEFAULT_DESKTOP}"
|
echo " Desktop : ${DEFAULT_DESKTOP}"
|
||||||
echo " Pkg : ${DEFAULT_PKG_BRANCH}"
|
echo " Pkg : ${DEFAULT_PKG_BRANCH}"
|
||||||
echo " GPU : ${GPU_DRIVER:-auto-detect}"
|
echo " GPU : ${GPU_DRIVER:-auto-detect}"
|
||||||
|
echo " NVIDIA universal : ${NVIDIA_UNIVERSAL:-NO}"
|
||||||
echo " Target : ${TARGET:-baremetal}"
|
echo " Target : ${TARGET:-baremetal}"
|
||||||
echo " Colibri : ${FEATURE_COLIBRI:-NO}"
|
echo " Colibri : ${FEATURE_COLIBRI:-NO}"
|
||||||
echo " Clawdie agent : ${FEATURE_CLAWDIE:-NO}"
|
echo " Clawdie agent : ${FEATURE_CLAWDIE:-NO}"
|
||||||
|
|
@ -906,6 +907,48 @@ install_clawdie_service() {
|
||||||
fi
|
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() {
|
install_live_npm_globals() {
|
||||||
echo " Installing bundled npm globals into live image..."
|
echo " Installing bundled npm globals into live image..."
|
||||||
|
|
||||||
|
|
@ -1561,6 +1604,15 @@ EOF
|
||||||
;;
|
;;
|
||||||
esac
|
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"
|
mkdir -p "${MOUNT_POINT}/etc/ssh/sshd_config.d"
|
||||||
install -m 0644 "${LIVE_SESSION_DIR}/sshd-live.conf" \
|
install -m 0644 "${LIVE_SESSION_DIR}/sshd-live.conf" \
|
||||||
"${MOUNT_POINT}/etc/ssh/sshd_config.d/clawdie-live.conf"
|
"${MOUNT_POINT}/etc/ssh/sshd_config.d/clawdie-live.conf"
|
||||||
|
|
@ -2158,6 +2210,7 @@ install_live_runtime_packages
|
||||||
configure_live_operator_session
|
configure_live_operator_session
|
||||||
install_colibri_service
|
install_colibri_service
|
||||||
install_clawdie_service
|
install_clawdie_service
|
||||||
|
install_nvidia_universal_repo
|
||||||
|
|
||||||
# Copy payload
|
# Copy payload
|
||||||
# Rebuild payload paths from scratch inside the reusable work image. A failed
|
# 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
|
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()
|
clawdie_live_gpu_has_pci_vendor()
|
||||||
{
|
{
|
||||||
_blocks="$1"
|
_blocks="$1"
|
||||||
|
|
@ -190,6 +241,14 @@ clawdie_live_gpu_start()
|
||||||
fi
|
fi
|
||||||
|
|
||||||
clawdie_live_gpu_log "detected display devices: $(echo "$_blocks" | grep -i '^vgapci' | tr '\n' ' ')"
|
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")
|
_modules=$(clawdie_live_gpu_select_modules "$_blocks")
|
||||||
if [ -z "$_modules" ]; then
|
if [ -z "$_modules" ]; then
|
||||||
clawdie_live_gpu_log "no live KMS module selected; using scfb/vesa fallback"
|
clawdie_live_gpu_log "no live KMS module selected; using scfb/vesa fallback"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue