feat: NVIDIA PRIME, audio fix, timezone, dmesg error cleanup

- Add nvidia/nvidia-dkms/nvidia-libs-32bit/nvidia-vaapi-driver to niri
  live and installed profiles; wireless-regdb and sof-firmware to all
  profiles (fixes regulatory.db and SOF firmware dmesg errors)

- iso/postsetup-nvidia.sh: new mklive -x hook that re-runs dracut inside
  the rootfs chroot after the overlay is applied; ensures the squashfs
  initramfs includes nvidia.ko and omits nouveau.ko at build time —
  no driver install needed at runtime (fixes /run tmpfs overflow that was
  killing wireplumber by corrupting D-Bus sockets)

- Both ISO inner build scripts gain -x postsetup-nvidia.sh and the nonfree
  repo flag so nvidia packages resolve correctly

- niri config: wireplumber started via supervisor loop (waits for PipeWire
  socket, auto-restarts on crash) replacing the one-shot exec — survives
  any D-Bus or pipewire disruption

- build-niri-live-iso.sh: NVIDIA modprobe blacklist-nouveau.conf,
  btusb-quirks.conf, modules-load.d/nvidia.conf, dracut/10-nvidia.conf,
  Xorg intel/nvidia configs, prime-run helper, elogind run script loop
  guard, timezone Europe/Zurich overlay, updated BOOT_CMDLINE

- build-live-iso.sh: same NVIDIA + timezone + sound udev rule overlays;
  live-setup.sh timezone and audio group fix

- installer/lib/grub.sh: GRUB_CMDLINE_LINUX_DEFAULT gains
  nvidia-drm.modeset=1 rd.driver.blacklist=nouveau btusb.enable_autosuspend=0

- installer/lib/postinstall.sh: configure_nvidia_prime() adds
  blacklist-nouveau.conf, btusb-quirks.conf, dracut omit_drivers nouveau,
  modules-load.d with all four nvidia modules
This commit is contained in:
mozempk
2026-04-25 18:27:06 +02:00
parent 40f4efceed
commit cd8248f2f5
12 changed files with 637 additions and 29 deletions

View File

@@ -221,6 +221,7 @@ trap _cleanup_mklive_builds EXIT
-T "$ISO_TITLE" \
-p "$ISO_PKGS" \
-I "$INCLUDE_DIR" \
-x "$PROJECT_DIR/iso/postsetup-nvidia.sh" \
-C "${BOOT_CMDLINE:-}" \
-o "$OUT_ISO"

View File

@@ -47,6 +47,7 @@ trap _cleanup_mklive_builds EXIT
./mklive.sh \
-a "$ARCH" \
-r "$REPO_URL" \
-r "${REPO_URL%/current}/current/nonfree" \
-c "$CACHE_DIR/xbps-live-pkgs" \
-H "$CACHE_DIR/xbps-host-pkgs" \
-k "$KEYMAP" \
@@ -54,6 +55,7 @@ trap _cleanup_mklive_builds EXIT
-T "$ISO_TITLE" \
-p "$ISO_PKGS" \
-I "$INCLUDE_DIR" \
-x "$PROJECT_DIR/iso/postsetup-nvidia.sh" \
-C "${BOOT_CMDLINE:-}" \
-o "$OUT_ISO"

View File

