升级到 4.4.0-116 内核后的登录循环:图形登录屏幕 -> 黑屏 -> 图形登录屏幕

jfs*_*jfs 5 upgrade nvidia kernel graphics 16.04

后无法登录桌面环境apt upgrade && reboot:输入密码后,屏幕闪烁为黑屏并返回登录屏幕。通过终端 ( Ctrl+Alt+F1)登录工作正常。

/var/log/Xorg.0.log 说:

(EE) NVIDIA:无法初始化 NVIDIA 内核模块。请参阅
(EE) NVIDIA: 系统内核日志以了解其他错误消息和
(EE) NVIDIA:有关详细信息,请参阅 NVIDIA README。
(EE) 未检测到设备。

$ dmesg 说:

nvidia: version magic '4.4.0-116-generic SMP mod_unload modversions' 应该是 '4.4.0-116-generic SMP mod_unload modversions retpoline'

尝试手动加载 nvidia 驱动程序失败:

$ sudo modprobe nvidia
modprobe: ERROR: could not insert 'nvidia': Exec format error
Run Code Online (Sandbox Code Playgroud)

相关:内核升级后 VirtualBox 未启动

jfs*_*jfs 8

问题在于不支持 retpoline 的 gcc 版本(什么是 retpoline 以及它是如何工作的?)。请参阅 Ubuntu 错误:2/21 上的 4.4.0-116 内核更新破坏了 Nvidia 驱动程序(在 14.04 和 16.04 上)

在我的情况下,清除ppa:ubuntu-toolchain-r/test安装默认的 gcc 版本并使用 DKMS 重建 nvidia 模块(通过重新安装 4.4.0-116 内核)修复了问题。请参阅@cjjefcoat 在错误跟踪器上发布的说明

通过 purgingppa:ubuntu-toolchain-r/test的版本恢复默认的 gcc :

$ sudo apt-get install ppa-purge
$ sudo ppa-purge ppa:ubuntu-toolchain-r/test
Run Code Online (Sandbox Code Playgroud)

支持 retpoline 的 gcc 版本(在 Ubuntu 16.04 上):

$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
Run Code Online (Sandbox Code Playgroud)

重装内核:

$ sudo apt-get purge linux-headers-4.4.0-116 linux-headers-4.4.0-116-generic linux-image-4.4.0-116-generic linux-image-extra-4.4.0-116-generic linux-signed-image-4.4.0-116-generic
$ sudo apt-get install linux-generic linux-signed-generic
Run Code Online (Sandbox Code Playgroud)

检查 nvidia 模块:

$ modinfo nvidia_xxx -k 4.4.0-116-generic | grep vermagic
vermagic:       4.4.0-116-generic SMP mod_unload modversions retpoline 
Run Code Online (Sandbox Code Playgroud)

替换_xxx为您的版本 - 之后只需按 TABmodinfo nvidia

retpoline 应该在输出中。

之后就reboot顺利完成了。


如果您已经有兼容的 gcc 版本,您可以使用dkms命令重建 nvidia 模块而无需重新安装内核:

# dkms remove nvidia-xxx/yyy.zzz -k 4.4.0-116-generic
# dkms install nvidia-xxx/yyy.zzz -k 4.4.0-116-generic
Run Code Online (Sandbox Code Playgroud)

我决定重新安装内核,而不是更新使用错误的 gcc 版本使用 DKMS 重新构建的所有模块。