diff --git a/mkosi.extra/usr/lib/rebuild-efi b/mkosi.extra/usr/lib/rebuild-efi index cd8bb2f..cbfcf28 100755 --- a/mkosi.extra/usr/lib/rebuild-efi +++ b/mkosi.extra/usr/lib/rebuild-efi @@ -28,8 +28,8 @@ fi # NOTE: plymouth MUST be after systemd as per the wiki! cat <<- EOF > mkinitcpio.conf MODULES=(overlay) -BINARIES=() -FILES=() +BINARIES=(nvidia nouveau) # Ensure both drivers are pulled into the initrd (see mkosi.finalize.d/20-nvidia-udev-generator.sh.chroot) +FILES=(/usr/lib/udev/rules.d/99-nvidia-module-selection.rules) # Determine which driver is used at boot with udev HOOKS=(base systemd modconf kms keyboard block sd-encrypt filesystems fsck systemd-extension plymouth microcode sd-shutdown) EOF diff --git a/mkosi.finalize.d/20-nvidia-udev-generator.sh.chroot b/mkosi.finalize.d/20-nvidia-udev-generator.sh.chroot new file mode 100644 index 0000000..8ae0500 --- /dev/null +++ b/mkosi.finalize.d/20-nvidia-udev-generator.sh.chroot @@ -0,0 +1,40 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +# SPDX-FileCopyrightText: 2025 Thomas Duckworth + +set -e + +# Remove the nouveau blacklist so our dynamic selection can actually load it +if [ -f /usr/lib/modprobe.d/nvidia-utils.conf ]; then + sed -i '/blacklist nouveau/d' /usr/lib/modprobe.d/nvidia-utils.conf +fi + +# Now, generate a huge udev rule which selects the correct driver for NVIDIA graphics cards. +# This gets included in the initrd - see mkosi.extra/usr/lib/rebuild-efi +PCI_IDS="/usr/share/hwdata/pci.ids" +UDEV_RULE="/usr/lib/udev/rules.d/99-nvidia-module-selection.rules" + +echo "# Generated by mkosi.finalize.d/50-nvidia-udev.chroot" > "$UDEV_RULE" +echo "# Static driver overrides for NVIDIA GPUs based on ID ranges" >> "$UDEV_RULE" + +gawk ' + /^10de/ { in_nvidia=1; next } + /^[0-9a-f]/ { in_nvidia=0 } + + in_nvidia && /^\t[0-9a-f]{4}/ { + device_id = $1 + dec_id = strtonum("0x" device_id) + + # 0x1e00 (7680) is where Turing architecture begins (RTX 20-series / GTX 16-series). + # This is, currently, the cutoff for support in the open kernel modules. + if (dec_id >= 7680) { + driver = "nvidia" + } else { + driver = "nouveau" + } + + # Match only Class 03 (Display Controllers) to avoid breaking Audio/USB/Bridges. + # The wildcard .* after 0x03 matches any programming interface/subclass. + printf "ACTION==\"add\", SUBSYSTEM==\"pci\", ATTR{vendor}==\"0x10de\", ATTR{device}==\"0x%s\", ATTR{class}==\"0x03*\", ATTR{driver_override}=\"%s\"\n", device_id, driver + } +' "$PCI_IDS" >> "$UDEV_RULE"