Files
arch/scripts/03b-gpu-driver.sh

211 lines
9.4 KiB
Bash
Raw Normal View History

2026-03-31 20:13:15 +08:00
#!/bin/bash
# ==============================================================================
# 03b-gpu-driver.sh GPU Driver Installer 参考了cachyos的chwd脚本
# ==============================================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 引用工具库
if [ -f "$SCRIPT_DIR/00-utils.sh" ]; then
source "$SCRIPT_DIR/00-utils.sh"
else
echo "Error: 00-utils.sh not found."
exit 1
fi
check_root
section "Phase 2b" "GPU Driver Setup"
# ==============================================================================
# 1. 变量声明与基础信息获取
# ==============================================================================
log "Detecting GPU Hardware..."
# 核心变量:存放 lspci 信息
GPU_INFO=$(lspci -mm | grep -E -i "VGA|3D|Display")
log "GPU Info Detected:\n$GPU_INFO"
# 状态变量初始化
HAS_AMD=false
HAS_INTEL=false
HAS_NVIDIA=false
GPU_NUMBER=0
# 待安装包数组
PKGS=("libva-utils")
# ==============================================================================
# 2. 状态变更 & 基础包追加 (Base Packages)
# ==============================================================================
# --- AMD 检测 --- -q 静默,-i忽略大小写
if echo "$GPU_INFO" | grep -q -i "AMD\|ATI"; then
HAS_AMD=true
info_kv "Vendor" "AMD Detected"
# 追加 AMD 基础包
PKGS+=("mesa" "lib32-mesa" "xf86-video-amdgpu" "vulkan-radeon" "lib32-vulkan-radeon" "linux-firmware-amdgpu" "gst-plugin-va" "opencl-mesa" "lib32-opencl-mesa" "opencl-icd-loader" "lib32-opencl-icd-loader" )
fi
# --- Intel 检测 ---
if echo "$GPU_INFO" | grep -q -i "Intel"; then
HAS_INTEL=true
info_kv "Vendor" "Intel Detected"
# 追加 Intel 基础包 (保证能亮机,能跑基础桌面)
PKGS+=("mesa" "vulkan-intel" "lib32-mesa" "lib32-vulkan-intel" "gst-plugin-va" "linux-firmware-intel" "opencl-mesa" "lib32-opencl-mesa" "opencl-icd-loader" "lib32-opencl-icd-loader" )
fi
# --- NVIDIA 检测 ---
if echo "$GPU_INFO" | grep -q -i "NVIDIA"; then
HAS_NVIDIA=true
info_kv "Vendor" "NVIDIA Detected"
# 追加 NVIDIA 基础工具包
fi
# --- 多显卡检测 ---
GPU_COUNT=$(echo "$GPU_INFO" | grep -c .)
if [ "$GPU_COUNT" -ge 2 ]; then
info_kv "GPU Layout" "Dual/Multi-GPU Detected (Count: $GPU_COUNT)"
# 安装 vulkan-mesa-layers 以支持 vk-device-select
PKGS+=("vulkan-mesa-layers" "lib32-vulkan-mesa-layers")
if [[ $HAS_NVIDIA == true ]]; then
PKGS+=("nvidia-prime" "switcheroo-control")
# fix gtk4 issue with nvidia dual gpu
if grep -q "GSK_RENDERER" "/etc/environment"; then
echo 'GSK_RENDERER=gl' >> /etc/environment
fi
fi
fi
# ==============================================================================
# 3. Conditional 包判断
# ==============================================================================
# ------------------------------------------------------------------------------
# 3.1 Intel 硬件编解码判断
# ------------------------------------------------------------------------------
if [ "$HAS_INTEL" = true ]; then
if echo "$GPU_INFO" | grep -q -E -i "Arc|Xe|UHD|Iris|Raptor|Alder|Tiger|Rocket|Ice|Comet|Coffee|Kaby|Skylake|Broadwell|Gemini|Jasper|Elkhart|HD Graphics 6|HD Graphics 5[0-9][0-9]\b"; then
log " -> Intel: Modern architecture matched (iHD path)..."
PKGS+=("intel-media-driver")
else
warn " -> Intel: Legacy or Unknown model. Skipping intel-media-driver."
fi
fi
# ------------------------------------------------------------------------------
# 3.2 NVIDIA 驱动版本与内核 Headers 判断
# ------------------------------------------------------------------------------
if [ "$HAS_NVIDIA" = true ]; then
NV_MODEL=$(echo "$GPU_INFO" | grep -i "NVIDIA" | head -n 1)
# 初始化一个标志位,只有匹配到支持的显卡才设为 true
DRIVER_SELECTED=false
# ==========================================================================
# nvidia-open
# ==========================================================================
if echo "$NV_MODEL" | grep -q -E -i "RTX|GTX 16"; then
log " -> NVIDIA: Modern GPU detected (Turing+). Using Open Kernel Modules."
# 核心驱动包
PKGS+=("nvidia-open-dkms" "nvidia-utils" "lib32-nvidia-utils" "opencl-nvidia" "lib32-opencl-nvidia" "libva-nvidia-driver" "vulkan-icd-loader" "lib32-vulkan-icd-loader" "opencl-icd-loader" "lib32-opencl-icd-loader")
DRIVER_SELECTED=true
# ==========================================================================
# nvidia-580xx-dkms
# ==========================================================================
elif echo "$NV_MODEL" | grep -q -E -i "GTX 10|GTX 950|GTX 960|GTX 970|GTX 980|GTX 745|GTX 750|GTX 750 Ti|GTX 840M|GTX 845M|GTX 850M|GTX 860M|GTX 950M|GTX 960M|GeForce 830M|GeForce 840M|GeForce 930M|GeForce 940M|GeForce GTX Titan X|Tegra X1|NVIDIA Titan X|NVIDIA Titan Xp|NVIDIA Titan V|NVIDIA Quadro GV100"; then
log " -> NVIDIA: Pascal/Maxwell GPU detected. Using Proprietary DKMS."
PKGS+=("nvidia-580xx-dkms" "nvidia-580xx-utils" "opencl-nvidia-580xx" "lib32-opencl-nvidia-580xx" "lib32-nvidia-580xx-utils" "libva-nvidia-driver" "vulkan-icd-loader" "lib32-vulkan-icd-loader" "opencl-icd-loader" "lib32-opencl-icd-loader" )
DRIVER_SELECTED=true
# ==========================================================================
# nvidia-470xx-dkms
# ==========================================================================
elif echo "$NV_MODEL" | grep -q -E -i "GTX 6[0-9][0-9]|GTX 760|GTX 765|GTX 770|GTX 775|GTX 780|GTX 860M|GT 6[0-9][0-9]|GT 710M|GT 720|GT 730M|GT 735M|GT 740|GT 745M|GT 750M|GT 755M|GT 920M|Quadro 410|Quadro K500|Quadro K510|Quadro K600|Quadro K610|Quadro K1000|Quadro K1100|Quadro K2000|Quadro K2100|Quadro K3000|Quadro K3100|Quadro K4000|Quadro K4100|Quadro K5000|Quadro K5100|Quadro K6000|Tesla K10|Tesla K20|Tesla K40|Tesla K80|NVS 510|NVS 1000|Tegra K1|Titan|Titan Z"; then
log " -> NVIDIA: Kepler GPU detected. Using nvidia-470xx-dkms."
PKGS+=("nvidia-470xx-dkms" "nvidia-470xx-utils" "opencl-nvidia-470xx" "vulkan-icd-loader" "lib32-nvidia-470xx-utils" "lib32-opencl-nvidia-470xx" "lib32-vulkan-icd-loader" "libva-nvidia-driver" "opencl-icd-loader" "lib32-opencl-icd-loader")
DRIVER_SELECTED=true
# ==========================================================================
# others
# ==========================================================================
else
warn " -> NVIDIA: Legacy GPU detected ($NV_MODEL)."
warn " -> Please manually install GPU driver."
fi
# ==========================================================================
# headers
# ==========================================================================
if [ "$DRIVER_SELECTED" = true ]; then
log " -> NVIDIA: Scanning installed kernels for headers..."
# 1. 获取所有以 linux 开头的候选包
CANDIDATES=$(pacman -Qq | grep "^linux" | grep -vE "headers|firmware|api|docs|tools|utils|qq")
for kernel in $CANDIDATES; do
# 2. 验证:只有在 /boot 下存在对应 vmlinuz 文件的才算是真内核
if [ -f "/boot/vmlinuz-${kernel}" ]; then
HEADER_PKG="${kernel}-headers"
log " + Kernel found: $kernel -> Adding $HEADER_PKG"
PKGS+=("$HEADER_PKG")
fi
done
fi
fi
if systemd-detect-virt -q; then
log "virtualmachine detected"
PKGS+=("spice-vdagent")
fi
# ==============================================================================
# 4. 执行
# ==============================================================================
DETECTED_USER=$(awk -F: '$3 == 1000 {print $1}' /etc/passwd)
TARGET_USER="${DETECTED_USER:-$(read -p "Target user: " u && echo $u)}"
#--------------sudo temp file--------------------#
SUDO_TEMP_FILE="/etc/sudoers.d/99_shorin_installer_temp"
echo "$TARGET_USER ALL=(ALL) NOPASSWD: ALL" >"$SUDO_TEMP_FILE"
chmod 440 "$SUDO_TEMP_FILE"
log "Temp sudo file created..."
# 定义清理函数:无论脚本是成功结束还是意外中断(Ctrl+C),都确保删除免密文件
cleanup_sudo() {
if [ -f "$SUDO_TEMP_FILE" ]; then
rm -f "$SUDO_TEMP_FILE"
log "Security: Temporary sudo privileges revoked."
fi
}
# 注册陷阱:在脚本退出(EXIT)或被中断(INT/TERM)时触发清理
trap cleanup_sudo EXIT INT TERM
if [ ${#PKGS[@]} -gt 0 ]; then
# 数组去重
UNIQUE_PKGS=($(printf "%s\n" "${PKGS[@]}" | sort -u))
section "Installation" "Installing Packages"
log "Target Packages: ${UNIQUE_PKGS[*]}"
# 执行安装
exe runuser -u "$TARGET_USER" -- yay -S --noconfirm --needed --answerdiff=None --answerclean=None "${UNIQUE_PKGS[@]}"
log "Enabling services (if supported)..."
systemctl enable --now nvidia-powerd &>/dev/null || true
systemctl enable switcheroo-control.service &>/dev/null || true
systemctl enable nvidia-suspend.service &>/dev/null || true
systemctl enable nvidia-hibernate.service &>/dev/null || true
systemctl enable nvidia-resume.service &>/dev/null || true
success "GPU Drivers processed successfully."
else
warn "No GPU drivers matched or needed."
fi
log "Module 02b completed."