1. EDID基础概念:从零认识显示器的“身份证”

大家好,我是老张。做显示系统这行十几年了,每次遇到显示异常,第一件事就是查EDID。说白了,EDID就是显示器的“身份证”——它告诉显卡:“我是什么牌子、支持多大分辨率、刷新率能跑多高”。没有这张身份证,显卡就只能瞎猜,猜错了就是黑屏、花屏。

什么是EDID?

EDID的全称是Extended Display Identification Data,扩展显示标识数据。嗯,名字挺长,但核心就一句话:显示器写给显卡的自我介绍信。

这封信存在显示器的EEPROM芯片里,通常是128字节。显卡上电后,通过I²C总线(DDC通道)去读这128字节。读到了,就知道怎么驱动显示器;读不到,那就麻烦了。

核心要点:EDID是显示链路中从设备(显示器)向主设备(显卡)单向传输的数据。显卡是“读”,显示器是“被读”。

我记得刚入行时,有个项目显示器死活点不亮。折腾了两天,最后发现是EDID的校验和错了。从那以后,我养成了一个习惯——拿到新显示器,先dump它的EDID看看。

EDID在显示链路中的作用

你想想看,显卡怎么知道显示器能支持什么?总不能一个个分辨率去试吧?EDID就是干这个的。它的作用可以归纳为三点:

  • 身份识别:厂商ID、产品ID、生产日期、序列号。我经常用这些信息判断显示器是不是“山寨货”。
  • 能力宣告:支持的最大分辨率、刷新率、色彩深度、音频格式。显卡根据这个决定输出什么信号。
  • 时序参数:每个分辨率对应的行场同步信号参数。说白了,就是告诉显卡“你该用多少像素时钟、行消隐多少、场消隐多少”。

我曾经遇到一个案例:客户说4K显示器只能输出1080P。查了半天,发现是EDID里没写4K的时序。显示器硬件明明支持,但EDID没告诉显卡——这就是典型的“能力没宣告”。

避坑指南:我曾经在产线上遇到过一批显示器,EDID里的校验和全是错的。原因是烧录器固件有bug。所以,量产前一定要用EDID工具校验一遍。

EDID数据块结构解析(128字节标准结构)

标准的EDID是128字节,结构非常固定。我把它分成几个区域,方便记忆:

字节偏移 长度 内容 说明
0x00-0x07 8 Header 固定为 00 FF FF FF FF FF FF 00,EDID的“魔数”
0x08-0x11 10 厂商信息 包括3字节PNP ID、2字节产品ID、4字节序列号
0x12-0x13 2 生产周/年 比如 0x1E 0x1F 表示2019年第30周
0x14-0x17 4 EDID版本 通常为 0x01 0x04(版本1.4)
0x18-0x35 30 基本显示参数 最大分辨率、色彩特性、Gamma值等
0x36-0x47 18 色度坐标 红绿蓝白点的CIE坐标
0x48-0x53 12 标准时序 4个标准分辨率,每个3字节
0x54-0x7B 40 详细时序描述 4个18字节的时序块,通常第一个是首选时序
0x7C-0x7D 2 扩展标志 是否有后续EDID扩展块
0x7E 1 校验和 前127字节之和取低8位,加上此字节应为0

这里我重点说几个容易出问题的地方:

  • Header(0x00-0x07):必须是 00 FF FF FF FF FF FF 00。我见过有人烧录时把第一个字节写成了01,结果显卡直接不认。
  • 校验和(0x7E):这是最常见的坑。前127字节加起来,加上校验和字节,结果必须是0x00。我曾经用脚本批量检查过一批EDID,发现5%的校验和都是错的。
  • 详细时序(0x54-0x7B):第一个详细时序块通常是“首选时序”,也就是显示器最推荐的分辨率。如果这里写的是1920x1080,显卡就会优先输出1080P。

注意:EDID的字节顺序是小端序(Little-Endian)。比如产品ID是0x1234,在EDID里存的是0x34 0x12。我第一次解析时就被这个坑过,读出来的ID完全不对。

EDID结构图

下面这张图是我用SVG画的,把128字节的结构画成了直观的布局。你一看就明白:

EDID 128字节结构布局 Header (8字节) - 固定魔数 00 FF FF FF FF FF FF 00 厂商信息 (10字节) - PNP ID + 产品ID + 序列号 版本/生产信息 (6字节) - 版本号 + 生产周/年 基本显示参数 (30字节) - 最大分辨率、Gamma、色彩 色度坐标 (18字节) - RGBW的CIE xy坐标 标准时序 (12字节) - 4个标准分辨率 详细时序描述 (40字节) - 4个18字节时序块(首选时序) 扩展标志 (2字节) + 校验和 (1字节) 0x00 0x08 0x12 0x18 0x36 0x48 0x54 0x7C

这张图我故意用了不同颜色区分各个区域。红色是Header,蓝色是厂商信息,绿色是版本...你调试的时候,用十六进制编辑器打开EDID文件,对照这张图,一眼就能定位到问题区域。

实战:如何读取EDID?

在Linux下,我常用edid-decode工具。Windows下可以用MonitorInfoView。这里给个Linux下的例子:

# 读取显卡连接的显示器的EDID
sudo get-edid | edid-decode

# 输出示例(部分):
# EDID version: 1.4
# Manufacturer: DEL (Dell)
# Product ID: 0x1234
# Serial Number: ABC123
# Maximum image size: 60 cm x 34 cm
# Gamma: 2.20
# Detailed mode: 1920x1080 60.00 Hz (首选时序)
#   Pixel clock: 148.50 MHz
#   H: 1920 2008 2052 2200
#   V: 1080 1084 1089 1125
# Checksum: 0x4A (valid)

看到“Checksum: valid”我才放心。如果显示invalid,那就要查查是不是EEPROM坏了,或者烧录时数据错了。

小技巧:我习惯把EDID dump成二进制文件,然后用Beyond Compare对比两个显示器的EDID。比如一个正常、一个异常,对比一下就知道差异在哪了。

好了,EDID的基础概念就讲到这里。128字节虽然不多,但每个字节都有它的意义。下一章我会讲EDID的扩展块——毕竟现在4K、8K显示器,128字节根本不够用。


可可精品资料库