升级到4.4.0-116内核后登录循环:图形登录界面 – >黑屏 – >图形登录界面

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

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

(EE)NVIDIA:无法初始化NVIDIA内核模块。 请看看
(EE)NVIDIA:系统的内核日志,用于显示其他错误消息和
(EE)NVIDIA:有关详细信息,请参阅NVIDIA README。
(EE)未检测到任何设备。

$ dmesg说:

nvidia:版本魔术’4.4.0-116-通用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 

相关: VirtualBox在内核升级后无法启动

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

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

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

 $ sudo apt-get install ppa-purge $ sudo ppa-purge ppa:ubuntu-toolchain-r/test 

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

 $ gcc --version gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 

重新安装内核:

 $ 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 

检查nvidia模块:

 $ modinfo nvidia_xxx -k 4.4.0-116-generic | grep vermagic vermagic: 4.4.0-116-generic SMP mod_unload modversions retpoline 

用您的版本替换_xxx – 只需在modinfo nvidia之后按TAB即可

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 

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

我不知道Ask Ubuntu是否是一个正确的地方,但是 – 因为我需要新的g++并且仍然定期更新内核 – 我写了一个bash脚本(1)清除ppa:ubuntu-toolchain-r/test ,(2)重建所选内核的所有DKMS模块,(3)安装g++-7 – 根据这个答案 。

该脚本“按原样”提供,没有任何forms的保证。
请不要使用它,除非你理解每一行的含义。
这是为了节省您做手动的事情所花费的时间(而不是做你不理解的“魔法”)。

剧本:

 #!/bin/bash -e for list in /etc/apt/sources.list.d/ubuntu-toolchain-r*.list; do sudo cp -a "$list" "$list.backup" echo "Backed up $list to $list.backup" done sudo ppa-purge ppa:ubuntu-toolchain-r/test readarray -t kernels < <(ls -1 /lib/modules) echo "Kernels: ${kernels[*]}" for kernel in "${kernels[@]}"; do dkms_modules=($(sudo dkms status -k "$kernel" | sed -r 's#^([^,]+), ([^,]+), .*$#\1/\2#')) while true; do echo read -p "Reinstall DKMS-modules (${dkms_modules[*]}) on kernel $kernel? [Y/n] " choice if [ "${choice^^}" = N ]; then continue 2; fi if [ "${choice^^}" = Y ] || [ -z "$choice" ]; then break; fi echo "Expected 'y', 'n' or '', but got '$choice'" done echo for dkms_module in "${dkms_modules[@]}"; do sudo dkms remove -k "$kernel" "$dkms_module" sudo dkms install -k "$kernel" "$dkms_module" done echo for module in /lib/modules/"$kernel"/updates/dkms/*.ko; do vermagic="$(modinfo -F vermagic $module)" echo -n "Vermagic for $(basename ${module%.ko}): $vermagic -- " fgrep -q retpoline <<<"$vermagic" && echo ok || echo "'retpoline' is missing!!!" done done for list in /etc/apt/sources.list.d/ubuntu-toolchain-r*.list; do sudo mv "$list.backup" "$list" echo "Restored $list from $list.backup" done sudo apt update sudo apt install g++-7 sudo apt dist-upgrade