SDB:NVIDIA 不易之路
安装编译 NVIDIA 驱动需要的软件包
我们需要三个软件包:
- gcc,编译器,即真正把源代码翻译为可执行文件的程序
- make,通过 Makefile 管理 gcc 编译顺序的程序
- kernel-devel,内核的“开发包”,提供了一些“头文件”(告诉我们它有哪些可调用的函数)
在 openSUSE 下面,您可以打开 YaST -> 软件管理,然后搜索这三个软件包,也可以在命令行下
安装。我建议您打开您的“终端模拟器”(konsole 或 gnome-terminal)在命令行下进行操作。先熟悉一下命令行界面。
下载 NVIDIA 官方驱动
还有图形模式的时候(也就是更新/升级后、还没重启前),用浏览器访问 NVIDIA 主页: http://www.nvidia.com/object/unix.html 下载驱动。
需要通过型号判断使用什么驱动,点驱动的版本号,然后切换到 Supported Products 可以看到该驱动支持的型号。
型号可以通过 lspci 查看,打开终端输入:
sudo /sbin/lspci | grep VGA
还要选择正确的系统架构 x86 或 x86_64。如果不能确定,可以打开终端输入:
uname -m
返回值除了显示为 x86_64,否则一般使用 x86 驱动(如果你是 ARM 你自己应该知道)。
纯命令行下下载 NVIDIA 官方驱动
您更新了内核,却没有对应的显卡驱动软件包的话,openSUSE 会卡在“开机动画”(正确的名字是 Plymouth Theme)那里一直等,进不去图形界面,也不会出现显示管理器(Display Manager,DM)的登陆界面。所以当您遇到这种情况的时候,一定要第一时间想到是不是更新了内核却没有对应的显卡驱动。这不是一个 bug,只是您的一个小疏忽,但这是大多数用户认为更新/升级后无法登入系统的根源。Be smart!👻👻👻
这时您需要同时按下 Ctrl、Alt 和 F1 键,切换到命令行(tty)。
输入普通用户名和密码按回车键登入(密码不显示,不要重复输入)。
因为 openSUSE 的图形界面使用 NetworkManager 管理网络(记得 KDE 进入后会弹出窗口提示您输入 root 密码连接无线网络?)纯命令行下,你可能上不去网。所以先来测试下网络:
e 开头的那个连接是有线,w 开头的那个是无线。如果没有网络连接,对应的 inet addr 字段是没有的。或者也可以:
这个会更加直接一些。
如果确认没有网络连接,您需要看看 SDB:命令行下连接网络连上网络,出于篇幅限制,我们只介绍 nmcli(NetworkManager 的命令行版本)连接无线网络的命令,别的方式和情况请看原文。
没有报错即是成功,也可以用上面的方法再确认一遍。
我们假设您已经连上网了。NVIDIA 驱动的下载地址在:
版本号你可以用手机访问 NVIDIA 官网选择(一般来说 US 官网会领先 CN 官网),架构上面说了可以用 uname -m 得到。
下面我们使用 wget 下载驱动到 /home/marguerite:
cd ~ wget -C http://us.download.nvidia.com/XFree86/Linux-x86_64/378.13/NVIDIA-Linux-x86_64-378.13.run
-C 表示下载任务中断后可以继续。所以你有事可以先按 Ctrl + C 中断任务,回头再用上面的 wget 命令继续下载。
安装 NIVIDIA 驱动
如果您还在图形界面下的话,请先保存好你的工作,然后注销。
在登陆管理器输入密码那个界面,同时按下 Ctrl、Alt 和 F1 键切换到命令行控制台。
以普通用户名和密码登入命令行。
接下来我们假设您的普通用户名是 opensuse。
因为安装显卡驱动是对底层的作业,我们需要切换到 root 用户。
输入您的 root 密码 (您在命令行看不到任何反馈),然后按下回车键。
切换到 init 3 模式:
openSUSE Leap 42.3 的用户还需要先卸载掉 drm-kmp-default 这个包:
zypper --no-refresh rm drm-kmp-default
假设您把 NVIDIA 驱动放到了用户主目录,输入:
替换 "opensuse” 为您的用户名。然后按回车键就启动了安装程序。
然后按回车键下一步下一步操作即可。
- 安装程序会提示您是否使用 dkms,这里要选 NO。
- 在最新版的安装程序中,会破天荒的出现一个三个选项的提示,"An incomplete installation of libglvnd was found"。您可以选择第二个选项覆盖安装。也可以这么启动安装程序 sh NVIDIA-*.run -aqs --install-libglvnd,会自动回答这个问题。
如果不成功,安装程序会提示您查看 /var/log/nvidia-install.log。
这时候也请不要担心,因为这不是你的错误,只是你要多做一些事来修复他们的错误,这很棒不是吗?
为官方驱动打补丁
有些时候 NVIDIA 官方驱动并不是紧跟 Linux 内核的更新,会导致内核模块编译失败。
这时有两个解决方法:
- 降级内核,等到 NVIDIA 新版驱动出来,这是保守的方法。
- 查找补丁。一般来说,你并不是第一个遇到这个问题的,https://devtalk.nvidia.com/default/board/98/linux/ 上可能早就出补丁了。
首先,您要查看 /var/log/nvidia-installer.log 搞清楚错误是什么。
cd /var/log vi nvidia-installer.log
然后按向下键盘,翻到“-> Building kernel modules”这里,仔细往下看,会看到“Error: xxx”这样的文字,把那个错误,或者从“-> Building kernel modules“一直到这行文字的内容全部拍照留存,发到 forum.suse.org.cn 去问。如果有点能力,也可以在 Google 上搜索对应的 Error,一般会看到 devtalk.nvidia.com 有讨论这个问题,甚至还给出了补丁。
先解压 NVIDIA-*.run 驱动:
sh NVIDIA-Linux-x86_64-390.25.run --extract-only
会得到一个名为 NVIDIA-Linux-x86_64-390.25 的文件夹:
cd NVIDIA-Linux-x86_64-390.25
根据SDB:如何制作补丁的教学制作补丁。
把补丁复制到上级目录:
cp -r xxx.patch ..
然后对 NVIDIA-Linux-x86_64-390.25.run 应用补丁:
sh NVIDIA-Linux-x86_64-390.25.run --apply-patch xxx.patch
会生成一个 NVIDIA-Linux-x86_64-390.25-custom.run 的文件,你可以使用这个 custom.run 像安装官方驱动那样安装。
禁用内核模式设置 (KMS)
nouveau 是使用 KMS 的,NVIDIA 官方驱动对 KMS 的支持不是很好,所以通过禁用 KMS 与下面的禁用 nouveau 驱动配合可以实现完全禁用 nouveau 的目的。
Grub Legacy
打开 /boot/grub/menu.lst 文件,查找 menuentry,注意要使用不是恢复模式的那个,然后在这个 menuentry 下面查找 showopts,在 showopts 后面写上 nomodeset,关闭文件即可。
接着编辑 /etc/sysconfig/kernel,修改 "NO-KMS-IN-INITRD = yes",关闭文件,然后运行:
mkinitrd
来从 initrd 中移除 KMS。
Grub2
跟上面差不多,通过编辑 /boot/grub2/grub.cfg 来实现 nomodeset。通过:
grub2-install --boot-directory=/boot /dev/sdaN
来安装新的 config。
/dev/sdaN 是您的 boot 分区,可以通过:
blkid
来判断。
或者您也可以通过把 nouveau 模块完全从 initrd 中剔除,配合 blacklist 禁用 nouveau 驱动的方式来做。
禁用开源驱动 nouveau
为了避免闭源 NVIDIA 驱动与默认的开源 nouveau 驱动冲突,禁用 nouveau 模块以防止引导期间被加载。
echo "blacklist nouveau" >> /etc/modprobe.d/50-blacklist.conf echo "options nouveau modeset=0" >> /etc/modprobe.d/50-blacklist.conf
为了轻微加快开机速度,您也可以把没人用的 nv 驱动也禁用下:
cho "blacklist nv" >> /etc/modprobe.d/50-blacklist.conf
如果您想要再次使用 nouveau 驱动您需要反向操作一下,比如在升级到 openSUSE 12.2 的更成熟可用的 nouveau 之后 (openSUSE 11.4 不行)。
重新制作 initrd
下面我们需要重新制作 initrd,添加编译好的 NVIDIA 内核模块,并把 nouveau 开源驱动模块从 initrd 中剔除。
openSUSE 的 initrd 在 /boot 目录下,命名为 initrd-4.15.13-1-default,你需要使用:
uname -r
来确认你的内核版本,以防做错了 initrd。
现行版本的 openSUSE 使用 dracut 来生成 initrd,mkinitrd 命令是调用它的一个脚本。失去支持的版本的 openSUSE 直接运行 mkinitrd 即可。
NVIDIA 官方驱动的三个内核模块名叫做 nvidia_drm, nvidia_modeset 和 nvidia。我们只需要在现有 initrd 的基础上,添加这三个模块,并剔除 nouveau 和 nv 模块即可:
sudo dracut --add-drivers "nvidia_drm nvidia_modeset nvidia" --omit-drivers "nouveau nv" --rebuild /boot/initrd-4.15.13-1-default
同理,卸载官方驱动时使用相反命令:
sudo dracut --omit-drivers "nvidia_drm nvidia_modeset nvidia" --add-drivers "nouveau nv" --rebuild /boot/initrd-4.15.13-1-default
重新进入图形界面
能看到这里,表示您的 NVIDIA 驱动已经安装成功了。但是现在您仍然停留在命令行环境下。
最简单的方法就是运行:
shutdown -r now
重启计算机。但还有一个不重启的方法,运行:
init 5
启动图形界面,如果看到的是黑屏,试着按 Ctrl + Alt + F7/F8 切换一下 TTY 到 7 或 8。
你应该就能看见图形界面了!
这时,您的 TTY 1 实际上还是登录着的,这在你在图形界面下关机时会有一个提示。您可以在图形界面下关机时按提示选择,也可以按 Ctrl + Alt + F1 切回 TTY 1, 多输入几次 exit 直到退回到输密码界面再 Ctrl + Alt + F7/F8 切回图形界面。
配置
openSUSE 11.3 之后 Sax2 被移除了。请使用 nvidia-setting 设置您的显卡。有些报告说在双屏幕上需要安装 "twinview" 才能让混成可用,twinview 是 NVIDIA 的 xinerama 替代。
其它
使用 DKMS 动态重编译内核模块
DKMS 会在内核更新后自动针对新内核重新编译 NVIDIA 的内核模块,让新内核也能自动用上老驱动,简而言之就是每次不用手动重装。
多显示器配置
参考下面的 ArchLinux 维基和 https://download.nvidia.com/XFree86/Linux-x86_64/390.25/README/index.html
GTX 1080 撕裂问题
https://forum.suse.org.cn/t/nvidia-geforce-gtx-1080/4652
撕裂都可以参考。
GRUB2 和虚拟终端分辨率问题
把 /etc/default/grub 里面的:
GRUB_GFXMODE="auto"
替换成:
GRUB_GFXMODE=1920x1080x32 GRUB_GFXPAYLOAD_LINUX=keep
然后重制 grub.cfg:
grub2-mkconfig -o /boot/grub2/grub.cfg
再仿造上面方法安装新的 config 即可。
Plymouth 显示”口口口“问题
openSUSE 的开机动画 Plymouth 天生和 NVIDIA 官方驱动不友好,切换回看文字可以仿照上面的方法添加内核选项。
把 splash=slient quiet 替换成 plymouth.enable=0 即可。嫌消息太多可以再加一个 loglevel=5。
卸载官方驱动并换回 nouveau
Ctrl + Alt + F1 切换到 TTY 1
首先运行:
init 3
然后运行:
sh NVIDIA-Linux-x86_64-390.25.run --uninstall
然后编辑 /etc/modprobe.d/50-blacklist.conf 把 blacklist 的内容删除掉。
然后编辑 grub 的 config 把 nomodeset 删除掉,安装新的 config。
然后重装 libglvnd0
zypper in --force libglvnd0
openSUSE Leap 42.3 用户还要重装 drm-kmp-default:
zypper in drm-kmp-default
然后重制 initrd 把 nouveau 加回去,nvidia 对应的剔除掉。
然后运行:
shutdown -r now
重启。
其它源相关
OBS 的 X11:Bumblebee 源提供了针对 Bumblebee 的方案,其中打包 NVIDIA 官方驱动的方式可以用来打包一个正常的非双显卡的 NVIDIA 驱动软件包。
相关 wiki 页面
https://wiki.archlinux.org/index.php/NVIDIA_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)