同型號共用總出問題,顯示器的「身份證」為什麼沒用了?

語言: CN / TW / HK

8 月末, macOS 外接顯示器自動亮度工具 Lunar 的開發者 Alin Panaitiu 在自己的一篇 部落格 中提到了這樣一個現象:

You know how people get two identical monitors and place them side by side for a neat ultrawide-like look.

Well a lot of those people experience a very annoying behavior: After standby or restart, the monitors get swapped by the OS, so moving the cursor to the left monitor will actually appear on the right monitor, and vice-versa.

If the monitors also had some of the settings different, like resolution or color profile, those also get swapped.

簡而言之,在電腦上連線了兩塊同型號的顯示器之後,一旦顯示器進入待機或重啟,兩塊顯示器上面的內容就有概率會被互換(比如分割好的桌布),與之相伴的還有一些在解析度、色彩檔案上有差別的設定也會一併發生對調——儘管你並沒有調整任何東西。

圖|Alin Panaitiu

發生類似問題的原因,便出在顯示器傳輸給電腦的識別資訊中。

在人類使用者之外,那個矽基的世界裡,你的顯示器是怎樣與你的輸出裝置交流、讓它輸出適當的顯示內容的呢?這答案便是 EDID ——擴充套件顯示器標識資料(Extended Display Identification Data)。

EDID 的功能

與我們手動連線顯示器,螢幕畫面「啪就轉過去了,很快啊」的觀感不同,畫面資料的傳輸是需要經過畫面的源端(Host Device,比如顯示卡、機頂盒)與終端(Display Device,比如顯示器、電視、投影儀)進行一次握手和資料交換,由終端裝置主動將自己支援的解析度、重新整理率、色域、Gamma 值等等資訊告知源端,從而避免輸出裝置為了保持最大相容性而僅僅輸出最低規格的畫面或者遍歷所有支援的格式,導致浪費效能或浪費時間。

EDID 工作方式的本質:吆喝

這些由畫面接收端主動通報給輸出端的資料,就是這臺顯示裝置的 EDID ,由顯示資料通道(Display Data Channel, DDC)負責傳輸——所以有時也會被不太規範的稱為 DDC 資料。因此,顯示裝置的 EDID 負責解決的,就是展示這臺顯示器「我是誰,我能做什麼,我能怎麼做」的「靈魂三問」的答案。

作為一項上世紀九十年代被 VESA 協會(Video Electronics Standards Association,視訊電子標準協會)提出的標準資料格式, EDID 的應用範圍橫跨了從模擬訊號到數字訊號的各類主流傳輸協議,從 1994 到 2006 年間共經歷了五個版本。以 2000 年推出的 v1.3 版本為界, v1.3 和 v1.4 的 EDID 被稱為 E-EDID ,即 Enhanced Extended Display Identification Data ——增強擴充套件顯示器標識資料,相比更早版本的 EDID 規範進行了資料量的擴充。

而隨著技術的進步和普及, VESA 協會於 2007 年進一步推出了新的格式標準 DisplayID ,被視為是第二代的 EDID 。 DisplayID 在向下相容 EDID 標準的同時增加了對於 3D 顯示、廣色域及 HDR 之類比較新的內容標準的支援。並且相比 EDID , DisplayID 對於資料格式的靈活性放寬了許多,讓顯示裝置廠商可以根據自己的需求增減所需的資料塊。

但相比規格更高的 DisplayID ,目前最主流的顯示設別識別協議仍然是 E-EDID 。本文基於 HDMI 協議下 E-EDID v1.4 進行介紹。

尋找 EDID

EDID 相比顯示裝置的解析度、色彩空間等等引數而言,是一個更加底層的資料,絕大多數的顯示裝置都不會預置檢視方式,我們需要通過在顯示訊號的源端——比如電腦上——通過一些第三方的程式進行查詢。 Windows 平臺可以使用 Monitor Asset Manager , macOS 上則有包含在 Xcode 工具中的 IORegistryExplorer ,可以單獨下載並獨立使用。

