内核级显示模式设置

来自 Arch Linux 中文维基
(重定向自Kernel mode setting

这篇文章的某些内容需要扩充。

原因: KMS 和非 root X (1.16), 见 Talk:Kernel mode settingXorg#Rootless Xorg. (在 Talk:内核级显示模式设置 中讨论)

内核级显示模式设置 (KMS) ,作用是可以在内核级别而不是最终用户级别切换显示分辨率和颜色深度。

Linux 内核的 KMS 实现支持在 framebuffer 中使用原生分辨率和即时终端(tty)切换。KMS 使用了更新的技术(例如 DRI2),可以减少失真、增强3D性能,甚至使用内核空间节能功能。

注意: NVIDIA 闭源驱动从 364.12 开始也实现了 KMS,但是没有利用 linux 内核的实现,缺少高分辨率终端的 fbdev 驱动。

背景[编辑 | 编辑源代码]

以前,设定显卡是 X 服务器的工作。所以虚拟终端不可能提供漂亮的图像效果。同时,每次使用Ctrl+Alt+F1~7从X切换到虚拟终端时,x服务器必须将显卡的控制权交给内核,这个流程显得低效并且会导致闪烁。将控制权切回到X服务器同样是一个“痛苦”的过程。

使用内核模式设置后,内核可以设定显卡的模式。这样开机启动即可看到漂亮的显示画面,在 X 图形界面 和 终端 之间也可以快速切换,还有其他的一些优点。

安装[编辑 | 编辑源代码]

不管使用什么方法,都需要先“禁用”下列项:

  • 所有启动加载器中的 "vga=" 选项,这个选项与 KMS 的原生分辨率设置冲突。
  • 所有 "video=" 选项,这个选项会启动帧缓冲,导致驱动冲突。
  • 所有帧缓冲驱动(例如 uvesafb)。

KMS 晚启动[编辑 | 编辑源代码]

Intel, Nouveau, ATIAMDGPU 驱动已经为所有芯片组提供了 KMS 支持。这些驱动也会自动启用 KMS。

闭源的 NVIDIA 驱动从 364.12 开始支持 KMS,但是需要 手动启用

KMS 早启动[编辑 | 编辑源代码]

提示:如果你有分辨率方面的问题,可以参考一下 强设模式 ,也许会有帮助。

KMS通常是在initramfs stage之后开始初始化,但是你也可以在initramfs的阶段启用KMS:

视频驱动模块加入/etc/mkinitcpio.conf的 MODULES 行。

  • AMDGPU 驱动加入 amdgpu; 老的 ATI 驱动加入 radeon
  • Intel 卡加入i915
  • 开源的 Nouveau 驱动加入nouveau
  • Matrox 卡加入 mgag200.


  • Matrox 显卡加入 mgag200
  • QEMU 显卡使用(qemu 选项 {{ic|-vga type)或 libvirt <video><model type='type'>[1]):
    • bochsstd (qemu) 和 vga/bochs (libvirt),
    • virtio-gpuvirtio,
    • qxlqxl,
    • vmwgfxvmware (qemu) and vmvga (libvirt),
    • cirruscirrus.
    • vmwgfx 予 VMSVGA,
    • vboxvideo 予 VBoxVGA or VBoxSVGA.

mkinitcpio[编辑 | 编辑源代码]

使用树内模块时,将 kms 加入到 /etc/mkinitcpio.conf 的 HOOKS 数组中。

对于树外模块,将模块的名字加入到 MODULES 数组中。例如,启动 NVIDIA 图形驱动的早启动 KMS 功能时:

/etc/mkinitcpio.conf
MODULES=(... nvidia nvidia_modeset nvidia_uvm nvidia_drm ...)
注意: 如果你使用 PRIME GPU,并且主要的 GPU 是英特尔核显,而 AMD 显卡是独立显卡。intel_agp 可能会在从显示器无信号状态恢复时造成麻烦。详见 [2]

如果你在使用 #强制设置显示模式与 EDID 的方法,则也需要将选定的文件集成到 initramfs 去:

/etc/mkinitcpio.conf
FILES=(/usr/lib/firmware/edid/your_edid.bin)

完成这一切后,重新生成 initramfs

Booster[编辑 | 编辑源代码]

设若阁下使用 Booster,阁下可通过以下的方式改变设置来加载需要的模块。

/etc/booster.yaml
modules_force_load: i915

如果你在使用 #强制设置显示模式与 EDID 的方法,则也需要将选定的文件集成到 initramfs 去:

/etc/mkinitcpio.conf
FILES=(/usr/lib/firmware/edid/your_edid.bin)

之后, 重新生成 一份 Booster 镜像。

问题解决[编辑 | 编辑源代码]

字体太小[编辑 | 编辑源代码]

Linux console#Fonts介绍了如何在终端中使用大字体。软件仓库中的 (terminus-font) 字体提供了很多字号,比如更大一些的 ter-132n。 或者,可以#禁用 KMS 以切换为更低的分辨率,使得字体外观显得更大一些。

启动错误信息[编辑 | 编辑源代码]

{{Out of date|这一节在 2011、[[Special:Diff/233813|2012] 的时候创建。十年过去了,它仍然和这个问题相关么?}}

在比较老的系统上轮询已连接的显示设备的开销很大。在不同的硬件上甚至可能每几百毫秒就轮询一次。这会导致在视频播放等场景中可见的显示延迟,即使视频具有HDP输出,若硬件设置为其他非HDP输出仍会出现延迟。如果每10秒延迟一次,则应禁用轮询。

如果启动时看到 0x00000010 (2) 错误码,(应该有 10 行文字,最后一行是错误码),请使用

/etc/modprobe.d/modprobe.conf
options drm_kms_helper poll=0

强制设置显示模式与 EDID[编辑 | 编辑源代码]

如果无法自动配置您本机的分辨率,或者根本无法侦测到显示器;您的显示器很有可能没有或发送了破损的 EDID 文件。内核将尝试捕获这种情况并设置为某一通用分辨率。

如果您拥有贵显示器的 EDID 文件,您只需明确地强制设置即可(详见下文)。但是,您在大多数情况下可能无法直接取得一个健全的 EDID 文件。您可能需要提取现有 EDID 文件中的信息并试图修复它,从而获得了一个新的 EDID 文件。

在内核编译期间,可以通过遵循 上游文档 来生成用於各种分辨率和配置的新EDID二进製文件(另请参见 此处 的简短指南)。 这篇文章 也详细概述了其他解决方案。在大多数情况下,提取现有文件比较容易。例如从Windows下的驱动程序中提取EDID,如果您的显示器在那里运行良好。或者您可以使用来自 read-edid 包的 get-edid 命令,从具有相同设置的类似显示器中提取。可以从 /sys/class/drm/*/edid 中查找一下。

在您的EDID准备就绪后,请将它放置于特定的文件夹。例如一个在 /usr/lib/firmware 下名为 edid 的文件夹,您可以将您的二进制文件放入其中。

请在内核参数中设置下述参数来在启动时加载:

drm.edid_firmware=edid/你的edid.bin

4.13 版本前的内核使用下述参数:

drm_kms_helper.edid_firmware=edid/你的edid.bin

用下述参数来设定特定的连接器:

drm.edid_firmware=VGA-1:edid/你的edid.bin

如果你希望设置多个 edid 文件,用下面的参数:

drm.edid_firmware=VGA-1:edid/你的edid.bin,VGA-2:edid/你的另一个edid.bin

您可以从下表找到内置的分辨率。名称列指定了为了强制使用该分辨率而应该使用的名称。

分辨率 名称
800x600 edid/800x600.bin
1024x768 edid/1024x768.bin
1280x1024 edid/1280x1024.bin
1600x1200 (kernel 3.10 or higher) edid/1600x1200.bin
1680x1050 edid/1680x1050.bin
1920x1080 edid/1920x1080.bin

如果您要进行KMS早启动,则必须在initramfs中包含自定义EDID文件,否则可能会遇到问题。

Forcing modes[编辑 | 编辑源代码]

警告: 下面描述的方法并不完整,e.g. Xorg does not take into account the resolution specified, so users are encouraged to use the method described above; however, specifying resolution with video= command line may be useful in some scenarios

来自 nouveau wiki:

用内核命令行可以强制设置使用的模式。但是 DRM 内核选项的文档很少,使用的方法位于:

格式:

video=<conn>:<xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
  • <conn>: Connector, e.g. DVI-I-1, 查看 /sys/class/drm/ .
  • <xres> x <yres>: resolution
  • M: compute a CVT mode?
  • R: reduced blanking?
  • -<bpp>: color depth
  • @<refresh>: refresh rate
  • i: interlaced (non-CVT mode)
  • m: margins?
  • e: output forced to on
  • d: output forced to off
  • D: digital output forced to on (e.g. DVI-I connector)

可以使用多个 "video" 设置不同输出的分辨率,例如要强制 DVI 使用 1024x768 85 Hz ,同时禁用 TV-out :

video=DVI-I-1:1024x768@85 video=TV-1:d

要获取当前连接器的状态,使用下面命令:

$ for p in /sys/class/drm/*/status; do con=${p%/status}; echo -n "${con#*/card?-}: "; cat $p; done
                                                                                         
DVI-I-1: connected
HDMI-A-1: disconnected
VGA-1: disconnected

禁用 KMS[编辑 | 编辑源代码]

有时需要禁用 KMS,例如使用 catalyst 驱动时. 只需在内核参数中加入 nomodeset 即可,设置方法请阅读内核参数页面。

使用 nomodeset 内核参数的同时,Intel 卡需要添加 i915.modeset=0, Nvidia 卡需要添加 nouveau.modeset=0. Nvidia Optimus 双显卡系统,需要添加三个内核参数:

"nomodeset i915.modeset=0 nouveau.modeset=0"
注意: 有些 Xorg 驱动必须启用 KMS 才能工作,参阅所用驱动的页面。