3. EDID基础
EDID(Extended Display Identification Data,扩展显示标识数据)是显示器、电视机、投影仪等显示设备向视频源(GPU、机顶盒、播放器)宣告自身能力与偏好的标准数据结构。在HDMI系统中,EDID通过DDC通道(基于I2C,地址0x50)传输,是CEC、HDCP、音频回传等功能正常工作的前提。理解EDID的结构、版本差异、数据块组织方式以及校验和算法,是进行自定义EDID、修复显示异常、实现多设备兼容性管理的核心基础。本章将从二进制结构出发,逐层拆解EDID的组成,并给出可落地的校验与修改方法。
上图展示了EDID的整体结构。Base Block是每个显示设备必须提供的,而Extension Block则根据设备功能(如HDMI音频、4K支持、HDR)按需添加。下面我们将深入解析每个部分的细节。
3.1 EDID的核心结构:从Header到Checksum
EDID的Base Block固定为128字节,从I2C偏移0x00开始读取。其结构布局遵循VESA E-EDID标准,每个字段都有明确的字节偏移和位定义。理解这些偏移是解析和修改EDID的第一步。
3.1.1 关键字段解析
| 字节偏移 | 字段名 | 长度 | 说明 |
|---|---|---|---|
| 0-7 | Header | 8字节 | 固定值 00 FF FF FF FF FF FF 00,用于识别EDID起始 |
| 8-9 | Manufacturer ID | 2字节 | PNP ID,3个ASCII字符压缩为16位 |
| 10-11 | Product Code | 2字节 | 厂商自定义产品编号 |
| 12-15 | Serial Number | 4字节 | 32位序列号,可为零 |
| 16 | Week of Manufacture | 1字节 | 生产周,0表示未知 |
| 17 | Year of Manufacture | 1字节 | 生产年份 = 值 + 1990 |
| 18 | EDID Version | 1字节 | 主版本号,通常为1 |
| 19 | EDID Revision | 1字节 | 次版本号,3/4/5等 |
| 20 | Video Input Definition | 1字节 | 信号类型(数字/模拟)、位深、接口类型 |
| 21 | Horizontal Screen Size | 1字节 | 屏幕宽度(cm),0表示未知 |
| 22 | Vertical Screen Size | 1字节 | 屏幕高度(cm) |
| 23 | Gamma | 1字节 | Gamma值 = (值+100)/100,0xFF表示2.2 |
| 24 | Features | 1字节 | 支持DPMS、色域、sRGB等特性 |
| 25-34 | Chromaticity | 10字节 | 红绿蓝白点的色度坐标 |
| 35-37 | Established Timings | 3字节 | 标准时序位图(VGA、XGA等) |
| 38-53 | Standard Timings | 16字节 | 8组2字节的厂商时序定义 |
| 54-125 | Detailed Timing Descriptors | 72字节 | 4个18字节描述符,可定义时序、名称、范围 |
| 126 | Extension Count | 1字节 | 后续扩展块数量 |
| 127 | Checksum | 1字节 | 校验和,使前127字节总和+校验和=0 (mod 256) |
在解析时,需要特别注意字节序。EDID中的多字节字段(如产品代码、序列号)采用小端序(Little-Endian)存储。例如,产品代码0x1234在字节10存储为0x34,字节11存储为0x12。
3.2 EDID版本演进:1.3、1.4与2.0的差异
EDID标准经历了多个版本迭代,每个版本在保持向后兼容的同时,增加了新的能力描述。版本号存储在字节18(主版本)和字节19(次版本)中。
3.2.1 版本对比表
| 特性 | EDID 1.3 | EDID 1.4 | EDID 2.0 |
|---|---|---|---|
| 发布时间 | 1997年 | 2002年 | 2016年(DisplayID 2.0) |
| 最大分辨率支持 | UXGA (1600x1200) | WUXGA (1920x1200) | 8K@60Hz及以上 |
| 色彩深度 | 6-bit/8-bit | 8-bit/10-bit/12-bit | 10-bit/12-bit/16-bit |
| 扩展块类型 | CEA-861B | CEA-861D/E/F | DisplayID 2.0 |
| HDR支持 | 不支持 | 通过CEA-861F VSDB支持 | 原生HDR元数据 |
| 音频支持 | 仅LPCM | LPCM + 压缩音频 | LPCM + 压缩 + 对象音频 |
| 3D支持 | 不支持 | 通过CEA-861D支持 | 原生3D描述 |
| 接口类型 | VGA/DVI | HDMI 1.4 | HDMI 2.1/DisplayPort |
EDID 1.4是目前最广泛使用的版本,它通过CEA-861扩展块实现了对HDMI 1.4特性的完整描述。EDID 2.0实际上与DisplayID 2.0标准融合,采用全新的数据块结构,不再使用传统的128字节Base Block格式,而是使用更灵活的Tiled DisplayID块。
3.3 Base Block与Extension Block的协作机制
Base Block提供了显示设备的基本信息,而Extension Block则承载了HDMI特有的功能描述。在HDMI系统中,最重要的扩展块是CEA-861系列(Tag 0x02)。
3.3.1 CEA-861扩展块结构
CEA-861扩展块同样为128字节,其内部结构如下:
- Tag (1字节):固定为0x02,标识这是CEA扩展块。
- Revision (1字节):CEA-861版本号(如3表示861C,4表示861D)。
- DTD Offset (1字节):指向Detailed Timing Descriptor的偏移量。
- Data Blocks (可变长度):包含音频数据块、视频数据块、VSDB(Vendor Specific Data Block)等。
- Detailed Timing Descriptors (18字节×N):额外的时序描述符。
- Checksum (1字节):与Base Block相同的校验算法。
在HDMI 1.4及以后版本中,VSDB是关键的扩展块,它包含了HDMI特有的能力声明:
VSDB结构示例(HDMI 1.4):
- Vendor ID (3字节): 0x000C03 (HDMI LLC)
- Physical Address (2字节): 设备物理地址
- Flags (1字节): 支持CEC、HDCP等
- Max TMDS Clock (1字节): 最大TMDS时钟(MHz/5)
- 可选字段: 3D、4K支持、HDR等
3.4 校验和计算:原理与实现
EDID的校验和机制简单但关键,它确保数据在传输过程中未被损坏。每个128字节块(Base Block和每个Extension Block)都有独立的校验和。
3.4.1 校验算法
校验和的计算方法如下:
- 将当前块的前127个字节(偏移0-126)的值累加。
- 对256取模(即取低8位)。
- 校验和字节 = (256 - 累加和) & 0xFF。
验证时,将前127字节与校验和字节相加,结果对256取模应为0。
// C语言实现示例
unsigned char calculate_checksum(unsigned char *edid_block) {
unsigned char sum = 0;
for (int i = 0; i < 127; i++) {
sum += edid_block[i];
}
return (unsigned char)(0x100 - sum);
}
// 验证函数
int verify_checksum(unsigned char *edid_block) {
unsigned char sum = 0;
for (int i = 0; i < 128; i++) {
sum += edid_block[i];
}
return (sum == 0);
}
3.4.2 校验和修改流程
当修改EDID中的任何字节后,必须重新计算校验和,否则设备会拒绝加载该EDID。修改流程如下:
- 定位需要修改的字节偏移。
- 修改目标字节值。
- 重新计算该块(Base或Extension)的校验和。
- 更新校验和字节(偏移127)。
- 如果修改了Extension Count(偏移126),还需检查后续扩展块是否完整。
3.5 实战案例:自定义EDID修复4K显示问题
下面通过一个实际案例,展示如何通过修改EDID解决4K@60Hz显示异常的问题。
3.5.1 问题背景
某用户使用HDMI 2.0线缆连接4K电视和显卡,但系统只能输出4K@30Hz,无法选择60Hz刷新率。初步判断是电视的EDID未正确声明HDMI 2.0能力。
3.5.2 分析过程
使用I2C读取电视的EDID,关键数据如下:
Base Block:
- Version: 1.4
- Extension Count: 2
CEA-861 Extension Block (第一个):
- Tag: 0x02
- Revision: 3 (CEA-861C)
- VSDB Vendor ID: 0x000C03
- Max TMDS Clock: 0x22 (170MHz,仅支持HDMI 1.4)
- 无4K@60Hz时序描述
问题定位:Max TMDS Clock字段值为0x22,对应170MHz,而4K@60Hz需要至少600MHz的TMDS时钟。此外,CEA-861C版本不支持4K时序描述。
3.5.3 修改方案
需要将CEA扩展块升级到861F,并添加4K@60Hz时序。具体操作:
- 将CEA Revision从3改为6(对应861F)。
- 将Max TMDS Clock改为0x78(600MHz/5=120,即0x78)。
- 在DTD区域添加4K@60Hz时序描述符(3840x2160@60Hz,Pixel Clock 594MHz)。
- 添加VSDB中的SCDC(Status and Control Data Channel)支持标志。
- 重新计算所有修改块的校验和。
修改后的VSDB关键字节:
- Max TMDS Clock: 0x78 (600MHz)
- SCDC Present: 1 (bit 7 of Flags)
- 4K@60Hz DTD: 像素时钟 594MHz,H: 3840, V: 2160
3.5.4 结果与复盘
修改后,系统成功识别4K@60Hz选项,画面正常输出。但需要注意:
- 此修改仅适用于支持HDMI 2.0的显卡和线缆。
- 如果电视硬件本身不支持HDMI 2.0,修改EDID可能导致无信号。
- 建议在修改前备份原始EDID,以便恢复。
3.6 常见误区与调试建议
在EDID解析和自定义过程中,以下误区需要特别注意:
- 误区1:忽略字节序。多字节字段(如产品代码)使用小端序,直接按大端序解析会导致错误。
- 误区2:混淆EDID版本与CEA版本。EDID 1.4可以搭配不同版本的CEA扩展块(861C/D/E/F),两者独立。
- 误区3:修改后不验证。修改EDID后,应使用工具(如Windows的"显示设置"或Linux的
edid-decode)验证解析结果。 - 误区4:忽略扩展块数量。修改Extension Count后,必须确保后续扩展块完整且校验和正确。
调试EDID问题时,推荐使用以下工具链:
- 读取EDID:Linux下使用
i2cdump -y 0 0x50,Windows下使用"显示器的EDID查看器"。 - 解析EDID:使用
edid-decode工具,可输出完整的字段解析。 - 修改EDID:使用AW EDID Editor或自定义脚本,修改后自动计算校验和。
- 验证修改:重新读取EDID,使用
edid-decode确认修改生效。