以 IORegistryExplorer 為例,開啟程式後在搜尋框內輸入「display」,在左側的目錄中找到 display0 下面的 AppleBacklightDisplay 與 AppleDisplay ,對應的分別是 MacBook 的內建螢幕與外接的顯示器,選擇其中任意一個之後右側 IODisplayEDID 下便是顯示器的 EDID 資料。

除了下載專用的程式之外,你也可以直接使用

ioreg -lw0 | grep IODisplayEDID

指令在 Terminal 中獲取所有正在使用中的顯示裝置的 EDID ,展示順序依然是內建 - 外接顯示器。

解讀 EDID

在絕大多數情況下,這些由顯示器回報上來的 EDID 資料是無需使用者勞神費力去解讀的,對於 EDID 資訊的編寫和韌體刷入也主要是顯示器廠商的工作,但是這仍然不妨礙我們以分段的形式簡單瞭解一下 EDID 資料的構成。

以 MacBook 內建螢幕的 EDID 資訊為例,其中包含了 256 個位元組( Byte )的 16 進位制資料,分為兩個各 128 位元組的資料塊 block0 和 block1 。

其中 block0 包含了 EDID 規定的基礎資料,也被稱為 Base Block ;而後的 block1 、block2 等等可以根據 EDID 協議的版本和裝置的支援規格最多延伸出 255 個 Extension Block (只限 E-EDID v1.4 ,v1.3 需要將 Block 255 留出來作為 Block Map ),組成由 256 個 Block 構成的 EDID 資料。

頭資訊(Header Information)

Base Block 的前 20 個位元組的資訊被稱為整段 EDID 的頭資訊,其中包含了 8 個位元組的固定字元、10 個位元組的生產廠商資訊與 2 個位元組的 EDID 版本資訊。

基本顯示引數(Basic Display Parameters and Features)

在 EDID 頭資訊之後的 5 個位元組則包含了裝置的基本顯示引數,負責描述顯示器支援的輸入格式——比如模擬訊號或數字訊號、螢幕的尺寸以及 Gamma 值,以及 1 位元組的功能支援資訊(比如是否是使用模擬訊號的單色顯示器、是否支援 DPMS ——顯示器的節能待機模式——等等)。

色度資訊(Color Characteristics)

基本顯示引數之後的 10 個位元組分別以紅色/綠色、藍色/白色的最低座標、紅綠藍白分別在 X 與 Y 軸上的最高座標數描述了顯示裝置顯示顏色的能力——比如對於單色顯示器來說,《VESA-EEDID-A2》規範文件中就建議將白色之外的三種顏色的 XY 軸座標均設定為 00hex 。

既定時序與標準時序(Established Timings, Standard Timings)

色度資訊後的 19 個位元組的資訊展示了顯示裝置的解析度資訊,分為 3 個位元組的 Established Timings 與 16 個位元組的 Standard Timings 。其中 Established Timings 3 個位元組分別對應了一些早期顯示器的格式,比如 Apple Mac II 的 640 x 480 @ 67Hz ,以及 IBM XGA2 的 720 x 400 @ 88Hz 等等;後面 16 位元組的 Standard Timings 則用來容納顯示裝置支援的更多預設解析度。

在 E-EDID v1.4 中這兩處解析度資料對於不使用 VESA Plug & Play 介面的顯示裝置都是選填的,因此可以看到蘋果在這兩處填寫的都是預設的填充符。

詳細時序資訊(Detailed Timing Descriptor Block)

在既定與標準時序之後的 72 個位元組被用來描述顯示裝置支援的更多解析度資訊,分為四個各 18 位元組的 Descriptor ,依次為:

  • 1st Detailed Timing Descriptor
  • 2nd Detailed Timing Descriptor
  • 1st Monitor Descriptor
  • 2nd Monitor Descriptor

其中 1st Detailed Timing Descriptor 會包含顯示裝置製造商決定的 Preferred Timing Mode (PTM) ,即由顯示面板決定的可以顯示最佳畫質的那個解析度,對應的通常就是顯示裝置的預設解析度。同時得益於 18 位元組可以承載的資訊量比前面既定時序與標準時序更多,這裡也可以填寫更多 CEA-861 檔案之外的非標準的解析度資料。

