EDID 校验和不对、或者根本读不到:怎么判断是哪一段的问题
工具报「checksum error」和工具报「读不到 EDID」,是两件事。前者说明数据已经取回来了、只是字节对不上;后者说明取数据这条路就没走通。先分清是哪一种,再决定往字节里查还是往链路上查——顺序反了会白折腾很久。
站内已经有一篇讲显示设备识别异常的总体排查:HDMI/EDID 不识别?显示设备识别异常 7 步排查。那篇给的是从换线、直连到调上电顺序的完整流程,需要走一遍总流程就去看它。这篇不重复那 7 步,只处理一种成因:你已经用工具把 EDID 读出来了(或者试图读却拿到一堆看不懂的东西),要判断问题出在这 128 字节的哪一段。
先分清:是没拿到,还是拿到了但不对
这两种情况的界线其实很清楚,判据就一条——前 8 个字节。
按 VESA E-EDID 规范,基础块固定 128 字节,开头 8 字节是写死的标志:00 FF FF FF FF FF FF 00。这 8 个字节不对,手上这段数据按规范就不是有效的 EDID 基础块。既然不是有效基础块,再去算它的校验和没有任何意义——你算的是一堆不知道从哪来的字节。
所以拿到数据第一件事不是算校验和,是看头 8 字节:
- 头 8 字节对得上:数据确实是从设备那边读回来的 EDID,问题在内容,往下一节走。
- 读回来全是
FF,或者全是00:header 自然对不上。这类数据说明读取过程没有真正取到 EDID 内容,方向应该转到通道和链路,而不是继续研究字节。 - 头 8 字节的图案出现了,但不在开头:比如
FF FF FF FF FF FF 00出现在第 2 个字节之后。这是起始地址偏了,整块数据整体错位一个字节。这种情况下后面所有字段都会解错,校验和当然也过不去,但真正的毛病是读取或者复制粘贴时把边界弄丢了。
本页下方的解析器就是按这个顺序做的:先看 header,header 不符直接给出提示、根本不往下解——它不会拿一段错位的数据去硬凑出一个「厂商」和「分辨率」来骗你。
校验和这条规则本身:128 个字节相加,低 8 位必须是 0
规范把基础块的第 127 字节(也就是最后一个字节)定义为校验和。规则只有一句:这 128 个字节当作无符号数全部相加,和对 256 取模应该等于 0。
这条规则可以反过来用,有两个很实用的推论:
推论一:想自己补一个校验和,算法是确定的。 把前 127 个字节相加、对 256 取模得到余数 r,那第 127 字节就应该写 (256 − r) mod 256。所以只要有人手工改过 EDID 里的任何一个字节——哪怕只是改了一位特性支持位——不重算这个字节,整块就作废。
推论二:校验和只覆盖它自己所在的那 128 字节。 第 126 字节写的是扩展块的数量。如果这个字节不是 0,说明这台设备的 EDID 不止基础块这一段。基础块的校验和管不到扩展块的内容,反过来扩展块的数据也不该被拿去和基础块一起求和。求和之前先把前 128 字节切出来,这是最常见的一种「假错」来源:工具把手上全部字节一股脑加起来,报了个校验和错误,其实基础块本身好好的。
字节数不对,算出来的校验和一定是错的
在怀疑设备之前,先数一下你手上到底有多少个字节。
EDID 的长度是 128 的整数倍——基础块 128,每有一个扩展块再多一段。如果数出来是 127、129 或者 131 这种数,那不是设备的问题,是数据在传递过程中掉了或者多了字节。常见于把十六进制文本从某个工具的界面里复制出来时,行尾被截断、或者把行号、地址列一起复制了进来。
判断方法很直接:把文本里的十六进制字节数一遍,看是不是 128 的整数倍;不是,就先把数据重新导一次,别急着下结论。本页解析器在不足 128 字节时会直接告诉你当前有多少字节,就是为了让这一步不用手工数。
头 8 字节对、字节数也对,校验和还是不过
到这一步才是真正的「内容不对」。这时候要做的是逐段看那些人能直接看懂的字段,用它们把可疑范围往后推。
基础块前半段几乎全是标识性的字段,解出来是不是合理,人一眼就能判断:
| 偏移 | 内容 | 怎么判断它合不合理 |
|---|---|---|
| 8–9 | 厂商 ID(PnP ID) | 三个字母各占 5 bit 打包进两个字节,A 记为 1。解出来应该是三个 A–Z 的字母;出现奇怪的符号,说明这两个字节可疑 |
| 10–11 | 产品码(小端) | 数值本身无从核对,但可与设备铭牌或厂商资料比对 |
| 12–15 | 序列号(小端) | 同上 |
| 16 | 制造周 | 合理范围应落在一年的周数之内 |
| 17 | 制造年 − 1990 | 加回 1990 之后应该是一个说得通的年份,解出来在 1990 之前或者远在未来,就是这个字节坏了 |
| 18–19 | EDID 版本与修订 | 应是规范里存在的版本组合 |
| 126 | 扩展块数量 | 和你实际拿到的字节数应当对得上 |
这几段如果解出来都合情合理,说明前半段字节没被破坏,剩下的嫌疑就落在后半段的时序与描述符区。
描述符区:偏移 54 到 125 这 72 个字节
这一段是四个各 18 字节的描述符,也是最容易看出「数据坏了」的地方,因为它们的内容有内在的一致性可以互相印证。
判断一个描述符是什么类型,只看它的前两个字节(像素时钟,单位 10 kHz,小端):非 0 表示这是一个详细时序描述符(DTD),为 0 表示它是显示器名称、序列号字符串、范围限制之类的其它类型描述符。
如果是 DTD,前 8 个字节的排布是:
| 偏移 | 内容 |
|---|---|
| 0–1 | 像素时钟,单位 10 kHz(小端) |
| 2 | 水平有效 低 8 位 |
| 3 | 水平消隐 低 8 位 |
| 4 | 高 4 位 = 水平有效的高 4 位;低 4 位 = 水平消隐的高 4 位 |
| 5 | 垂直有效 低 8 位 |
| 6 | 垂直消隐 低 8 位 |
| 7 | 高 4 位 = 垂直有效的高 4 位;低 4 位 = 垂直消隐的高 4 位 |
注意这里有一个很多人搞错的点:刷新率不是 EDID 里直接写着的字段,它是推算出来的——像素时钟 ÷ (水平总数 × 垂直总数),其中总数等于有效加消隐。任何工具给你显示的刷新率都是这么算的,包括本页下方那个。
这个推算关系正好可以拿来当校验手段:如果某个 DTD 解出来的水平有效、垂直有效看着像个正常分辨率,但推算出的刷新率荒唐得离谱,那多半是消隐值或者像素时钟那几个字节被破坏了。反过来,四个描述符全都解不出合理内容,那怀疑范围就要放大回整块数据的完整性,而不是纠结某一段。
校验和能证明什么,不能证明什么
这一条经常被误用,值得单独说。
校验和是一个简单的模 256 和校验,它的能力边界是确定的:
- 校验和不通过 → 一定有字节和写入时不一致(或者你读的起始位置、字节范围不对)。这个结论是可靠的,不会冤枉人。
- 校验和通过 ≠ EDID 内容正确。和校验对错误的抵消没有防御能力:一个字节多了 1、另一个字节少了 1,总和不变,校验照样通过。所以「校验和是对的」只能说明数据没有明显损坏,不能说明这份 EDID 描述的能力和这台显示设备真实的能力一致。
后一条在做过 EDID 学习、复制、手工编辑的链路里尤其要留心:一份被人为改过而且重算了校验和的 EDID,形式上完全合法,但它宣称的分辨率可能根本不是下游设备真正能吃下的。这类问题查不到校验和头上,得回到显示表现本身去判断,具体做法见EDID / 显卡输出与多屏拼接配置(实操步骤)那篇里的输出配置与固定流程。
根本读不到的那条路:DDC 通道和视频通道不是一回事
如果 header 那一关就没过、拿回来的是空数据,问题不在字节里,在取字节的这条通道上。
站内既有文章已经写明了这条通道是什么:显卡是通过接口里的 DDC 通道(走 I2C 总线)去读 EDID 的,这条通道和传视频的那几对差分线是分开的针脚。这个结构决定了两件反直觉的事:
- 画面正常,不等于 EDID 一定读得到;
- EDID 读得到,也不等于视频链路一定通。
两者不能互相当作证明。这也解释了那篇实操文里点名的一个原因:有些转接头根本不接 DDC 那几根针,视频过得去,EDID 过不去,源设备只能把对面当成非即插即用设备处理。
另一类是时机问题而不是通道问题:源设备开机那一刻如果对端还没准备好,它读不到就按默认值定下来了,之后也不会主动重读;把线拔下再插上等于强行让它重来一次。这个判据在开头那篇 7 步排查里已经给过——每次拔插都能出图,本身就是诊断结论,不是救急手段。
一个可以照着走的收敛顺序
把上面几节串成顺序,就是这篇的全部结论:
- 数字节:是不是 128 的整数倍?不是,重新导数据。
- 看 header:前 8 字节是不是
00 FF FF FF FF FF FF 00?不是,去查 DDC 通道与转接环节,别在字节里耗。 - 切基础块:只拿前 128 字节去算校验和,别把扩展块也加进去。
- 算校验和:128 字节相加对 256 取模是不是 0。
- 看前半段:厂商三字母、制造年份、版本这几项解出来合不合理,把嫌疑往后推。
- 看描述符区:像素时钟非 0 的那些描述符,推算的刷新率是否说得通。
前四步都可以直接把十六进制贴进本页下方的解析器一次跑完,它会告诉你字节总数、header 是否合法、校验和过不过、以及第一个描述符解出来的时序。
最容易栽的三个坑
一、把校验和错误当成显示设备坏了。 校验和不过只能说明这段字节和写入时不一致,它不区分是设备里存的内容坏了、还是读取路径把数据弄坏了。在换设备之前,先把上面第 1 到第 3 步走一遍,很多所谓的「校验和错误」在这三步里就没了。
二、手工改了一个字节,忘了重算第 127 字节。 只要动过基础块里的任意一个字节,都必须按 (256 − r) mod 256 重算校验和,否则整块作废。这一点在做 EDID 编辑、把一份 EDID 改成固定输出模式时最容易漏。
三、把「校验和通过」当成 EDID 没问题。 前面说过,和校验挡不住互相抵消的错误,更挡不住一份合法但描述错了的 EDID。如果分辨率表现始终不对而校验和一路绿灯,就该换个方向查——比如源设备读到的到底是显示设备本身的 EDID,还是链路中间某台设备代答的那一份,参见拼接屏分辨率反复跳变?EDID 没锁住是主因。想先补一下显卡输出与 EDID 的整体关系,可以看播放器视频输出(显卡/拼接/EDID)科普。
在线解析你自己的 EDID
解析全程在浏览器本地完成,数据不会离开你的电脑。
EDID 基础块解析
把读到的 EDID 十六进制粘进来,解析在你自己的浏览器里完成,不上传任何数据。 支持空格、换行、0x 前缀混排。
留言讨论
评论发布后会被人工复核,违规内容将被删除。
如果发表没有反应,可以前往联系我们告诉我们。