mirror of
https://github.com/KDE/kde-linux.git
synced 2026-06-03 05:09:27 -04:00
Take a different approach
Generate module blacklists instead when initramfs is loaded.
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
# SPDX-FileCopyrightText: 2026 Thomas Duckworth <tduck@filotimoproject.org>
|
||||
|
||||
# Necessary for letting udev control what GPUs get which drivers
|
||||
# using driver_override, so nouveau or nvidia can be dynamically selected.
|
||||
# Necessary for generating automatic modprobe blacklists before
|
||||
# drivers load so nouveau or nvidia can be dynamically selected.
|
||||
# Also gives us some certainty that these are included for kernel modesetting.
|
||||
|
||||
build() {
|
||||
@@ -11,8 +11,12 @@ build() {
|
||||
add_module "nvidia-drm"
|
||||
add_module "nvidia-modeset"
|
||||
add_module "nvidia-uvm"
|
||||
|
||||
add_module "nouveau"
|
||||
|
||||
add_checked_modules "/drivers/gpu/drm"
|
||||
|
||||
add_binary "/usr/lib/initcpio/nvidia-driver-selection"
|
||||
|
||||
add_systemd_unit "kde-linux-nvidia-driver-selection.service"
|
||||
add_symlink "/etc/systemd/system/sysinit.target.wants/kde-linux-nvidia-driver-selection.service" "/usr/lib/systemd/system/kde-linux-nvidia-driver-selection.service"
|
||||
}
|
||||
42
mkosi.extra/usr/lib/initcpio/nvidia-driver-selection
Executable file
42
mkosi.extra/usr/lib/initcpio/nvidia-driver-selection
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
# SPDX-FileCopyrightText: 2026 Thomas Duckworth <tduck@filotimoproject.org>
|
||||
|
||||
# Checks sysfs for NVIDIA GPUs and generates a modprobe blacklist dynamically.
|
||||
|
||||
mkdir -p /run/modprobe.d
|
||||
mkdir -p /run/modules-load.d
|
||||
USE_NVIDIA=0
|
||||
GPU_FOUND=0
|
||||
|
||||
for dev in /sys/bus/pci/devices/*; do
|
||||
[ -f "$dev/vendor" ] && [ -f "$dev/device" ] && [ -f "$dev/class" ] || continue
|
||||
|
||||
vendor=$(cat "$dev/vendor")
|
||||
class=$(cat "$dev/class")
|
||||
|
||||
# 0x10de = NVIDIA. Class 0x03* = Display controllers
|
||||
if [ "$vendor" = "0x10de" ] && [[ "$class" == 0x03* ]]; then
|
||||
GPU_FOUND=1
|
||||
device=$(cat "$dev/device")
|
||||
dec_id=$(printf "%d" "$device")
|
||||
|
||||
# 7680 (0x1e00) is the Turing (NVIDIA driver) cutoff
|
||||
if [ "$dec_id" -ge 7680 ]; then
|
||||
USE_NVIDIA=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$GPU_FOUND" -eq 1 ]; then
|
||||
if [ "$USE_NVIDIA" -eq 1 ]; then
|
||||
echo "blacklist nouveau" > /run/modprobe.d/05-dynamic-gpu.conf
|
||||
modprobe nvidia-drm modeset=1
|
||||
else
|
||||
echo "blacklist nvidia" > /run/modprobe.d/05-dynamic-gpu.conf
|
||||
echo "blacklist nvidia-drm" >> /run/modprobe.d/05-dynamic-gpu.conf
|
||||
echo "blacklist nvidia-modeset" >> /run/modprobe.d/05-dynamic-gpu.conf
|
||||
echo "blacklist nvidia-uvm" >> /run/modprobe.d/05-dynamic-gpu.conf
|
||||
modprobe nouveau
|
||||
fi
|
||||
fi
|
||||
@@ -28,8 +28,8 @@ fi
|
||||
cat <<- EOF > mkinitcpio.conf
|
||||
MODULES=(overlay)
|
||||
BINARIES=()
|
||||
FILES=(/usr/lib/udev/rules.d/05-nvidia-module-selection.rules) # Determine which driver is used at boot with udev
|
||||
HOOKS=(base systemd nvidia-module-selection modconf kms keyboard block sd-encrypt filesystems fsck systemd-extension plymouth microcode sd-shutdown)
|
||||
FILES=()
|
||||
HOOKS=(base systemd nvidia-driver-selection modconf kms keyboard block sd-encrypt filesystems fsck systemd-extension plymouth microcode sd-shutdown)
|
||||
EOF
|
||||
|
||||
echo "rw \
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
# SPDX-FileCopyrightText: 2025 Thomas Duckworth <tduck@filotimoproject.org>
|
||||
|
||||
[Unit]
|
||||
Description=Dynamic NVIDIA Driver Selection
|
||||
DefaultDependencies=no
|
||||
Before=systemd-udevd.service systemd-modules-load.service
|
||||
ConditionPathExists=/sys/bus/pci/devices
|
||||
|
||||
# This service and binary is included in the initramfs.
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/lib/initcpio/nvidia-driver-selection
|
||||
RemainAfterExit=yes
|
||||
@@ -146,40 +146,6 @@ if [ -f /usr/lib/modprobe.d/nvidia-utils.conf ]; then
|
||||
sed -i '/blacklist nouveau/d' /usr/lib/modprobe.d/nvidia-utils.conf
|
||||
fi
|
||||
|
||||
# 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/05-nvidia-module-selection.rules"
|
||||
|
||||
echo "# Generated by mkosi.postinst.chroot" > "$UDEV_RULE"
|
||||
echo "# Static driver overrides for NVIDIA GPUs based on ID ranges." >> "$UDEV_RULE"
|
||||
|
||||
gawk '
|
||||
BEGIN { IGNORECASE = 1 }
|
||||
# Vendor line, e.g. "10de NVIDIA Corporation".
|
||||
/^10de\b/ { in_nvidia = 1; next }
|
||||
# Any other vendor line (4 hex digits at start) disables in_nvidia.
|
||||
/^[0-9A-Fa-f]{4}\s/ { in_nvidia = 0; next }
|
||||
|
||||
# device lines are indented and begin with a 4-hex-digit device id
|
||||
in_nvidia && /^\s+[0-9A-Fa-f]{4}\b/ {
|
||||
device_id = gensub(/^\s+([0-9A-Fa-f]{4}).*/, "\\1", "g")
|
||||
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.
|
||||
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"
|
||||
|
||||
|
||||
cd /tmp
|
||||
/usr/lib/rebuild-efi
|
||||
mv -v ./*.efi /
|
||||
|
||||
Reference in New Issue
Block a user