内核模式设置

出自 ArchWiki
(重定向自 KMS

此条目或章节需要扩充。

原因: KMS 和无根 X (1.16),参见 Talk:Kernel mode settingXorg#Rootless Xorg。(在 Talk:Kernel mode setting 中讨论)

内核模式设置 (KMS) 是一种在内核空间而不是用户空间中设置显示分辨率和深度的方法。

Linux 内核对 KMS 的实现使得在帧缓冲区中实现原生分辨率,并允许即时控制台 (tty) 切换。KMS 还支持更新的技术(例如 DRI2),这将有助于减少伪影并提高 3D 性能,甚至内核空间节能。

注意: 专有 NVIDIA 驱动程序(自 364.12 版本起)也实现了内核模式设置,但它不使用内置的内核实现,并且用于高分辨率控制台的 fbdev 驱动程序仅作为可选的实验性功能存在(自 545.29 版本起)

背景

以前,设置显卡是 X 服务器的工作。因此,在虚拟控制台中不容易拥有精美的图形。此外,每次从 X 切换到虚拟控制台 (Ctrl+Alt+F2) 时,服务器都必须将显卡的控制权交给内核,这很慢并且会导致闪烁。当控制权交还给 X 服务器(当 X 在 VT7 中运行时按 Alt+F7)时,也会发生同样“痛苦”的过程。

通过内核模式设置 (KMS),内核现在能够设置显卡的模式。这使得启动、虚拟控制台和 X 快速切换期间的精美图形成为可能,以及其他功能。

配置

首先,请注意,对于您使用的任何方法,您都应始终禁用

  • 启动加载程序中的任何 vga= 选项,因为这些选项会与 KMS 启用的原生分辨率冲突。
  • 任何启用与驱动程序冲突的帧缓冲区的 video= 行。
  • 任何其他帧缓冲区驱动程序(例如 uvesafb)。

此条目或章节已过时。

原因: Arch 官方支持的内核 多年来都内置了 simpledrm KMS 驱动程序 [1]。这意味着 Arch 用户始终具有早期 KMS 启动。因此,本节更多是关于“simpledrm 何时将控制权移交给另一个驱动程序”。(在 Talk:Kernel mode setting 中讨论)

此条目或章节需要扩充。

原因: 提及 simpledrm 及其作为通用图形驱动程序的能力。(在 Talk:Kernel mode setting 中讨论)

后期 KMS 启动

IntelNouveauATIAMDGPU 驱动程序已经为所有芯片组自动启用 KMS,因此您无需执行任何操作。

专有 NVIDIA 驱动程序支持 KMS(自 364.12 版本起),必须手动启用

早期 KMS 启动

提示: 如果您遇到分辨率问题,您可以检查强制模式是否有帮助。

KMS 通常在 initramfs 阶段之后初始化。但是,可以在 initramfs 阶段启用 KMS。将 显卡驱动程序所需的模块添加到 initramfs 配置文件

  • mgag200 用于 Matrox 显卡。
  • 取决于使用的 QEMU 显卡(qemu 选项 -vga typelibvirt <video><model type='type'>[2]
    • bochs 用于 std (qemu) 和 vga/bochs (libvirt),
    • virtio-gpu 用于 virtio,
    • qxl 用于 qxl,
    • vmwgfx 用于 vmware (qemu) 和 vmvga (libvirt),
    • cirrus 用于 cirrus
  • 取决于 VirtualBox 图形控制器
    • vmwgfx 用于 VMSVGA,
    • vboxvideo 用于 VBoxVGA 或 VBoxSVGA。

Initramfs 配置说明根据您使用的 initramfs 生成器略有不同。

mkinitcpio

对于树内模块,请确保 kms 包含在 /etc/mkinitcpio.conf 中的 HOOKS 数组中(自 mkinitcpio v33 起,这是默认设置)。

对于树外模块,请将模块名称放在 MODULES 数组中。例如,为 NVIDIA 显卡驱动程序启用早期 KMS

/etc/mkinitcpio.conf
MODULES=(... nvidia nvidia_modeset nvidia_uvm nvidia_drm ...)
注意: 如果您使用 PRIME 图形处理器 (GPU),其中 Intel 集成图形处理器 (IGP) 是您的主 GPU,而 AMD 是独立 GPU,则从休眠状态恢复时 intel_agp 可能会导致问题(显示器没有信号)。有关详细信息,请参阅 [3]

如果您使用#强制模式和 EDID 方法,您还应该将自定义文件嵌入到 initramfs

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

然后重新生成 initramfs

Booster

如果您使用 Booster,您可以使用此配置更改加载所需的模块

/etc/booster.yaml
modules_force_load: i915

如果您使用#强制模式和 EDID 方法,您还应该将自定义文件嵌入到您的 booster 镜像中

/etc/booster.yaml
extra_files: /usr/lib/firmware/edid/your_edid.bin

然后重新生成 booster 镜像。

故障排除

我的字体太小

有关如何将控制台字体更改为大字体,请参阅Linux 控制台#字体。Terminus 字体 (terminus-font) 有多种尺寸可供选择,例如更大的 ter-132b

或者,禁用模式设置可能会切换到较低分辨率,并使字体显得更大。

强制模式和 EDID

如果您的原生分辨率未自动配置或未检测到任何显示器,则您的显示器可能发送了无 EDID 文件或仅发送了倾斜的 EDID 文件。内核将尝试捕获这种情况,并将设置最典型的分辨率之一。

如果您有显示器的 EDID 文件,您只需显式强制执行它即可(见下文)。但是,通常情况下,人们无法直接访问正常的 EDID 文件,因此有必要提取现有的文件并修复它,或者生成一个新的文件。

在内核编译期间,可以通过遵循上游文档(另请参见 此处的简短指南)为各种分辨率和配置生成新的 EDID 二进制文件。本文章详细介绍了其他解决方案。提取现有的 EDID 通常更容易,例如,如果您的显示器在 Windows 下运行良好,您可能有幸从相应的驱动程序中提取 EDID,或者如果类似的具有相同设置的显示器工作正常,您可以使用 get-edid(1),来自 read-edid 软件包。您也可以尝试在 /sys/class/drm/*/edid 中查找。

准备好 EDID 后,将其放置在目录中,例如在 /usr/lib/firmware/ 下名为 edid 的目录中,并将您的二进制文件复制到其中。

要在启动时加载它,请在内核命令行中指定以下内容

drm.edid_firmware=edid/your_edid.bin

为了仅将其应用于特定连接器,请使用

drm.edid_firmware=VGA-1:edid/your_edid.bin

如果要设置多个 edid 文件,请使用

drm.edid_firmware=VGA-1:edid/your_edid.bin,VGA-2:edid/your_other_edid.bin

如果您正在进行早期 KMS,则必须将自定义 EDID 文件包含在 initramfs 中,否则您将遇到问题。

drm.edid_firmware 参数的值也可以在启动后通过写入 /sys/module/drm/parameters/edid_firmware 来更改

# echo edid/your_edid.bin > /sys/module/drm/parameters/edid_firmware

这仅对新插入的显示器生效,已经插入的屏幕将继续使用其现有的 EDID 设置。对于外部显示器,重新插入它们就足以看到效果。

要在启动后加载 EDID,如果内核未处于锁定模式,您可以使用 debugfs 而不是内核命令行参数。如果您在连接器上交换显示器或只是为了测试,这非常有用。一旦您有了如上的 EDID 文件,请运行

# cat correct-edid.bin > /sys/kernel/debug/dri/0/HDMI-A-2/edid_override

并禁用

# echo -n reset > /sys/kernel/debug/dri/0/HDMI-A-2/edid_override

如果您的显示器支持热插拔,您还可以触发热插拔以使显示器使用您刚刚加载的新 EDID(例如,加载到 edid_override 中),这样您就不必物理重新插入显示器或重新启动

# echo 1 > /sys/kernel/debug/dri/0/HDMI-A-2/trigger_hotplug

强制模式

警告: 下面描述的方法在某种程度上是不完整的,例如 Xorg 不会考虑指定的分辨率,因此建议用户使用上面描述的方法。但是,在某些情况下,使用 video= 命令行指定分辨率可能很有用。

来自 nouveau wiki

可以在内核命令行上强制模式。不幸的是,命令行选项 video 在 DRM 情况下文档记录不佳。有关如何使用它的零星信息可以在以下位置找到

格式是

video=<driver>:<conn>:<xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
  • <driver>: 在启动时指定视频模式。
  • <conn>: 指定视频连接类型,例如 VGA、DVI、HDMI 等,请参阅 /sys/class/drm/ 以获取可用连接器
  • <xres>: 水平分辨率(以像素为单位)。
  • <yres>: 垂直分辨率(以像素为单位)。
  • [M]: 启用 VESA 协调视频定时 (CVT) 以计算视频模式定时,而不是从数据库中查找模式
  • [R]: 在使用 CVT 时,为数字显示器启用减少消隐计算。这减少了水平和垂直消隐间隔以节省带宽。
  • [-<bpp>]: 指定颜色深度或每像素位数(例如,-24 表示 24 位颜色)。
  • [@<refresh>]: 指定刷新率(以 Hz 为单位)。
  • [i]: 启用隔行扫描模式。
  • [m]: 将边距添加到 CVT 计算(xres 的 1.8% 向下舍入为 8 像素,以及 yres 的 1.8%)
  • [e]: 强制输出为开启
  • [D]: 强制数字输出为开启(例如 DVI-I 连接器)
  • [d]: 强制输出为关闭

您可以多次使用 video= 来覆盖多个输出的模式,例如,强制 DVI1024x76885 Hz,并关闭 TV-out

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

要获取连接器的名称和当前状态,您可以使用以下 shell 单行命令

$ 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,请添加 nomodeset 作为内核参数。有关更多信息,请参阅内核参数

除了 nomodeset 内核参数外,对于 Intel 显卡,您需要添加 i915.modeset=0,对于 Nvidia 显卡,您需要添加 nouveau.modeset=0。对于 Nvidia Optimus 双显卡系统,您需要添加所有三个内核参数(即 "nomodeset i915.modeset=0 nouveau.modeset=0")。

注意: 某些 Xorg 驱动程序在禁用 KMS 的情况下将无法工作。有关详细信息,请参阅有关您的特定驱动程序的 wiki 页面。