SDB:NVIDIA 不易之路

(重定向自SDB:NVIDIA the hard way
跳转至: 导航, 搜索
该文章教您如何在 openSUSE 上安装从 NVIDIA 官网下载的硬件驱动。我们也叫它“困难模式”。比起其它方法,本法要多做一些功课。这是您进入 openSUSE 世界后面对的第一个复杂问题,会尽可能碎碎念一些,让您能够一步一步跟着去做。
注意: 在您没有 100% 掌握本页面内容之前,请不要盲目更新 kernel 相关软件包或跨版本升级,把自己带进只有命令行界面可用的尴尬境地 😱😱😱


安装编译 NVIDIA 驱动需要的软件包

Linux 与 Windows 不同的一点在于,Linux 下绝大多数的自由开源软件都是以源代码的形式分发给最终用户的,上游很少会封装诸如 .exe 这样的可执行文件。所以这就涉及到了“编译”,即在您的电脑上把源代码变成可执行文件的过程。NVIDIA 驱动作为一个商业软件,提供了一部分可以运行的“库”(即看不到具体实现的源代码,但提供了接口,行为是确定的,的预编译文件)的同时,也提供了一部分源代码,用于编译内核模块(内核即 Linux 下与硬件直接通信并加载硬盘上的操作系统的底层部分,以模块形式支持第三方硬件)。这里我们就要编译 Nvidia 的内核模块来支持您的显卡,这可能会是您人生的第一次编译,所以,are you ready?😈

我们需要三个软件包:

  • gcc,编译器,即真正把源代码翻译为可执行文件的程序
  • make,通过 Makefile 管理 gcc 编译顺序的程序
  • kernel-devel,内核的“开发包”,提供了一些“头文件”(告诉我们它有哪些可调用的函数)
注意: 已经过了支持期限的 openSUSE 还需要安装 kernel-source。即内核的源代码。

在 openSUSE 下面,您可以打开 YaST -> 软件管理,然后搜索这三个软件包,也可以在命令行下

sudo zypper install gcc make kernel-devel


安装。我建议您打开您的“终端模拟器”(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 驱动 (NVIDIA-Linux-******.run) 保存在命令行能够访问的文件夹中 (路径中不能有中文,因为纯命令行下没有中文输入法)。

纯命令行下下载 NVIDIA 官方驱动

您更新了内核,却没有对应的显卡驱动软件包的话,openSUSE 会卡在“开机动画”(正确的名字是 Plymouth Theme)那里一直等,进不去图形界面,也不会出现显示管理器(Display Manager,DM)的登陆界面。所以当您遇到这种情况的时候,一定要第一时间想到是不是更新了内核却没有对应的显卡驱动。这不是一个 bug,只是您的一个小疏忽,但这是大多数用户认为更新/升级后无法登入系统的根源。Be smart!👻👻👻

以上多见于内核的大版本更新,比如 4.9 -> 4.10。因为 NVIDIA 官方源只是针对 openSUSE 新版本发布时点的内置内核提供显卡驱动软件包。在固定版本的 openSUSE 中,内核的大版本也是固定的,只会进行小版本的更新比如 4.9.1 -> 4.9.2,这时原来的驱动依然是能用的。只从 update 源进行更新不会出现上面的问题。怕就怕您自行添加了 OBS 上的 Kernel: 相关源,却不会使用困难模式安装显卡驱动。

这时您需要同时按下 Ctrl、Alt 和 F1 键,切换到命令行(tty)。

输入普通用户名和密码按回车键登入(密码不显示,不要重复输入)。

因为 openSUSE 的图形界面使用 NetworkManager 管理网络(记得 KDE 进入后会弹出窗口提示您输入 root 密码连接无线网络?)纯命令行下,你可能上不去网。所以先来测试下网络:

sudo /sbin/ip a


e 开头的那个连接是有线,w 开头的那个是无线。如果没有网络连接,对应的 inet addr 字段是没有的。或者也可以:

nslookup baidu.com


这个会更加直接一些。

如果确认没有网络连接,您需要看看 SDB:命令行下连接网络连上网络,出于篇幅限制,我们只介绍 nmcli(NetworkManager 的命令行版本)连接无线网络的命令,别的方式和情况请看原文。

sudo nmcli device wifi connect <你的 Wi-Fi 名字> password <你的 Wi-Fi 密码>


没有报错即是成功,也可以用上面的方法再确认一遍。

我们假设您已经连上网了。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 用户。

su


输入您的 root 密码 (您在命令行看不到任何反馈),然后按下回车键。

切换到 init 3 模式:

init 3


openSUSE Leap 42.3 的用户还需要先卸载掉 drm-kmp-default 这个包:

   zypper --no-refresh rm drm-kmp-default

假设您把 NVIDIA 驱动放到了用户主目录,输入:

# sh /home/opensuse/NVIDIA-*.run


替换 "opensuse” 为您的用户名。然后按回车键就启动了安装程序。

然后按回车键下一步下一步操作即可。

需要注意的两个地方:
  • 安装程序会提示您是否使用 dkms,这里要选 NO。
  • 在最新版的安装程序中,会破天荒的出现一个三个选项的提示,"An incomplete installation of libglvnd was found"。您可以选择第二个选项覆盖安装。也可以这么启动安装程序 sh NVIDIA-*.run -aqs --install-libglvnd,会自动回答这个问题。

如果不成功,安装程序会提示您查看 /var/log/nvidia-install.log。

这时候也请不要担心,因为这不是你的错误,只是你要多做一些事来修复他们的错误,这很棒不是吗?

为官方驱动打补丁

有些时候 NVIDIA 官方驱动并不是紧跟 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 的目的。

不知道如何在终端下编辑文件的请看基本 vim 操作指南。或者可以通过终端下运行 yast进入 Boot Loader 模块,通过内核参数选项卡来输入。

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

如果上面的每步都做过,这一步骤是可选的,仅针对洁癖和想轻微加快开机速度的需要。但如果您只使用了 blacklist 禁用 nouveau 模块而没有添加 nomodeset,那您就需要这步来把 blacklist 写入 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 切回图形界面。

配置

NVIDIA 官方驱动的安装步骤集成了调用 nvidia-xconfig 设置 xorg.conf 的步骤,所以这一步只有在极特殊情况下才需要手动运行。

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)