From c8f83686519660ee551deb4878c130c19da1b886 Mon Sep 17 00:00:00 2001 From: Thomas Duckworth Date: Mon, 29 Dec 2025 17:36:19 +1100 Subject: [PATCH] Support pre-Turing cards OOTB Automatically determines the kernel module required for a NVIDIA graphics card, then dynamically creates an udev rule which overrides the driver. Adds the udev rule as well as nvidia and nouveau binaries to initrd. This, essentially, enables support for pre-Turing cards OOTB, by overriding unsupported cards to use Nouveau. --- mkosi.extra/usr/lib/rebuild-efi | 4 +- .../20-nvidia-udev-generator.sh.chroot | 40 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 mkosi.finalize.d/20-nvidia-udev-generator.sh.chroot 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"