@@ -135,6 +135,17 @@ if [ -f /etc/nsswitch.conf ]; then
echo "live-setup: removed mdns from nsswitch.conf (hosts line)"
fi
# ── Timezone ──────────────────────────────────────────────────────────────
ln -sf /usr/share/zoneinfo/Europe/Zurich /etc/localtime 2>/dev/null || true
echo "live-setup: timezone set to Europe/Zurich"
# ── Fix sound device permissions ───────────────────────────────────────────
# PCM/control nodes may be root:root at early boot before the audio group
# exists. Re-apply correct ownership so PipeWire/ALSA can open the devices.
chown root:audio /dev/snd/pcmC* /dev/snd/controlC* /dev/snd/hwC* 2>/dev/null || true
chmod 660 /dev/snd/pcmC* /dev/snd/controlC* /dev/snd/hwC* 2>/dev/null || true
udevadm trigger --subsystem-match=sound 2>/dev/null || true
# ── DNS: ensure a working nameserver is configured ───────────────────────
# NetworkManager will overwrite resolv.conf once DHCP completes.
# If the DHCP-provided nameserver is broken (e.g. QEMU's 10.0.2.3), add
@@ -264,6 +275,16 @@ chmod 0755 "$INCLUDE_DIR/etc/runit/2"
install -d -m 0755 "$INCLUDE_DIR/etc/runit/runsvdir/default"
# Write all repos to xbps.d so they persist in the live squashfs.
# The nonfree repo is needed for nvidia and other proprietary drivers.
install -d -m 0755 "$INCLUDE_DIR/etc/xbps.d"
cat > "$INCLUDE_DIR/etc/xbps.d/00-void-repos.conf" <<EOF
repository=${REPO_URL:-https://repo-default.voidlinux.org/current}
repository=${REPO_URL%/current}/current/nonfree
repository=${REPO_URL%/current}/current/multilib
repository=${REPO_URL%/current}/current/multilib/nonfree
EOF
# ── 3b) LightDM autologin ───────────────────────────────────────────────
install -d -m 0755 "$INCLUDE_DIR/etc/lightdm"
# .session file: read by the vmklive dracut hook (display-manager-autologin.sh)
@@ -561,6 +582,55 @@ cat > "$INCLUDE_DIR/etc/environment" <<'ENVEOF'
XDG_DATA_DIRS=/home/live/.nix-profile/share:/usr/local/share:/usr/share
ENVEOF
# ── Timezone ──────────────────────────────────────────────────────────────
ln -sf /usr/share/zoneinfo/Europe/Zurich "$INCLUDE_DIR/etc/localtime"
cat > "$INCLUDE_DIR/etc/rc.conf" <<'RCEOF'
KEYMAP="ch"
HARDWARECLOCK="UTC"
TIMEZONE="Europe/Zurich"
RCEOF
# ── Sound device udev rules ──────────────────────────────────────────────
# PCM/control nodes are created root:root at early boot before the audio group
# is provisioned; this rule ensures correct ownership on every boot.
install -d -m 0755 "$INCLUDE_DIR/etc/udev/rules.d"
cat > "$INCLUDE_DIR/etc/udev/rules.d/70-sound-perms.rules" <<'EOF'
SUBSYSTEM=="sound", GROUP="audio", MODE="0660"
EOF
# ── NVIDIA PRIME overlay ────────────────────────────────────────────────
# Blacklist nouveau — the live-setup.sh PRIME detection block already writes
# Xorg config, but the kernel must also not load nouveau.
install -d -m 0755 "$INCLUDE_DIR/etc/modprobe.d"
cat > "$INCLUDE_DIR/etc/modprobe.d/blacklist-nouveau.conf" <<'EOF'
blacklist nouveau
options nouveau modeset=0
EOF
cat > "$INCLUDE_DIR/etc/modprobe.d/btusb-quirks.conf" <<'EOF'
options btusb enable_autosuspend=0
EOF
install -d -m 0755 "$INCLUDE_DIR/etc/modules-load.d"
cat > "$INCLUDE_DIR/etc/modules-load.d/nvidia.conf" <<'EOF'
nvidia
nvidia_modeset
nvidia_uvm
nvidia_drm
EOF
install -d -m 0755 "$INCLUDE_DIR/etc/dracut.conf.d"
cat > "$INCLUDE_DIR/etc/dracut.conf.d/10-nvidia.conf" <<'EOF'
add_drivers+=" nvidia nvidia_modeset nvidia_uvm nvidia_drm "
omit_drivers+=" nouveau "
EOF
install -d -m 0755 "$INCLUDE_DIR/usr/local/bin"
cat > "$INCLUDE_DIR/usr/local/bin/prime-run" <<'EOF'
#!/bin/sh
exec env __NV_PRIME_RENDER_OFFLOAD=1 \
__VK_LAYER_NV_optimus=NVIDIA_only \
__GLX_VENDOR_LIBRARY_NAME=nvidia \
"$@"
EOF
chmod 0755 "$INCLUDE_DIR/usr/local/bin/prime-run"
# /etc/profile.d: PATH for interactive terminals (alacritty, etc.)
install -d -m 0755 "$INCLUDE_DIR/etc/profile.d"
cat > "$INCLUDE_DIR/etc/profile.d/nix-prebaked.sh" <<'NIXEOF'
@@ -696,7 +766,7 @@ TS="$(date -u +%Y%m%d)"
OUT_ISO="${OUTPUT_ISO:-$OUT_DIR/void-live-stable-${TS}.iso}"
# live.user=live → vmklive dracut hook creates user 'live' (default would be 'anon')
# console=ttyS0 → serial output for QEMU/real hardware debugging
BOOT_CMDLINE="${BOOT_CMDLINE:-live.user=${LIVE_USER} console=tty0 console=ttyS0,115200}"
BOOT_CMDLINE="${BOOT_CMDLINE:-live.user=${LIVE_USER} console=tty0 console=ttyS0,115200 nvidia-drm.modeset=1 rd.driver.blacklist=nouveau modprobe.blacklist=nouveau btusb.enable_autosuspend=0}"
echo ">>> running mklive.sh inside docker — output: $OUT_ISO"
"$DOCKER" run --rm --privileged \

View File

@@ -84,7 +84,7 @@ cat > "$INCLUDE_DIR/etc/greetd/config.toml" <<'EOF'
vt = 2
[default_session]
command = "tuigreet --time --greeting 'Void Linux Live (niri)' --cmd 'niri --session'"
command = "tuigreet --time --greeting 'Void Linux Live (niri)' --cmd niri-session"
user = "_greeter"
EOF
@@ -102,8 +102,16 @@ BAUD_RATE=38400
TERM_NAME=linux
EOF
# ── 3b) noctalia XBPS repo ──────────────────────────────────────────────
# ── 3b) xbps repo configuration ─────────────────────────────────────────
# Write all repos into xbps.d so they are available in the live session
# (not just at build time). The nonfree repo is needed for nvidia et al.
install -d -m 0755 "$INCLUDE_DIR/etc/xbps.d"
cat > "$INCLUDE_DIR/etc/xbps.d/00-void-repos.conf" <<EOF
repository=${REPO_URL:-https://repo-default.voidlinux.org/current}
repository=${REPO_URL%/current}/current/nonfree
repository=${REPO_URL%/current}/current/multilib
repository=${REPO_URL%/current}/current/multilib/nonfree
EOF
cat > "$INCLUDE_DIR/etc/xbps.d/10-noctalia.conf" <<'EOF'
repository=https://universalrepo.r1xelelo.workers.dev/void
EOF
@@ -145,13 +153,16 @@ XDG_RUN="/run/user/$(id -u "$LIVE_USER" 2>/dev/null || echo 1000)"
install -d -m 0700 "$XDG_RUN" 2>/dev/null || true
chown "$LIVE_USER" "$XDG_RUN" 2>/dev/null || true
# Fix sound device permissions — PCM/control nodes are created root:root during
# early boot before the audio group is guaranteed to exist. Re-apply the correct
# ownership now that the group is present, then trigger udev to re-evaluate the
# sound subsystem so the persistent 70-sound-perms.rules rule is applied too.
chown root:audio /dev/snd/pcmC* /dev/snd/controlC* /dev/snd/hwC* 2>/dev/null || true
chmod 660 /dev/snd/pcmC* /dev/snd/controlC* /dev/snd/hwC* 2>/dev/null || true
udevadm trigger --subsystem-match=sound 2>/dev/null || true
# Start elogind here, once, before runsvdir brings up greetd.
# Runit does NOT supervise it — this avoids cgroup-race restart spam.
# We wait until dbus is available (dbus service starts first in runsvdir),
# then start elogind as a background daemon.
# NOTE: live-setup.sh runs BEFORE runsvdir, so dbus isn't up yet here.
# We start elogind from a one-shot at-startup hook instead — see runit/2.
# Timezone
ln -sf /usr/share/zoneinfo/Europe/Zurich /etc/localtime 2>/dev/null || true
echo "niri live-setup: done (user=$LIVE_USER)"
SV_EOF
@@ -194,6 +205,12 @@ install -d -m 0755 "$INCLUDE_DIR/etc/sv/elogind"
cat > "$INCLUDE_DIR/etc/sv/elogind/run" <<'EOF'
#!/bin/sh
exec 2>&1
# If elogind is already running (e.g. from a previous attempt), stay up
# permanently rather than letting runit restart the wrapper every 3 s.
if [ -f /run/elogind.pid ] && kill -0 "$(cat /run/elogind.pid 2>/dev/null)" 2>/dev/null; then
echo "elogind-sv: already running (PID $(cat /run/elogind.pid)), yielding"
exec tail -f /dev/null
fi
# Wait for dbus socket — poll every second, up to 30s
i=0
while [ $i -lt 30 ] && [ ! -S /run/dbus/system_bus_socket ]; do
@@ -226,6 +243,9 @@ export XDG_CURRENT_DESKTOP=niri
export XDG_SESSION_TYPE=wayland
# Use elogind's logind backend — works correctly on Void/runit via audit session IDs
export LIBSEAT_BACKEND=logind
# Force GTK apps (and Electron/VSCode) to use XDG portal file dialogs
export GTK_USE_PORTAL=1
export ELECTRON_OZONE_PLATFORM_HINT=auto
EOF
chmod 0644 "$INCLUDE_DIR/etc/profile.d/wayland.sh"
@@ -238,6 +258,13 @@ if [[ -d "${HOME:-}/.nix-profile/bin" ]]; then
*) export PATH="$HOME/.nix-profile/bin:$PATH" ;;
esac
fi
# Expose nix .desktop files and icons to XDG-compliant launchers/shells
if [[ -d "${HOME:-}/.nix-profile/share" ]]; then
case ":${XDG_DATA_DIRS:-}:" in
*":$HOME/.nix-profile/share:"*) ;;
*) export XDG_DATA_DIRS="$HOME/.nix-profile/share:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" ;;
esac
fi
export NIXPKGS_ALLOW_UNFREE=1
# Pre-baked nix is single-user (no daemon) — bypass daemon connection attempt
export NIX_REMOTE=local
@@ -344,7 +371,9 @@ cursor {
// Audio / screen session services — started by niri as the live user
spawn-at-startup "pipewire"
spawn-at-startup "pipewire-pulse"
spawn-at-startup "wireplumber"
// Keep WirePlumber running: wait for the PipeWire socket then start it,
// restart on any crash or pipewire restart (e.g. after package installs).
spawn-at-startup "sh" "-c" "while true; do while [ ! -S /run/user/\$(id -u)/pipewire-0 ]; do sleep 0.2; done; wireplumber; sleep 1; done"
// Background, notifications and auth
spawn-at-startup "swaybg" "-i" "/usr/share/backgrounds/void-installer/pxfuel.jpg" "-m" "fill"
@@ -360,7 +389,7 @@ spawn-at-startup "sh" "-c" "[ -f ~/.first-login-done ] || alacritty -T 'Void Set
binds {
Mod+T { spawn "alacritty"; }
Mod+D { spawn "fuzzel"; }
Mod+D { spawn "sh" "-c" "quickshell msg -c noctalia-shell launcher toggle"; }
Mod+Q { close-window; }
Mod+Shift+E { quit; }
Print { screenshot; }
@@ -474,11 +503,27 @@ install -d -m 0755 "$INCLUDE_DIR/usr/share/themes"
install -d -m 0755 "$INCLUDE_DIR/usr/share/icons"
[[ -d "$OVERLAY/icons" ]] && cp -a "$OVERLAY/icons"/. "$INCLUDE_DIR/usr/share/icons/" 2>/dev/null || true
# ── 3g) GTK settings for Wayland apps ───────────────────────────────────
# ── 3g) GTK settings + dark theme dconf ────────────────────────────────
# Write GTK2/3/4 settings to skel so the live user picks them up.
install -d -m 0755 "$INCLUDE_DIR/etc/skel/.config/gtk-3.0"
install -d -m 0755 "$INCLUDE_DIR/etc/skel/.config/gtk-4.0"
# dconf system keyfile: ensures GTK dark theme is reported to all apps via
# xdg-desktop-portal-gtk regardless of whether the user has a dconf DB yet.
install -d -m 0755 "$INCLUDE_DIR/etc/dconf/db/local.d"
install -d -m 0755 "$INCLUDE_DIR/etc/dconf/profile"
cat > "$INCLUDE_DIR/etc/dconf/db/local.d/01-dark-theme" <<'EOF'
[org/gnome/desktop/interface]
color-scheme='prefer-dark'
gtk-theme='${GTK_THEME}'
icon-theme='${ICON_THEME}'
cursor-theme='${CURSOR_THEME:-Bibata-Modern-Ice}'
cursor-size=24
EOF
sed -i "s/'\${GTK_THEME}'/'${GTK_THEME}'/; s/'\${ICON_THEME}'/'${ICON_THEME}'/; s/'\${CURSOR_THEME:-Bibata-Modern-Ice}'/'${CURSOR_THEME:-Bibata-Modern-Ice}'/" \
"$INCLUDE_DIR/etc/dconf/db/local.d/01-dark-theme"
printf 'user-db:user\nsystem-db:local\n' > "$INCLUDE_DIR/etc/dconf/profile/user"
cat > "$INCLUDE_DIR/etc/skel/.config/gtk-3.0/settings.ini" <<EOF
[Settings]
gtk-theme-name=${GTK_THEME}
@@ -500,22 +545,214 @@ gtk-cursor-theme-size=24
gtk-font-name="Noto Sans 11"
EOF
# XDG_DATA_DIRS so Wayland apps pick up installed theme/icon .desktop files
cat > "$INCLUDE_DIR/etc/environment" <<'ENVEOF'
XDG_DATA_DIRS=/usr/local/share:/usr/share
# XDG_DATA_DIRS: include the pre-baked nix profile share dir so launchers
# and icon themes pick up nix-installed apps on first boot.
# /etc/environment is loaded by pam_env for ALL session types (tty autologin
# and greetd), so this is the most reliable place to set this baseline.
cat > "$INCLUDE_DIR/etc/environment" <<ENVEOF
XDG_DATA_DIRS=/home/${LIVE_USER}/.nix-profile/share:/usr/local/share:/usr/share
QT_QPA_PLATFORM=wayland;xcb
GDK_BACKEND=wayland,x11
MOZ_ENABLE_WAYLAND=1
LIBSEAT_BACKEND=logind
GTK_USE_PORTAL=1
ELECTRON_OZONE_PLATFORM_HINT=auto
ENVEOF
# ── noctalia default settings ─────────────────────────────────────────────
# Baseline settings.json placed in skel so the live user (and any installed
# user whose home is created from skel) starts with:
# - correct wallpaper directory pointing at the baked-in backgrounds
# - Gruvbox dark colour scheme
# - real app icons (iconMode=apps) instead of tabler monochrome icons
install -d -m 0755 "$INCLUDE_DIR/etc/skel/.config/noctalia"
cat > "$INCLUDE_DIR/etc/skel/.config/noctalia/settings.json" <<NOCEOF
{
"appLauncher": {
"iconMode": "apps",
"sortByMostUsed": true,
"showCategories": true,
"viewMode": "grid",
"pinnedApps": [],
"terminalCommand": "alacritty -e",
"density": "default",
"position": "center"
},
"colorSchemes": {
"darkMode": true,
"predefinedScheme": "Gruvbox",
"generationMethod": "tonal-spot",
"manualSunrise": "06:30",
"manualSunset": "18:30",
"monitorForColors": ""
},
"wallpaper": {
"enabled": true,
"directory": "/usr/share/backgrounds/void-installer",
"fillMode": "crop",
"fillColor": "#000000",
"automationEnabled": false,
"favorites": [],
"hideWallpaperFilenames": false,
"linkLightAndDarkWallpapers": true,
"monitorDirectories": [],
"enableMultiMonitorDirectories": false
}
}
NOCEOF
# ── Default browser: google-chrome (nix) ──────────────────────────────────
# System-wide MIME defaults so chrome is the default browser from first boot.
# Written to /etc/xdg/mimeapps.list (system default) and skel.
install -d -m 0755 "$INCLUDE_DIR/etc/xdg"
cat > "$INCLUDE_DIR/etc/xdg/mimeapps.list" <<'EOF'
[Default Applications]
text/html=google-chrome.desktop
x-scheme-handler/http=google-chrome.desktop
x-scheme-handler/https=google-chrome.desktop
x-scheme-handler/about=google-chrome.desktop
x-scheme-handler/unknown=google-chrome.desktop
application/pdf=google-chrome.desktop
application/xhtml+xml=google-chrome.desktop
application/xml=google-chrome.desktop
EOF
install -d -m 0755 "$INCLUDE_DIR/etc/skel/.config"
cp "$INCLUDE_DIR/etc/xdg/mimeapps.list" "$INCLUDE_DIR/etc/skel/.config/mimeapps.list"
# ── Portal backend configuration for niri ─────────────────────────────────
# Without this, xdg-desktop-portal doesn't know which backend to use for
# XDG_CURRENT_DESKTOP=niri, causing file-picker / portal calls to fail.
install -d -m 0755 "$INCLUDE_DIR/etc/xdg/xdg-desktop-portal"
cat > "$INCLUDE_DIR/etc/xdg/xdg-desktop-portal/niri-portals.conf" <<'EOF'
[preferred]
default=gtk
org.freedesktop.impl.portal.FileChooser=gtk
org.freedesktop.impl.portal.AppChooser=gtk
org.freedesktop.impl.portal.OpenURI=gtk
org.freedesktop.impl.portal.Print=gtk
org.freedesktop.impl.portal.Screenshot=gtk
org.freedesktop.impl.portal.Inhibit=gtk
org.freedesktop.impl.portal.Notification=gtk
org.freedesktop.impl.portal.Settings=gtk
EOF
# ── Sound device udev rules ────────────────────────────────────────
# PCM/control nodes are created root:root at early boot before the audio
# group is provisioned; this rule ensures correct ownership on every boot.
install -d -m 0755 "$INCLUDE_DIR/etc/udev/rules.d"
cat > "$INCLUDE_DIR/etc/udev/rules.d/70-sound-perms.rules" <<'EOF'
# Allow the audio group to access ALSA PCM and control devices.
SUBSYSTEM=="sound", GROUP="audio", MODE="0660"
EOF
# ── Timezone ──────────────────────────────────────────────────────────
# Create the /etc/localtime symlink and rc.conf TIMEZONE setting so the live
# session starts in the correct timezone without requiring a user step.
ln -sf /usr/share/zoneinfo/Europe/Zurich "$INCLUDE_DIR/etc/localtime"
cat > "$INCLUDE_DIR/etc/rc.conf" <<'RCEOF'
KEYMAP="ch"
HARDWARECLOCK="UTC"
TIMEZONE="Europe/Zurich"
RCEOF
# ── NVIDIA PRIME overlay ────────────────────────────────────────────────
echo ">>> staging NVIDIA PRIME overlay"
# Blacklist nouveau — prevents the open-source driver from grabbing the GPU
# before the proprietary nvidia driver.
install -d -m 0755 "$INCLUDE_DIR/etc/modprobe.d"
cat > "$INCLUDE_DIR/etc/modprobe.d/blacklist-nouveau.conf" <<'EOF'
blacklist nouveau
options nouveau modeset=0
EOF
# Intel BT on this platform suffers firmware download failures when USB
# autosuspend is active for the btusb adapter.
cat > "$INCLUDE_DIR/etc/modprobe.d/btusb-quirks.conf" <<'EOF'
options btusb enable_autosuspend=0
EOF
# Load nvidia modules early so the DRM device node exists before niri starts.
install -d -m 0755 "$INCLUDE_DIR/etc/modules-load.d"
cat > "$INCLUDE_DIR/etc/modules-load.d/nvidia.conf" <<'EOF'
nvidia
nvidia_modeset
nvidia_uvm
nvidia_drm
EOF
# dracut: include nvidia modules in initramfs; omit nouveau.
install -d -m 0755 "$INCLUDE_DIR/etc/dracut.conf.d"
cat > "$INCLUDE_DIR/etc/dracut.conf.d/10-nvidia.conf" <<'EOF'
add_drivers+=" nvidia nvidia_modeset nvidia_uvm nvidia_drm "
omit_drivers+=" nouveau "
EOF
# Xorg output-class configs: intel=modesetting (primary), nvidia=PRIME offload.
# Needed by xwayland-satellite for X11 clients running under niri.
install -d -m 0755 "$INCLUDE_DIR/etc/X11/xorg.conf.d"
cat > "$INCLUDE_DIR/etc/X11/xorg.conf.d/10-intel.conf" <<'EOF'
Section "OutputClass"
Identifier "intel"
MatchDriver "i915"
Driver "modesetting"
EndSection
EOF
cat > "$INCLUDE_DIR/etc/X11/xorg.conf.d/20-nvidia.conf" <<'EOF'
Section "OutputClass"
Identifier "nvidia"
MatchDriver "nvidia-drm"
Driver "nvidia"
Option "AllowEmptyInitialConfiguration"
Option "PrimaryGPU" "no"
ModulePath "/usr/lib/nvidia/xorg"
ModulePath "/usr/lib/xorg/modules"
EndSection
EOF
# prime-run: launch any app on the NVIDIA dGPU via PRIME render-offload.
cat > "$INCLUDE_DIR/usr/local/bin/prime-run" <<'EOF'
#!/bin/sh
# Run a program on the NVIDIA dGPU via PRIME render offload.
exec env __NV_PRIME_RENDER_OFFLOAD=1 \
__VK_LAYER_NV_optimus=NVIDIA_only \
__GLX_VENDOR_LIBRARY_NAME=nvidia \
"$@"
EOF
chmod 0755 "$INCLUDE_DIR/usr/local/bin/prime-run"
# ── 3g2) niri-session wrapper ─────────────────────────────────────────────
# greetd/tuigreet starts niri-session (not niri --session directly) so that
# /etc/profile is sourced first, ensuring /etc/profile.d/* scripts run and
# XDG_DATA_DIRS gets ~/.nix-profile/share prepended for the compositor and
# all apps it spawns (noctalia-shell, fuzzel, etc.).
install -d -m 0755 "$INCLUDE_DIR/usr/local/bin"
cat > "$INCLUDE_DIR/usr/local/bin/niri-session" <<'EOF'
#!/bin/bash
# niri-session — wrapper started by greetd/tuigreet.
# Sources /etc/profile so that all /etc/profile.d/* scripts run
# (nix paths, wayland env, XDG_DATA_DIRS with ~/.nix-profile/share, etc.)
# before handing off to the compositor.
[ -f /etc/profile ] && . /etc/profile
exec niri --session "$@"
EOF
chmod 0755 "$INCLUDE_DIR/usr/local/bin/niri-session"
# ── 3h) .bash_profile: source .bashrc + launch niri on tty1 ───────────
# agetty autologin on tty1 runs a login shell; .bash_profile execs niri
# via dbus-run-session so it gets a D-Bus session bus.
cat > "$INCLUDE_DIR/etc/skel/.bash_profile" <<'EOF'
[[ -f ~/.bashrc ]] && . ~/.bashrc
if [[ "$(tty)" == /dev/tty1 ]] && [[ -z "$WAYLAND_DISPLAY" ]] && [[ -z "$NIRI_SOCKET" ]]; then
exec dbus-run-session -- niri --session
# Wrap niri startup: start GNOME Keyring daemon first (inside the D-Bus session)
# so Chrome/VSCode/apps can store secrets via org.freedesktop.secrets.
exec dbus-run-session -- sh -c '
if command -v gnome-keyring-daemon >/dev/null 2>&1; then
eval "$(gnome-keyring-daemon --start --components=secrets,pkcs11 2>/dev/null)" || true
export GNOME_KEYRING_CONTROL GNOME_KEYRING_PID SSH_AUTH_SOCK
fi
exec niri --session
'
fi
EOF
@@ -595,7 +832,7 @@ ISO_PKGS=$(grep -vE '^\s*(#|$)' \
| tr '\n' ' ')
TS="$(date -u +%Y%m%d)"
OUT_ISO="${OUTPUT_ISO:-$OUT_DIR/void-live-niri-${TS}.iso}"
BOOT_CMDLINE="${BOOT_CMDLINE:-live.user=${LIVE_USER} console=tty0 console=ttyS0,115200}"
BOOT_CMDLINE="${BOOT_CMDLINE:-live.user=${LIVE_USER} console=tty0 console=ttyS0,115200 nvidia-drm.modeset=1 rd.driver.blacklist=nouveau modprobe.blacklist=nouveau btusb.enable_autosuspend=0}"
echo ">>> running mklive.sh inside docker — output: $OUT_ISO"
"$DOCKER" run --rm --privileged \

81
iso/postsetup-nvidia.sh Executable file
View File

@@ -0,0 +1,81 @@
#!/bin/bash
# void-mklive postsetup hook (-x flag).
#
# Runs AFTER copy_include_directories (overlay applied) but BEFORE
# generate_initramfs (boot initramfs). The xbps initramfs-regenerate trigger
# fires during install_packages — BEFORE the overlay — so the squashfs rootfs's
# own /boot/initramfs-KVER.img is missing our etc/dracut.conf.d/10-nvidia.conf.
#
# This script re-runs dracut inside the rootfs chroot for every installed kernel
# so the squashfs initramfs:
# • includes nvidia.ko (add_drivers from 10-nvidia.conf)
# • excludes nouveau.ko (omit_drivers from 10-nvidia.conf)
#
# $1 = absolute path to the rootfs directory being built.
set -euo pipefail
ROOTFS="$1"
if [[ ! -d "$ROOTFS/usr/lib/modules" ]]; then
echo "[postsetup-nvidia] no modules dir — skipping"
exit 0
fi
if [[ ! -x "$ROOTFS/usr/bin/dracut" ]]; then
echo "[postsetup-nvidia] dracut not in rootfs — skipping"
exit 0
fi
if [[ ! -f "$ROOTFS/etc/dracut.conf.d/10-nvidia.conf" ]]; then
echo "[postsetup-nvidia] WARNING: 10-nvidia.conf not found in rootfs overlay — skipping"
exit 0
fi
# Mount pseudo-filesystems needed by dracut inside the chroot.
_umount_pseudo() {
for f in dev proc sys; do
[[ -d "$ROOTFS/$f" ]] && \
{ umount -R -f "$ROOTFS/$f" 2>/dev/null || umount -R -l "$ROOTFS/$f" 2>/dev/null || true; }
done
}
trap _umount_pseudo EXIT
for f in dev proc sys; do
mkdir -p "$ROOTFS/$f"
mount --rbind "/$f" "$ROOTFS/$f"
done
echo "[postsetup-nvidia] regenerating initramfs with nvidia config"
echo "[postsetup-nvidia] 10-nvidia.conf:"
sed 's/^/ /' "$ROOTFS/etc/dracut.conf.d/10-nvidia.conf"
found=0
for kdir in "$ROOTFS/usr/lib/modules"/*/; do
[[ -d "${kdir}/kernel" ]] || continue
kver="${kdir##*/}"
found=1
# Verify nvidia.ko is present for this kernel version.
nv_ko=$(find "$ROOTFS/usr/lib/modules/$kver" -name 'nvidia.ko' -o -name 'nvidia.ko.zst' 2>/dev/null | head -1)
if [[ -z "$nv_ko" ]]; then
echo "[postsetup-nvidia] WARNING: nvidia.ko not found for kernel $kver — initramfs regeneration skipped"
continue
fi
echo "[postsetup-nvidia] kernel $kver: nvidia.ko at ${nv_ko#"$ROOTFS"}"
echo "[postsetup-nvidia] running dracut --force for $kver ..."
chroot "$ROOTFS" env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin \
/usr/bin/dracut --force \
"/boot/initramfs-${kver}.img" \
"$kver" 2>&1 | grep -v '^$' | tail -5 || {
echo "[postsetup-nvidia] WARNING: dracut failed for $kver — continuing"
continue
}
sz=$(ls -lh "$ROOTFS/boot/initramfs-${kver}.img" 2>/dev/null | awk '{print $5}')
echo "[postsetup-nvidia] done: /boot/initramfs-${kver}.img ($sz)"
done
[[ "$found" -eq 1 ]] || echo "[postsetup-nvidia] WARNING: no kernels found in rootfs"
echo "[postsetup-nvidia] complete"