这是关于我为我的 Nvidia GTX GeForce 860M 显卡启动Ubuntu 17.10 x86_64
clang-built Linux 4.15.7 kernel
(目前最新的稳定版本)和专有Nvidia 390.25
(目前最新的)驱动程序的成功经验。
问题
Linux 内核 4.15.7 是使用clang
主机和目标编译器构建的,并根据默认内核配置与模块一起安装。我不得不禁用模块,因为它有不支持的exofs
非标准“嵌入在结构中的 VLA” 。然后,我还在从其专有安装程序中提取驱动程序源代码后对其进行了编译 - 我不得不忽略编译器版本不匹配伪警告,因为内核头文件包含线程模型和平台信息,而 Nvidia 驱动程序脚本检查仅得出版本。clang
Nvidia 390.25
安装这样构建的 Nvidia 驱动程序模块后,我重新启动了系统,但 Ubuntu 17.10 启动没有完成 - 它卡在了Loading ... 4.15.7
。
为了进一步隔离内核与 gcc/clang 以及 Nvidia 驱动程序与 gcc/clang 之间的兼容性问题(如果有的话),使用 编译了 Linux 内核 4.15.7,使用gcc
Nvidia 390.25 驱动程序clang
,反之亦然。对于第一个,启动过程通过了该Loading ... 4.15.7
阶段并转移到某个systemd
服务,但卡在那里。对于第二个,它再次卡在该Loading ... 4.15.7
阶段。系统journalctl
/logs 没有多大帮助。
答案1
阶段1:由于之前使用过 Qemu/Kvm,我想找到启动 clang 构建的内核时的实际失败点。因此,我尝试在 Qemu/kvm busybox
x86_64 上使用 x86_64 默认配置启动 clang 构建的 Linux 内核 4.15.7 映像,并为根文件系统 (initrd) 启动 clang 构建的 x86_64。这很有效。我得到了 shell,busybox
实用程序正在运行等等。
在主机 Ubuntu 17.10 x86_64 上:
$ strings -a defconfig-linux-4.15.7/linux-4.15.7/vmlinux | grep "clang version" | head -1
Linux version 4.15.7 (exp@exp) (clang version 5.0.0-3 (tags/RELEASE_500/final)) #1 SMP Fri Mar 2 21:15:24 PST 2018
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 17.10
Release: 17.10
Codename: artful
$ clang -v
clang version 5.0.0-3 (tags/RELEASE_500/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
在 Qemu/kvm 客户机中,Linux 内核 4.15.7(x86_64 defconfig)/Busybox 64 位:
/ # cat /proc/version
Linux version 4.15.7 (exp@exp) (clang version 5.0.0-3 (tags/RELEASE_500/final)) #1 SMP Fri Mar 2 21:15:24 PST 2018
/ #
/ # uname -arv
Linux (none) 4.15.7 #1 SMP Fri Mar 2 21:15:24 PST 2018 x86_64 GNU/Linux
/ #
/ #
/ # strings -a bin/busybox | grep "clang version"
clang version 5.0.0-3 (tags/RELEASE_500/final)
/ #
/ #
/ # dmesg | grep QEMU
[ 0.000000] DMI: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org 04/01/2014
[ 0.024000] smpboot: CPU0: Intel QEMU Virtual CPU version 2.5+ (family: 0x6, model: 0x6, stepping: 0x3)
[ 0.337415] ata2.00: ATAPI: QEMU DVD-ROM, 2.5+, max UDMA/100
[ 0.339072] scsi 1:0:0:0: CD-ROM QEMU QEMU DVD-ROM 2.5+ PQ: 0 ANSI: 5
/ #
/ #
第二阶段:有了上述使用 defconfig 内核的初步成功,我采用了主机 Ubuntu 17.10 内核配置并重建了 Linux 内核 4.15.7 映像。这样,我保留了 busybox 的其余部分,并尝试像之前一样在 Qemu/kvm 上启动它们 - 但这没有奏效。结果为general protection faults
和kernel oops
- kernel panic
。我查看了内核堆栈转储。
我注意到第一个问题出在kernel irq work tick
逻辑上。然后下一个问题与kernel live instruction update
逻辑有关。我对这两个问题都进行了研究。重建了内核。再次尝试使用 Qemu/kvm - 获得了 shell,这次没有崩溃。下一步是安装内核模块和 Nvidia 驱动程序模块。我这样做了,但这次,使用所有的 Ubuntu 内核模块和 Nvidia 驱动程序模块,Qemu/kvm 显示了一些彩色像素并卡住了 - 主要是由于主机硬件和客户机虚拟化硬件之间的差异。所以,我只想尝试使用 Nvidia 驱动程序,因为它是我在主机上用于图形的驱动程序,因此是主要关注点。因此,我在 busybox rootfs 中包含(未安装)Nvidia 驱动程序模块,并尝试像往常一样启动 Qemu/kvm - 这次,由于 rootfs-not-found 导致内核崩溃,尽管有一个 rootfs。
因此,我尝试将所有 Nvidia 驱动程序模块压缩到一个 zip 中,并将其包含在 rootfs 中。但是,当我尝试使用 Qemu/kvm 客户机提取 zip 时,出现了no space left on device
。因此,我尝试构建一个 10G 虚拟 qemu 磁盘并在该磁盘中安装 rootfs 以解决空间问题 - 但是,过了一段时间,我取消了这一计划,因为我更感兴趣的是将 clang 构建的 Nvidia 驱动程序应用于真实系统硬件,而不是模拟的 Qemu/kvm 环境(我知道它没有通过 GPU 直通提供的真正 Nvidia 显卡,因此在我尝试在主机的真实系统硬件/显卡上测试 clang 构建的 Nvidia 390.25 驱动程序之前,我还是尝试了一下,只是为了看看 clang 构建的 Nvidia 驱动程序在加载时是否在 Qemu/kvm 中出现任何问题)。
在 Qemu/kvm 客户机中,Linux 内核 4.15.7(主机 Ubuntu 17.10 x86_64 配置)/Busybox64 位:
/ # cat /proc/version
Linux version 4.15.7 (exp@exp) (clang version 5.0.0-3 (tags/RELEASE_500/final)) #20 SMP Sat Mar 3 20:46:15 PST 2018
/ #
/ #
/ # uname -arv
Linux (none) 4.15.7 #20 SMP Sat Mar 3 20:46:15 PST 2018 x86_64 GNU/Linux
/ #
/ #
/ #
/ # dmesg | grep QEMU
[ 0.000000] DMI: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org 04/01/2014
[ 0.024000] smpboot: CPU0: Intel QEMU Virtual CPU version 2.5+ (family: 0x6, model: 0x6, stepping: 0x3)
[ 0.340776] ata2.00: ATAPI: QEMU DVD-ROM, 2.5+, max UDMA/100
[ 0.343135] scsi 1:0:0:0: CD-ROM QEMU QEMU DVD-ROM 2.5+ PQ: 0 ANSI: 5
/ #
/ # strings -a bin/busybox | grep "clang version"
clang version 5.0.0-3 (tags/RELEASE_500/final)
/ #
第 3 阶段及成功:由于我的主要和实际目标是我的主机(Ubuntu 17.10),我直接在主机系统上安装了这个 clang 构建的内核(解决了上述问题)和 Nvidia 390.25 驱动程序。重新启动我的系统。砰!我使用 clang 构建的 4.15.7 内核和 clang 构建的 Nvidia 390.25 驱动程序启动并运行了我的 Ubuntu 17.10 x86_64,没有任何问题。
在主机 Ubuntu 17.10 x86_64 上,使用 clang 构建的 Linux 内核 4.15.7 和 clang 构建的 Nvidia 390.25 GeForce GTX 860M 专有驱动程序 - 我的成功研究和经验:
$ dmesg | grep clang
[ 0.000000] Linux version 4.15.7 (exp@exp) (clang version 5.0.0-3 (tags/RELEASE_500/final)) #20 SMP Sat Mar 3 20:46:15 PST 2018
$ cat /proc/version
Linux version 4.15.7 (exp@exp) (clang version 5.0.0-3 (tags/RELEASE_500/final)) #20 SMP Sat Mar 3 20:46:15 PST 2018
$ uname -arv
Linux exp 4.15.7 #20 SMP Sat Mar 3 20:46:15 PST 2018 x86_64 x86_64 x86_64 GNU/Linux
$ nvidia-smi
Sun Mar 4 18:15:39 2018
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 390.25 Driver Version: 390.25 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 860M Off | 00000000:01:00.0 Off | N/A |
| N/A 54C P0 N/A / N/A | 370MiB / 4046MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
exp@exp:~$ dmesg | grep NVIDIA | grep 390.25
[ 17.643496] NVRM: loading NVIDIA UNIX x86_64 Kernel Module 390.25 Wed Jan 24 20:02:43 PST 2018 (using threaded interrupts)
[ 17.689835] nvidia-modeset: Loading NVIDIA Kernel Mode Setting Driver for UNIX platforms 390.25 Wed Jan 24 19:29:37 PST 2018
$ lsmod | grep nvidia
nvidia_uvm 815104 0
nvidia_drm 24576 2
nvidia_modeset 1097728 5 nvidia_drm
nvidia 14352384 334 nvidia_uvm,nvidia_modeset
ipmi_msghandler 61440 2 nvidia,ipmi_devintf
drm 454656 6 nvidia_drm,i915,drm_kms_helper
# clang-built Linux kernel 4.15.7 image and Nvidia 390.25 driver modules having clang compiler specific
# metadata within them.
#
$ eclang /lib/modules/4.15.7/build/vmlinux | grep "Linux"
++ strings -a /lib/modules/4.15.7/build/vmlinux
++ grep clang
Linux version 4.15.7 (exp@exp) (clang version 5.0.0-3 (tags/RELEASE_500/final)) #20 SMP Sat Mar 3 20:46:15 PST 2018
exp@exp:~$ eclang /lib/modules/4.15.7/kernel/drivers/video/nvidia.ko | head -1
++ strings -a /lib/modules/4.15.7/kernel/drivers/video/nvidia.ko
++ grep clang
clang version 5.0.0-3 (tags/RELEASE_500/final)
$ eclang /lib/modules/4.15.7/kernel/drivers/video/nvidia-drm.ko | head -1
++ strings -a /lib/modules/4.15.7/kernel/drivers/video/nvidia-drm.ko
++ grep clang
clang version 5.0.0-3 (tags/RELEASE_500/final)
$ eclang /lib/modules/4.15.7/kernel/drivers/video/nvidia-uvm.ko | head -1
++ strings -a /lib/modules/4.15.7/kernel/drivers/video/nvidia-uvm.ko
++ grep clang
clang version 5.0.0-3 (tags/RELEASE_500/final)
$ eclang /lib/modules/4.15.7/kernel/drivers/video/nvidia-modeset.ko | head -1
++ strings -a /lib/modules/4.15.7/kernel/drivers/video/nvidia-modeset.ko
++ grep clang
clang version 5.0.0-3 (tags/RELEASE_500/final)
# DMI specific hardware information - verifies and confirms the physical hardware used
# instead of QEMU or any other virtual platform for running clang-built kernel and
# Nvidia 390.25 driver.
#
$ sudo dmidecode -t bios | grep Vendor
Vendor: LENOVO
$ sudo dmidecode -t system | grep "Manufacturer:\|Version"
Manufacturer: LENOVO
Version: Lenovo Y50-70 Touch
$ sudo dmidecode -t processor | grep Version
Version: Intel(R) Core(TM) i7-4710HQ CPU @ 2.50GHz
注 1:对于所有详细的日志(来自每个阶段),你可以在这里阅读我对 LLVM-Clang/Linux 内核问题的回答:使用 LLVM/clang 构建 Linux 内核。
笔记2:在我看来,clang 的警告比 gcc 更繁琐。但是,目前,为了让内核/nvidia 驱动程序启动并运行,我忽略了它们,看看它们是否不严重(到目前为止它们并不严重)。
更新1:为了通用性,我用后续内核版本(截至 2018 年 3 月中旬是最新版本)和最新的 Nvidia 显卡 GTX GeForce 驱动程序 v390.42(截至 2018 年 3 月中旬是最新版本)重复了上述操作 - 它们均在更新内核 4.15.11 代码中的 IRQ 工作滴答逻辑和实时指令更新逻辑后使用与之前相同的方法构建,4.15.10
就像我对 4.15.7 所做的那样,最后将它们都直接安装在我的系统硬件上(这次没有进行 Qemu/kvm 实验,因为早期的 4.15.7 内核在处理 IRQ 工作滴答逻辑和实时指令更新逻辑后已经成功启动)。这样,Ubuntu 17.10 x86_64 再次成功出现在我的系统硬件上,在 clang 构建的内核 4.15.11 和 clang 构建的最新 Nvidia 驱动程序 v390.42 上,就像之前在内核 4.15.7 和 Nvidia 驱动程序 v390.25 的情况下一样。4.15.11
clang
以下是在 clang 构建的最新 v4.15.11 内核和 clang 构建的最新 Nvidia 驱动程序 v390.42 场景上运行 Ubuntu 17.10 x86_64 的详细信息:
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 17.10
Release: 17.10
Codename: artful
$ cat /proc/version
Linux version 4.15.11 (exp@exp) (clang version 5.0.0-3 (tags/RELEASE_500/final)) #2 SMP Tue Mar 20 05:37:06 PDT 2018
$ eclang /lib/modules/4.15.11/build/vmlinux | grep Linux
++ strings -a /lib/modules/4.15.11/build/vmlinux
++ grep clang
Linux version 4.15.11 (exp@exp) (clang version 5.0.0-3 (tags/RELEASE_500/final)) #2 SMP Tue Mar 20 05:37:06 PDT 2018
$ sudo dmidecode -t system | grep "Manufacturer:\|Version"
Manufacturer: LENOVO
Version: Lenovo Y50-70 Touch
$ dmesg | grep NVIDIA
[ 19.491452] nvidia: module license 'NVIDIA' taints kernel.
[ 19.499360] NVRM: loading NVIDIA UNIX x86_64 Kernel Module 390.42 Sat Mar 3 04:10:22 PST 2018 (using threaded interrupts)
[ 19.542830] nvidia-modeset: Loading NVIDIA Kernel Mode Setting Driver for UNIX platforms 390.42 Sat Mar 3 03:30:48 PST 2018
$ nvidia-smi
Tue Mar 20 22:15:00 2018
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 390.42 Driver Version: 390.42 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 860M Off | 00000000:01:00.0 Off | N/A |
| N/A 52C P8 N/A / N/A | 451MiB / 4046MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
$ glxinfo | grep NVIDIA
server glx vendor string: NVIDIA Corporation
client glx vendor string: NVIDIA Corporation
OpenGL vendor string: NVIDIA Corporation
OpenGL core profile version string: 4.5.0 NVIDIA 390.42
OpenGL core profile shading language version string: 4.50 NVIDIA
OpenGL version string: 4.6.0 NVIDIA 390.42
OpenGL shading language version string: 4.60 NVIDIA
OpenGL ES profile version string: OpenGL ES 3.2 NVIDIA 390.42
$ lsmod | grep nv
nvidia_uvm 815104 0
nvidia_drm 24576 2
nvidia_modeset 1105920 5 nvidia_drm
nvidia 14368768 334 nvidia_uvm,nvidia_modeset
ipmi_msghandler 61440 2 nvidia,ipmi_devintf
drm 454656 6 nvidia_drm,i915,drm_kms_helper
$ ~/nvidia-driver-compiler.sh
++ head -1
+++ uname -r
++ eclang /lib/modules/4.15.11/kernel/drivers/video/nvidia.ko
+++ strings -a /lib/modules/4.15.11/kernel/drivers/video/nvidia.ko
+++ grep clang
clang version 5.0.0-3 (tags/RELEASE_500/final)
++ head -1
+++ uname -r
++ eclang /lib/modules/4.15.11/kernel/drivers/video/nvidia-drm.ko
+++ strings -a /lib/modules/4.15.11/kernel/drivers/video/nvidia-drm.ko
+++ grep clang
clang version 5.0.0-3 (tags/RELEASE_500/final)
+++ uname -r
++ head -1
++ eclang /lib/modules/4.15.11/kernel/drivers/video/nvidia-modeset.ko
+++ strings -a /lib/modules/4.15.11/kernel/drivers/video/nvidia-modeset.ko
+++ grep clang
clang version 5.0.0-3 (tags/RELEASE_500/final)
+++ uname -r
++ head -1
++ eclang /lib/modules/4.15.11/kernel/drivers/video/nvidia-uvm.ko
+++ strings -a /lib/modules/4.15.11/kernel/drivers/video/nvidia-uvm.ko
+++ grep clang
clang version 5.0.0-3 (tags/RELEASE_500/final)
$ ~/nvidia_driver_modules_version.sh
++ grep '^version='
+++ uname -r
++ strings -a /lib/modules/4.15.11/kernel/drivers/video/nvidia.ko
version=390.42
++ grep '^version='
+++ uname -r
++ strings -a /lib/modules/4.15.11/kernel/drivers/video/nvidia-drm.ko
version=390.42
++ grep '^version='
+++ uname -r
++ strings -a /lib/modules/4.15.11/kernel/drivers/video/nvidia-uvm.ko
+++ uname -r
++ grep '^version='
++ strings -a /lib/modules/4.15.11/kernel/drivers/video/nvidia-modeset.ko
version=390.42