出自 Arch Linux 中文维基

Tango-view-fullscreen.png這篇文章的某些內容需要擴充。Tango-view-fullscreen.png

原因: 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

例如對 Intel 顯卡,將 i915 模塊加入到 /etc/mkinitcpio.confMODULES行:

MODULES=(i915)
注意: 順序很重要,因為模塊是按順序加載的.
注意: 有些用戶也許需要在 i915 之前添加intel_agp 用來阻止 ACPI 錯誤。(檢查運行系統中lsmod的輸出,看看intel_agp是否加載)。這對於從休眠狀態恢復到改變後的顯示配置可能是必要的。如果你使用PRIME GPU,英特爾IGP是你的主GPU,AMD是獨立GPU,添加intel_agp可能會導致從休眠狀態恢復時出現問題(顯示器沒有信號)。詳見[2]

如果您使用的是自定義的 EDID 文件,你應該也把它添加到initramfs中:

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

最後,重新生成內核鏡像(詳情參閱 mkinitcpio)。

問題解決

字體太小

Linux console#Fonts介紹了如何在終端中使用大字體。軟體倉庫中的 (terminus-font) 字體提供了很多字號,比如更大一些的 ter-132n。 或者,可以#禁用 KMS 以切換為更低的解析度,使得字體外觀顯得更大一些。

啟動錯誤信息

在比較老的系統上輪詢已連接的顯示設備的開銷很大。在不同的硬體上甚至可能每幾百毫秒就輪詢一次。這會導致在視頻播放等場景中可見的顯示延遲,即使視頻具有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_kms_helper.edid_firmware=edid/your_edid.bin

或者(從內核版本 4.15 開始),您也可以通過下列方式在底層強制EDID信息:

drm.edid_firmware=edid/your_edid.bin

如果您希望僅將其應用於特定的連接器:

drm_kms_helper.edid_firmware=VGA-1:edid/your_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

警告: The method described below is somehow incomplete because 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.

From the nouveau wiki:

A mode can be forced on the kernel command line. Unfortunately, the command line option video is poorly documented in the DRM case. Bits and pieces on how to use it can be found in

The format is:

video=<conn>:<xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
  • <conn>: Connector, e.g. DVI-I-1, see /sys/class/drm/ for available connectors
  • <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)

You can override the modes of several outputs using video= several times, for instance, to force DVI to 1024x768 at 85 Hz and TV-out off:

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

To get the name and current status of connectors, you can use the following shell oneliner:

$ 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

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 才能工作,參閱所用驅動的頁面。