1st Detailed Timing Descriptor

而在 HDMI 協議下,後續的三組 Descriptor 中則會包含一部分 Monitor Range Descriptor,用來描述顯示裝置的水平與垂直重新整理率,以及 Monitor Name Descriptor 用來包含產品名稱。

擴充套件數量與校驗碼(Extension Flag & Checksum)

在 Base Block 的最後兩個位元組中,前一位元組被稱為 Extension Flag ,標記了這臺顯示裝置的 EDID 資料中包含了幾個 Extension Block 。最後一位元組則是 Base Block 前面 127 位元組資料的校驗碼,由源端在連線時對 Base Block 進行模除(modulo)後加總,計算結果為 00hex 即 EDID 資料無誤。

Extension Block

在格式基本固定的 Base Block 之後,顯示裝置的生產廠商可以根據自己的需要和裝置的規格自行新增 Extension Block 對顯示裝置的更多功能進行描述,比如更加細分的解析度種類、 HDR 和 3D 支援等等。如果顯示裝置自帶揚聲器的話,關於內建揚聲器的支援格式、分佈方式之類的資訊也會被儲存在 Extension Block 中。

EDID 的問題

回到開頭 Alin Panaitiu 部落格裡提到的那個問題上。

每當電腦連線到顯示器時,電腦會將使用者針對這臺顯示器的各項設定——比如佈局、解析度、色彩檔案等等,根據顯示器的 EDID 生成一份 UUID (識別碼)將對應的配置儲存下來。而顯示器在進入待機模式後,會完全斷開與電腦的連線、從電腦的 I/O 登錄檔中消失。

然而在 E-EDID v1.4 中, VESA 協會 並沒有強制要求 顯示裝置廠商在 EDID 中記錄產品的序列號——無論是在頭資訊中純數字格式的序列號還是 Monitor Descriptor 中 ASCII 編碼的序列號——這樣就導致一些顯示器廠商會將相同的 EDID 資料刷寫到同一批次相同型號的顯示器產品中。

《VESA-EEDID-A2》

而電腦正是根據顯示器的 EDID 來生成對應的配置檔案的,如果你用來組多螢幕的幾臺顯示器不巧是來自同一生產批次的同型號產品的話,它們韌體中相同的 EDID 會讓電腦為它們生成相同的 UUID ,哪怕這些 UUID 對應的是你分別設定過的不同的顯示設定。

因此,當顯示器被重新喚醒後,這些顯示器在電腦的眼中是完全相同的,電腦只能隨機將 UUID 對應的配置檔案分配給它們,最終呈現的結果便是你的電腦有時候會把你已經分別設定好的多顯示器配置搞混。

修改 EDID ?

很不幸的是,對於這些由於 EDID 導致的問題,目前仍然很難找到特別好的解決方案, Alin Panaitiu 最終也是通過寫了一個對調顯示器的 指令碼 來處理,並沒有從 EDID 本身入手。

儘管 EDID 通常儲存在顯示裝置的 EEPROM 上,是可以通過一些工具進行修改的。但是修改 EDID 不僅需要專用的軟體,還需要對 EDID 協議本身的編寫方式有足夠的瞭解,有時甚至還得手動計算一些引數(比如畫素頻率 Pix Clk 以確定某個解析度對應的重新整理率)。因此目前需要觸碰到 EDID 的場景中,反而是提取原有 EDID 資訊後注入 Hackintosh 以解決顯示問題反而佔了大多數。

但如果重新編寫 EDID 的確是你的需要,那麼這篇微軟為 Windows 硬體開發者提供的通過 INF 檔案覆寫 EDID 的技術文件或許是最專業穩妥的方式: Manufacturer override of monitor EDIDs ,也可以參閱中國電子技術標準化研究院出版的 EDID 規範詳解

> 下載少數派 2.0 客戶端、關注少數派公眾號,解鎖全新閱讀體驗 :newspaper:

> 實用、好用的正版軟體,少數派為你呈現 :rocket: