十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

无显示器Linux远程桌面花屏根因与修复:以麒麟2403为例

无显示器Linux远程桌面花屏根因与修复:以麒麟2403为例 先说结论麒麟 2403 在无显示器环境下用 x11vnc 做远程桌面花屏的锅不在 VNC也不在桌面组件而是 X server 启动时拿不到显示器的 EDID显卡驱动在“盲猜”输出参数像素格式错乱最终把画面渲染成一团花。你反复重装桌面没有用是因为重装桌面/DE 根本没有碰到底层的显示拓扑和驱动层配置。这篇文章我会把问题根因拆开再给出一套完整的、不需要重装系统的解决方案顺便把 x11vnc 的踩坑配置一并说清楚。这套内容主要适合三类人给麒麟 2403 做无头化部署的运维、喜欢用旧电脑当服务器想省一块显示器的折腾党、以及被“花屏”两个字折磨到准备重装系统的苦主。文章里所有命令我都直接在麒麟 2403 上实测过如果你的桌面环境略有差异稍作调整即可。1. 问题场景与根因拆解先说场景一台装了麒麟 2403 的机器放在弱电井或者机柜里没有接显示器通过 SSH 进去配好 x11vnc然后用 VNC 客户端连上去结果屏幕上是雪花条纹、彩色波浪线或者半张桌面在漂移根本没法操作。很多人第一反应是显卡驱动坏了第二反应是 x11vnc 没装好第三反应就是重装系统或者重装桌面。实际上这三步全是白费工夫。1.1 无显示器开机到底卡在哪一步Linux 图形栈的启动链路是内核 DRM 驱动初始化 → X server或 Wayland compositor根据显示输出口信息创建 Screen → 桌面环境绘制画面 → x11vnc 把画面以 RFB 协议转发给 VNC 客户端。问题就出在第二步。X server 在初始化时需要通过显示输出接口读取显示器的 EDID 数据里面包含了分辨率、刷新率、物理尺寸这些信息。有显示器的时候这个流程很顺畅驱动读到 EDID 后就知道该输出什么参数。但如果你没接显示器X server 就只能“盲猜”。不同驱动在无显示器时的表现完全不一样。Intel 核显在无头模式下会默认走虚拟输出虽然能启动但分辨率可能被限制在 1024x768 或者更低AMD 和 NVIDIA 的老驱动在某些版本下直接拒绝启动 X。麒麟 2403 默认基于 Linux 内核 6.x桌面端大多用 Mesa 的 modesetting 驱动这类驱动的行为是没有 EDID 时它会按芯片组默认的 modelist 来配置输出而这个默认 modelist 往往和 VNC 客户端期望的深度、时钟对不上。对不上的结果不是黑屏而是花屏。因为 X server 以为自己在以 1920x108060Hz 输出实际上画到帧缓冲里的像素排列方式却是另一种格式x11vnc 读取像素时按照错误的 stride/对齐方式去解析画面自然就花了。1.2 为什么是花屏而不是黑屏很多人的惯性思维是没有显示器就应该是黑屏怎么会花屏其实花屏恰恰说明链路是通的数据在流动只是两端对数据的解释不一致。我用一个生活化的类比X server 画了一幅用“RGB 红绿蓝三个一组”排队的像素画但 x11vnc 在读取时以为屏幕的数据是按“BGR 蓝绿红”排列的于是每个像素的颜色都错位看起来就是锯齿状的花纹。还有一种情况是 stride一行像素占用的内存字节数不匹配比如 X server 每行像素实际占 1984 字节x11vnc 却按 2048 字节去读那么画面上就会出现横向的剪切和偏移看起来像是画面被“打碎”了。除了数据格式错位另一个常见原因是刷新率/像素时钟异常。无显示器时驱动可能把刷新率调到非常规值比如 30Hz 或者 70HzVNC 客户端在重绘时会处理不过来导致画面撕裂、残留、花块。1.3 为什么反复重装桌面是白费劲这是最可惜的一部分。我看到不少人在头条和论坛里求助底下评论清一色在说“重装 UKUI”“用 apt 重装 x11vnc”“升级内核”实际上这些都动不了问题的根基。桌面环境UKUI、GNOME、XFCE是运行在 X server 之上的用户态组件负责画窗口、任务栏、壁纸。x11vnc 本身也只是 X server 的“转播设备”它不会改变 X server 的输出参数。真正决定花屏的是 X server 和 DRM 驱动在无显示器情况下的初始化行为。重装桌面相当于给一座地基歪了的房子重新刷了一遍油漆楼还是歪的。所以正确路线只有一条在无显示器的情况下给 X server 一个确定的、合理的输出配置让驱动不再瞎猜。也就是给系统“虚拟一台显示器”出来。2. 动手前的状态确认与工具准备在改配置前先花十分钟把系统的现状摸清楚。这一步别省很多朋友改完配置反而黑屏就是因为没搞明白自己的机器用的是 X11 还是 Wayland授权路径是什么有没有走 GDM 的自动登录。以下几步在 SSH 终端里操作就行。2.1 确认系统版本和桌面类型先确认麒麟 2403 的具体版本和桌面环境命令如下cat /etc/os-release echo $XDG_CURRENT_DESKTOP echo $XDG_SESSION_TYPE loginctl show-session $(loginctl | grep $(whoami) | awk {print $1}) -p Type注意第三句XDG_SESSION_TYPE是在已登录的图形会话里才有值你如果纯 SSH 进去这个变量可能是空的所以用loginctl来查更准确。麒麟 2403 默认安装的是 UKUI 桌面但你不知道别人之前有没有改装过其他桌面。如果XDG_CURRENT_DESKTOP显示的是GNOME或XFCE后面配置自动登录的时候操作路径会不一样这一步先记录在案。另外要确认当前是 Xorg 会话还是 Wayland。x11vnc 只能镜 X11 的帧缓冲如果系统跑了 Wayland 会话x11vnc 是抓不到画面的这时候你看到的花屏可能并不是输出格式错乱而是 x11vnc 在抓 Wayland 合成器画面时出现的兼容性问题。麒麟 2403 默认登录会话是 Xorg但如果你之前手动切过最好彻底退回到 Xorg 会话再继续。2.2 查看当前 X 会话与显卡驱动状态接着看 X server 是否在跑以及跑在哪个 display 编号ps -ef | grep -E Xorg|Xwayland | grep -v grep如果输出里有一行类似/usr/lib/xorg/Xorg :0 ...说明 X server 已经起来了虚拟显示器配置的好戏就有了操作对象。如果什么都没输出说明图形会话还没启动光靠 x11vnc 是拉不起桌面的你需要先解决自动登录/会话启动问题。再看显卡驱动加载情况lspci -k | grep -A 2 -E VGA|3D|Display lsmod | grep -E i915|amdgpu|nouveau|radeon这一步是为了确定你该往哪个方向补配置。Intel 核显走 i915AMD 走 amdgpuNVIDIA 走 nouveau 或专有驱动不同驱动的虚拟输出能力不一样后面方案 C 能不能用完全依赖这里的结果。2.3 准备一份“后悔药”SSH 兜底通道接下来要改的配置全部涉及 X server 和显示管理器一旦写错可能导致图形服务起不来。虽然不大会影响 SSH但建议你多留一条兜底路以防 SSH 服务本身被误伤。我的习惯是开两个 SSH 会话一个用于改配置另一个始终保持在/root或者家目录下随时准备恢复备份。所有要改的配置文件改之前先cp一份带日期后缀的备份比如sudo cp /etc/X11/xorg.conf.d/10-headless.conf /etc/X11/xorg.conf.d/10-headless.conf.bak-20250101这个习惯救过我很多次比什么回滚工具都好用。另外如果你的机器放在远程机柜最好确认 IPMI 或带外管理口可用万一 X server 配置彻底坏了你还能通过带外控制台把配置改回来。3. 核心解决流程给系统“虚拟一台显示器”现在进入正题。解决无显示器花屏的办法本质上是让 X server 在没有物理显示器的前提下依然认为自己连了一台参数确定的显示器。我按从简单到复杂列了三种方案你按顺序试90% 的情况第一个方案就能解决。3.1 方案 Axorg.conf 虚构显示器推荐优先这是最直接、最稳定的方案。思路是写一个 Xorg 配置文件强制指定一个输出口和一组分辨率参数让驱动在启动时直接按这个配置来不需要 EDID。在麒麟 2403 上Xorg 的配置目录默认是/etc/X11/xorg.conf.d/我们新建一个文件sudo mkdir -p /etc/X11/xorg.conf.d sudo nano /etc/X11/xorg.conf.d/10-headless.conf文件内容如下Section Device Identifier Card0 Driver modesetting Option PrimaryGPU true EndSection Section Monitor Identifier VirtualMonitor Option PreferredMode 1920x1080 Option DPMS false EndSection Section Screen Identifier Screen0 Device Card0 Monitor VirtualMonitor DefaultDepth 24 SubSection Display Depth 24 Modes 1920x1080 EndSubSection EndSection这里几个关键点解释一下Driver modesetting是内核 modesetting 驱动麒麟 2403 默认桌面用的就是这个兼容性最好。如果你的机器是 NVIDIA 独显装了专有驱动这里改成nvidia但参数会有些不同后面单独说。PreferredMode 1920x1080是告诉 X server虽然没有 EDID但是请按 1920x1080 这个分辨率来。你可以根据实际需求改成 2560x1440 或者 1280x720。DefaultDepth 24是颜色深度x11vnc 在 24 位深下的表现最稳定16 位深有时会出现色阶断裂看起来也像花屏的一部分。DPMS false是禁止显示器节能管理无头环境下 DPMS 有时会导致 X server 进入奇怪的休眠状态。写完保存后重启图形服务sudo systemctl restart gdm # 如果你用的是 GDM sudo systemctl restart lightdm # 如果你用的是 LightDM麒麟 2403 桌面版默认用的是 LightDM跟 Ubuntu 默认 GDM 不太一样这个细节要注意。重启完图形服务后再确认 X server 是否按你的配置启动了xdpyinfo -display :0 | grep dimensions xrandr --display :0 --verbose | grep -- --如果第一句输出1920x1080 pixels第二句列出的输出模式里带1920x1080说明 X server 已经接受了虚拟显示器配置。这时候再启动 x11vnc花屏问题基本就消失了。3.2 方案 Bxrandr 动态添加 Modeline不用重启如果你不想重启图形服务或者你是在已经开机的现场排查问题不想打断正在运行的服务可以用 xrandr 临时把虚拟输出加上去。这个方案适合应急缺点是重启后需要重新执行需要配合开机自启脚本。先看当前有哪些输出接口xrandr --display :0输出里通常会有eDP-1、HDMI-1、DP-1、VGA-1之类的名称分别代表不同的物理输出。无显示器时这些口的 status 会是disconnected但 X server 依然会保留它们。用 cvt 生成一个标准的 VESA CVT 分辨率 1920x1080 的 modelinecvt 1920 1080 60输出类似Modeline 1920x1080_60.00 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync vsync然后把这个 mode 添加进去再绑定到输出口xrandr --newmode 1920x1080_60.00 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync vsync xrandr --addmode HDMI-1 1920x1080_60.00 xrandr --output HDMI-1 --mode 1920x1080_60.00 --pos 0 0 --primary注意把HDMI-1换成你机器实际存在的输出口名称如果只有一个 eDP内置笔记本屏接口也可以绑到eDP-1上。绑定成功后xrandr --display :0会看到那个口变成了 connected 状态。接着启动 x11vnc 试试画面应该就正常了。这个方法的问题在于如果 X server 在启动时没有为对应输出口分配帧缓冲xrandr 可能报cannot add mode之类的错误。这种情况说明你的 X server 本身就处于无头异常态还是回到方案 A 更靠谱。3.3 方案 C内核级虚拟输出DRM/KMS 层面兜底如果你想彻底一点在系统还没进入用户态之前就让内核以为有显示器存在可以通过 GRUB 启动参数来指定输出模式和虚拟连接。这个方法对 Intel 核显最有效因为 i915 驱动自带虚拟显示功能。编辑 GRUB 配置sudo nano /etc/default/grub找到GRUB_CMDLINE_LINUX一行在引号里加上videoeDP-1:1920x108060或者强制让某个输出口处于 connected 状态videoHDMI-A-1:d videoHDMI-A-1:1920x108060第一个参数的含义是把 HDMI-A-1 强制设为 connectedd detect第二个是同时指定分辨率和刷新率。这个方案在内核阶段就建立了虚拟显示链路X server 起来后看到的输出状态就是正常的解决得最彻底适合设备长期固定作为无头服务器使用的场景。改完执行sudo update-grub sudo reboot重启后查看/var/log/Xorg.0.log你会看到内核驱动在初始化时直接找到了显示器参数不再是(EE) No EDID之类的报错。需要注意GRUB 参数的具体写法跟内核版本和显卡驱动有关video参数对 AMDGPU 和 NVIDIA 的兼容性不如 i915 那么完美。如果你用的不是 Intel 核显优先考虑方案 A。4. x11vnc 参数调优与开机自启虚拟显示器配好以后x11vnc 花屏的问题就等于解决了大半但如果你直接用最朴素的命令启动过不了多久还会碰到卡顿、颜色偏色、断线重连失败等问题。这一节我把 x11vnc 在生产环境里最实用的参数组合和自启配置一次讲清楚。4.1 常用关键参数逐个讲解很多人启动 x11vnc 只写一句x11vnc -forever -shared -display :0这在有显示器的场景下可能够用但在无显示器虚拟输出的场景下你至少还要关注以下几个参数。-noxdamage最重要。X server 的 Damage 扩展是用来告诉客户端“画面上哪些区域变了”的机制x11vnc 默认开启它来优化性能。但在虚拟显示器环境下Damage 事件可能因为输出参数异常而频繁触发导致画面一直被重画表现就是闪烁、花屏、CPU 占用飙高。加上-noxdamage让 x11vnc 直接走全屏轮询反而更稳定。-ncache是另一个能解决“半块屏幕是残影”问题的参数。它开启客户端的缓存机制VNC 协议在没有 ncache 时一旦画面变化区域覆盖整个屏幕就要重传整张画面带宽不够时就会出现撕裂。加了-ncache 10之后客户端会缓存一份屏幕副本重绘时只传差异区域效果立竿见影。代价是客户端窗口会稍微大一圈因为缓存区域挤占了显示空间在 RealVNC 里可以在连接时把适应窗口比例调出来。-geometry参数可以限制输出画面的尺寸。比如服务器端实际是 3840x2160 的分辨率但 VNC 客户端屏幕只有 1366x768这时候如果不做缩放VNC 客户端看到的只是一块超大的画布移动鼠标要滚轮。用x11vnc -geometry 1920x1080会让 x11vnc 在服务器端直接按 1920x1080 的帧缓冲来做转播分辨率低的客户端看着也舒服。不过有一点要提醒-geometry不是随便能用的它需要 framebuffer 支持缩放如果你用的是虚拟输出部分驱动并不支持动态缩放强行加可能直接报错。所以我通常的做法是让 X server 侧分辨率在方案 A 里就设成一个适中的值比如 1920x1080x11vnc 不缩放客户端用缩放来适应。-auth参数是新手最容易踩的坑。如果你不是以 root 身份启动 x11vnc它需要读取当前登录用户的 Xauthority 文件才能访问 X server。有显示器环境下桌面环境通常会生成一个~/.Xauthority但在无头自动登录的场景下Xauthority 文件可能不在默认位置。启动报错如果出现XOpenDisplay(:0) failed基本就是授权问题。正确做法是先从登录会话里取到授权文件路径ps -ef | grep Xorg看 Xorg 进程启动参数里带的-auth选项后面的路径然后显式传给 x11vncx11vnc -auth /var/run/lightdm/root/:0 -display :0麒麟 2403 的 LightDM 默认授权文件路径通常是/var/run/lightdm/root/:0不同版本可能有差异以你机器上 Xorg 进程的实际参数为准。更安全的做法是把 x11vnc 服务放在 systemd 里跑配好 User 和 Environment 变量让它能拿到正确的 XAUTHORITY。4.2 编写 systemd 服务托管 x11vnc要保证重启后 x11vnc 自动生效别用rc.local了直接用 systemd 服务最干净。在/etc/systemd/system/x11vnc.service写入[Unit] Descriptionx11vnc remote desktop server Afterdisplay-manager.service network.target Wantsdisplay-manager.service [Service] Typesimple ExecStart/usr/bin/x11vnc -display :0 -auth /var/run/lightdm/root/:0 -forever -shared -noxdamage -ncache 10 -rfbport 5900 -rfbauth /etc/x11vnc.pass Restarton-failure RestartSec3 [Install] WantedBymulti-user.target生成访问密码文件sudo x11vnc -storepasswd your_password /etc/x11vnc.pass sudo chmod 644 /etc/x11vnc.pass这里的权限要留意有些教程写chmod 600但 x11vnc 如果没有以 root 启动就会因为权限不足读不了文件。如果你在 ExecStart 里没加User服务默认以 root 跑644没问题。你也可以加上User你的用户名把密码文件chown给那个用户。启动并设置开机自启sudo systemctl daemon-reload sudo systemctl enable --now x11vnc sudo systemctl status x11vncstatus 输出里看到Main process exited的话用journalctl -u x11vnc -f看实时日志定位很快。4.3 开机自启 X 会话的完整链路x11vnc 只是一个转播层它依赖上层有已登录的图形会话。所以无头场景下你还得确保系统开机后有自动登录的 X 会话。麒麟 2403 的 LightDM 配置在/etc/lightdm/lightdm.conf需要在[Seat:*]段里启用自动登录[Seat:*] autologin-user你的用户名 autologin-user-timeout0 user-sessionukui如果你用 GDM部分麒麟服务器版可能会装 GDM自定义配置放在/etc/gdm3/custom.conf[daemon] AutomaticLoginEnabletrue AutomaticLogin你的用户名这里有个细节自动登录的用户名不要用 root。麒麟的图形会话默认禁止 root 登录就算你改了几条配置让它能进桌面x11vnc 抓 root 会话的授权文件也会很折腾不值得。配置好自动登录后重启机器验证一次完整链路机器没有接显示器 → LightDM 自动登录 → Xorg 启动虚拟显示器 → x11vnc 自动运行 → VNC 客户端连上看到桌面。任何一环断了就按 5.2 节的思路去查日志。5. 常见问题与排查技巧实录把花屏问题解决之后我顺手整理了一些在无显示器 VNC 场景下的高频问题。这些坑有的是我自己踩的有的是帮朋友排查时发现的集中写出来算是一份速查表。5.1 花屏形态分类速查花屏和花屏还不一样不同的形态背后是不同的原因。学会区分排查时间至少缩短一半。横向彩色条纹画面像被拆成一条条彩带通常就是像素格式/stride 不匹配优先走方案 A 重新指定分辨率和色深。画面有完整桌面背景但鼠标拖尾严重或者拖动窗口时留下大片残影更像 VNC 客户端缓存和重绘机制的问题检查是否加了-ncache参数客户端建议把“自动调整画质”关掉。画面上下两半颜色一个正常一个偏色大概率是颜色深度不一致。X server 侧是 24 位深但 x11vnc 启动时误判成了 16 位在启动命令里显式加-depth 24试试。还有一种情况是 VNC 连接后整个屏幕是暗绿色的怎么点都不同这个不是花屏而是编码格式兼容性问题。x11vnc 默认用的是 Tight 编码部分老客户端解析不好在客户端设置里强制切换成 Raw 或者 Hextile 编码即可。5.2 排查三板斧日志、日志、还是日志遇到问题先别急着改配置先看三份日志。第一份是 X server 日志/var/log/Xorg.0.log。重点搜索(EE)和(WW)标记grep -E (EE)|(WW) /var/log/Xorg.0.log如果看到No EDID或者No monitor的字样说明虚拟显示器配置没有生效回到方案 A 检查 xorg.conf 有没有被正确加载。第二份是系统日志journalctl -b --no-pager | grep -iE x11vnc|drm|gpu这一步能看到内核 DRM 驱动加载时有没有报错以及 x11vnc 服务有没有被正确拉起。第三份是 x11vnc 自己的日志sudo journalctl -u x11vnc -f如果启动时 x11vnc 报XOpenDisplay failed把这个错误严格按照“授权文件路径 → display 编号 → X server 状态”的顺序去查90% 的问题出在授权文件路径上。5.3 三个容易忽略的坑第一个坑是权限。有时候 x11vnc 能启动但连上去操作时键盘/鼠标无响应这和 VNC 无关而是 X server 的输入设备配置问题。无显示器环境下某些驱动不会自动挂载虚拟化的 evdev 设备导致指针和键盘事件无法注入。这时你需要在 Xorg 配置里显式启用 libinput 设备的自动添加或者在启动 X server 前确保内核有usbhid、evdev模块被加载。第二个坑是显示器休眠导致的“二次花屏”。系统启动时配置正常VNC 连上也正常但跑一会儿后屏幕自动休眠了因为长时间没有物理显示器输入再唤醒时就花了。解决方法是把 xorg.conf 里的 DPMS 禁用掉也就是我方案 A 里写的那句Option DPMS false。另外还可以在 X 会话里执行xset s off -dpms彻底关闭屏保和休眠。第三个坑是 x11vnc 的-scale参数。很多教程会让你用-scale 1/2之类来降低带宽但在虚拟输出场景下缩放后的画面经常出现文字模糊和线条断裂看起来像低码率花屏。建议不用-scale而是在服务端把分辨率直接调高客户端再自己缩放窗口。5.4 快速验证清单最后给你一个我在无头部署时反复使用的验证清单照着走一遍基本不会漏。检查项命令/操作预期结果X server 在运行ps -ef | grep Xorg有 Xorg 进程虚拟分辨率正确xrandr --display :0 | grep HW显示你在配置里写定的分辨率x11vnc 服务状态systemctl status x11vncactive (running)VNC 端口监听ss -tlnp | grep 59005900 端口 LISTEN客户端连接随便一个 VNC Viewer桌面画面正常无花无闪屏幕不会休眠xset -display :0 q | grep DPMSDPMS is Disabled这个清单我每次都贴在笔记里因为排查无头问题很容易陷入“这里改一下那里试一下”的循环浪费时间。按清单逐项过关思路清晰得多。写在最后的一点经验我在实际处置这类问题时发现很多人都卡在“以为是 x11vnc 的问题”这个点上。x11vnc 只是一个很单纯的“画面转发器”它的工作界面是 X server 已经渲染好的帧缓冲前端的花朵再漂亮也没用后院的地基歪了什么都白搭。所以建议各位在动手前先把思路从“这个工具不行”切换成“这个环境没有给它提供正常的地基”折腾方向对了问题往往比你想象中简单。另外这套配置方案不仅适用于麒麟 2403基本上所有基于 Debian 系 Xorg 的发行版都通用Ubuntu、Debian、其他 Linux 桌面版只要把配置路径稍作调整就能跑。最后再分享一个小技巧方案 A 里的 xorg.conf如果你不确定自己的显卡驱动应该写modesetting还是别的名字先跑一句sudo Xorg -configure它会自动生成一份基于当前硬件的配置文件你把里面的 Driver 字段抄过来用就行了比自己猜靠谱得多。
返回列表