H110/B250主板BIOS魔改:CPU微码、ME与刷写校验全流程
简介:面向希望为 B150、B250、H110 等老主板扩展 Intel 8/9 代 CPU 兼容性的 DIY 玩家与装机爱好者,这份 BIOS 魔改工具包提供了一套较完整的固件修改辅助材料,适合具备一定硬件基础、了解刷写风险的用户在做好备份与稳定供电的前提下研究使用。压缩包为 zip,共 435 个文件、约 83.9MB,以 bin 固件/模块、exe 与 bat/cmd 工具、txt 说明、efi 驱动及 diff/dat 补丁数据为主,并含 dll、lom、pdf 等辅助内容,覆盖 Windows 与 Linux 环境下常见的固件解包、模块替换和差异比对需求。已有 9569 人学习下载。其价值在于把分散的魔改工具、模块资源与说明文档集中归档,便于读者按芯片组和平台查阅兼容模块、核对补丁差异并理解固件组成,也为研究厂商限制与 DIY 升级方案提供参考。
1. 一块 H110 主板能不能吃下八代六核:先看清这套 BIOS 魔改工具动的是哪几层
手里压着一块 H110 或者 B250 的老板子,CPU 又刚好缺一颗,这种时候大多数人第一反应是换平台,而实际上一套 BIOS 魔改工具就能让这块板子认下原本不支持的处理器。它做的事情并不神秘:把官方固件拆开,换掉 CPU 微码、降级管理引擎固件、调整 PCH 的端口与时钟配置,再把校验和补齐后重新封装成一个可以烧进去的镜像。听起来像拼图,实际动手时每一步都有硬性约束,改错一个字节就是黑屏。
这套工具适合两类人:一类是手上确实有闲置的 100/200 系主板,想让老平台再撑一两年;另一类是想弄明白 UEFI 固件到底由哪些部分组成,借一块便宜板子做实验。不适合拿来给生产环境的主力机做尝试,因为魔改固件的稳定性取决于原厂固件的底子,不同厂商、不同版本的镜像能改到什么程度差别很大。
先把预期摆正:改完之后 CPU 能点亮、能进系统、能正常睿频,这算成功;至于睡眠唤醒、核显输出、PCIe 通道分配这些边角功能,能不能全须全尾,得看具体板子的供电设计和原厂固件留了多少余地。下面按固件结构、备份、修改、刷写、排错的顺序往下拆。
2. 拆开固件分区:微码、管理引擎与选项字节各改哪一处
固件不是一整块随便写的数据,它有自己的分区表和内部结构。搞不清楚这一点就直接动手,最常见的结局是改完刷进去,主板连风扇都不转。
2.1 从 Flash Descriptor 看镜像被切成几段
整片闪存镜像最前面是一张区域描述符表,它规定了后面每一段数据的起始偏移和长度。常见的分区有这么几块:
| 区域 | 典型内容 | 魔改时的处理 |
|---|---|---|
| Descriptor | 区域表、厂商信息、上电配置 | 一般不动,动了要重算整片校验 |
| ME | 管理引擎固件与配置 | 需要替换成兼容版本 |
| GbE | 网卡固件与 MAC | 不要整段覆盖,会丢 MAC |
| BIOS | UEFI 卷,微码、驱动、Setup | 主要修改对象 |
| EC | 嵌入式控制器固件 | 通常不动 |
用编辑器打开镜像,开头能搜到一串固定的特征字节,描述符表里每一行是「基地址 + 长度」的十六进制值。我一般会先把这几行的值抄到纸上,后面替换任何一段之前都对着这张表核一遍长度,因为一旦某一段长度变化,后面所有段的偏移全部错位,描述符表如果没同步更新,刷进去就是彻底的砖。
这里有个反直觉的点:很多人以为改 BIOS 就是改最后那一大段,实际上如果只替换 BIOS 区而不动描述符,理论上是安全的;但只要你换进去的 BIOS 区比原来长了一点点,尾部就会覆盖到后面的数据,或者干脆超出闪存容量被截断。所以换微码这类操作,原则永远是「等长替换」或者「替换后重新按描述符表回填」,不能直接拼接。
2.2 微码替换:为什么不能整段覆盖
CPU 微码在固件里是以独立的文件形式存在的,一个文件里可以塞多个不同 CPUID 的微码块。每个微码块有自己的头部,字段大致是这样:
import struct, sys # 微码头部固定 48 字节,格式:9 个 32 位字段 + 12 字节保留 HDR_FMT = '<9I12s' HDR_LEN = struct.calcsize(HDR_FMT) # 48 def dump_microcodes(blob, base=0): off = 0 while off + HDR_LEN <= len(blob): (hdr_ver, revision, date, cpuid, checksum, loader_rev, flags, data_size, total_size, _res) = struct.unpack_from(HDR_FMT, blob, off) # 头部版本号不为 1 说明这里不是微码起点,直接停 if hdr_ver != 1 or total_size == 0 or off + total_size > len(blob): break # 整个微码块按 32 位累加应当为 0,否则校验不对 words = struct.unpack_from('<%dI' % (total_size // 4), blob, off) ok = (sum(words) & 0xFFFFFFFF) == 0 print('偏移 0x%06X CPUID 0x%08X 版本 0x%08X ' '平台位 0x%02X 长度 %d 校验 %s' % (base + off, cpuid, revision, flags & 0xFF, total_size, 'OK' if ok else 'BAD')) off += total_size if __name__ == '__main__': with open(sys.argv[1], 'rb') as f: dump_microcodes(f.read())这段脚本的作用是把一段二进制里连续排列的微码块逐个解析出来,输出 CPUID、修订号和长度。参数上要留意total_size这个字段,它表示这个微码块的总长度(含头部),下一个块的起点就是当前位置加上它。判断结束的条件有三个:头部版本不是 1、长度为 0、或者越界,任一成立就停止,避免在无关数据上死循环。
知道结构之后就能理解为什么不能「整段覆盖」了。你从别的固件里抠出来的微码段,长度和原来的往往不一致,而微码文件在 UEFI 卷里是作为独立文件存在的,文件之间的偏移是紧挨着的。直接覆盖会让后面的文件全部错位,卷头的长度字段和校验和对不上,固件在启动早期解析卷的时候就会判定损坏。正确做法是整体替换这个微码文件的内容,同时让固件工具重算所在卷的头部校验,而不是用十六进制编辑器硬贴。
另一个坑是平台标志位。一个微码块可以被多个平台共用,头部里的 flags 字段是一个位图,每一位对应一类平台。新微码的 flags 如果和你原固件里其他微码不一致,可能出现「微码加载了但被跳过」的情况——现象就是 CPU 能点亮,但跑分明显偏低,因为跑在了没有微码修正的早期状态。
2.3 管理引擎固件降级窗口:版本不对直接不亮
管理引擎固件是固件里最容易被忽视、但影响最大的一段。它负责上电时序的一部分,还参与 CPU 的初始化流程。老平台原厂固件里带的管理引擎版本,通常不支持后来架构的处理器,所以魔改时必须把它换成落在兼容窗口内的版本。
换的方法不是简单地把另一份固件贴进去,而是要用配套的配置工具把管理引擎区域重新构建一遍:先导出原厂固件的配置,把 SKU 类型、电源相关的几项配置调成目标平台能接受的组合,再和新的固件主体一起生成一段新的完整区域。这一步如果只替换主体不动配置,现象是通电后风扇转一下就停,或者反复重启,因为上电时序卡在管理引擎初始化的等待上。
还有一点血泪经验:管理引擎区的长度在描述符表里是写死的,新生成的区域如果比原来的短,尾部要按闪存的擦除粒度补齐;如果比原来的长,就只能放弃,或者找一份更小的固件主体。补齐用 0xFF 还是 0x00 有讲究,擦除态是 0xFF,但有些配置结构要求尾部填 0x00,填错了不会立刻出问题,而是在下次冷启动时才发作,非常难查。
对于 100/200 系芯片组,能稳定带起新架构管理引擎版本就那么几个,选的时候优先看两件事:一是这个版本在原厂固件里有没有被其他板型用过,二是配置工具里对应的 SKU 是不是消费级。企业级 SKU 的固件即使版本对得上,也可能因为额外的校验流程导致起不来。
2.4 选项字节与 SKU 切换:改错一个 bit 就白忙
固件里还有一大块是 Setup 相关的变量区,它决定了开机时哪些选项可见、哪些被隐藏、默认值是多少。魔改场景下经常要动的有两类:一类是 PCIe 端口和通道的分配,新架构处理器的通道划分和老的不一样,配置对不上会出现「能进系统但某几个 SATA 口或 PCIe 槽失灵」;另一类是供电相关的限制项,有些板子默认把电流墙设得很保守,换上新 CPU 后一跑负载就降频。
这块的修改我一般用图形化的配置编辑器,思路是先在固件里定位到 Setup 的那个文件,导出成可读的文本形式,改完再导回去。改的时候有个原则:只改确定的项,不要顺手把隐藏开关全打开,因为有些选项背后关联着固件里并不存在的硬件支持,打开之后初始化流程会走到一个未定义分支。
SKU 切换是另一个高频陷阱。消费级和企业级固件在初始化顺序上有差异,把企业级的配置原样搬到消费级板子上,能通电但过不了内存自检。判断办法很朴素:先看原厂固件的区域表里管理引擎区的大小,企业级的通常明显大一圈,对不上的话就别费劲了。
3. 下手前的三件保命事:读原片、备份、认芯片
魔改翻车的成本很高,但绝大多数翻车是可以救回来的,前提是你在动手之前把该留的东西留全了。
3.1 三种刷写路径怎么选
刷写方式决定了你有多大的试错空间,先看对比:
| 方式 | 前提 | 可恢复性 | 适用阶段 |
|---|---|---|---|
| 厂商刷写工具 | 固件能通过签名校验 | 低,失败即黑屏 | 只适合刷官方版本 |
| 通用刷写工具强制模式 | 描述符未锁定写入保护 | 中,失败后需外部手段 | 小改动验证 |
| 外部编程器直刷 | 需要接触闪存芯片 | 高,可反复重刷 | 魔改首选 |
我的习惯是全程走外部编程器。原因很简单:魔改固件第一次刷进去大概率不是最终版,可能要来回改两三遍,只有直刷才能保证每一次都有退路。软刷适合在你已经验证过一版可用固件、只想做个小调整的时候用,第一次上手不建议。
如果主板是双固件设计,那另说,主固件刷坏还能切到备份固件救回来,这种板子容错空间大很多。但要注意切换开关的逻辑,有些设计是切换之后仍然从主固件读取一部分配置,这种情况下刷坏主固件一样起不来。
3.2 用编程器把原厂镜像完整读出来
这一步是整个流程里最不能省的一步。读出来的原厂镜像要保存三份:本地一份、移动硬盘一份、网盘一份。因为后面的每一次修改都是在这份镜像上做文章,一旦原片丢了、改废了,你就只能去找别人的同型号镜像,而别人的镜像里 MAC 地址和主板序列号跟你不一样,刷进去会出现网卡异常。
操作上,编程器夹子夹住闪存芯片的时候一定要断电、拔掉电池,夹子方向不能反。读取之后立刻做一次全片读取比对:连读两次,两次结果完全一致才说明接触良好。接触不良读出来的数据会有随机位翻转,直接拿这个当原片,后面所有修改都建立在错误的基础上。
# 用编程器命令行工具连读两次,比对一致性 flashrom -p ch341a_spi -r dump_a.bin flashrom -p ch341a_spi -r dump_b.bin sha256sum dump_a.bin dump_b.bin命令里的-p指定编程器类型,-r表示读出到文件。两次哈希一致只能说明读取稳定,不能说明内容正确,所以还要看文件大小是否和芯片标称容量完全一致,比如标称 8MB 的芯片读出来应该是 8388608 字节,多一个字节或少一个字节都说明有问题。有些工具会自动去掉尾部填充,这种情况要加参数强制全片读取。
读稳之后,还要确认这份镜像里描述符表、管理引擎区、BIOS 区都在,且长度加起来不超过芯片容量。用前面那段解析脚本扫一遍,能看到多组微码就说明 BIOS 区定位正确了。
3.3 校验和与镜像一致性检查
固件内部有两级校验:卷头校验和、以及部分结构的整体校验。改完之后如果只靠「刷进去试试」来验证,效率太低。我一般先用脚本扫一遍,把明显不对的地方揪出来。
import struct, sys FV_SIG = b'_FVH' def check_volumes(data): """扫描所有固件卷,校验头部 16 位累加和""" pos, found = 0, 0 while True: idx = data.find(FV_SIG, pos) if idx < 0: break fv_start = idx - 0x28 # 签名在卷头偏移 0x28 处 if fv_start < 0: pos = idx + 4 continue header_len, checksum = struct.unpack_from('<HH', data, fv_start + 0x30) if 0 < header_len <= 0x1000 and fv_start + header_len <= len(data): words = struct.unpack_from( '<%dH' % (header_len // 2), data, fv_start) total = sum(words) & 0xFFFF print('卷 0x%06X 头长 %d 校验 0x%04X %s' % (fv_start, header_len, checksum, 'OK' if total == 0 else 'BAD 差值 0x%04X' % total)) found += 1 pos = idx + 4 print('共发现 %d 个固件卷' % found) if __name__ == '__main__': with open(sys.argv[1], 'rb') as f: check_volumes(f.read())逻辑上,卷头偏移 0x28 处是固定的特征字节,往前推 0x28 字节就是卷的起点;偏移 0x30 处两个 16 位字段分别是头长度和校验和。校验的算法是把整个头部按 16 位为单位累加,结果应当为 0。输出里如果出现 BAD,后面跟的差值就是需要补偿的量,但我不建议手工补偿,正确做法是回到固件编辑工具里让它重新封装一次。
需要注意的是,这个脚本只能验证卷头,验证不了卷内部每个文件的头部校验。文件级的校验要靠编辑工具在保存时自动重算,所以修改流程一定要走工具,不要用十六进制编辑器直接改字节。
4. 从原厂镜像到可刷固件:一次完整的魔改流程
前面把结构讲清楚了,这一章走一遍完整流程。每一步都假设你手上已经有了一份读稳的原厂镜像。
4.1 解包镜像并定位微码与管理引擎区域
第一步是把镜像拆开,看清里面有哪些卷、哪些文件。用固件编辑工具打开镜像,左侧会呈现出树状结构,微码通常位于 BIOS 区的一个独立卷里,文件类型标识为一个特定的 GUID;管理引擎区在描述符表里是独立的一段,不在 UEFI 卷树里。
定位微码有个快办法:直接搜特征。微码块头部第一个 32 位字段固定是 1,紧接着是修订号,这两个值组合在一起特征很明显。也可以用前面那段解析脚本对整个镜像做一次全盘扫描,输出所有能解析成微码的偏移,然后对照片区表确认哪个落在 BIOS 区范围内。
定位到之后,把这份微码文件的内容导出成单独文件,记下它的原始长度。这一步是后面等长校验的基准。
4.2 换微码、修核显模块、调 PCH 配置
真正的修改分三块,顺序不能反。
第一块是微码。把目标平台需要的微码块按 CPUID 逐个添加进微码文件,注意保留原文件里那些你还要用的老 CPUID 的块——万一魔改失败想刷回原 CPU,微码还在,省一次折腾。添加的时候用工具插入而不是拼接,让工具去处理长度和校验。核显输出如果需要用到,图形初始化模块和显示相关的那几个模块也要一并换成版本更新的,否则新 CPU 的核显会在系统里显示成一个未知设备,或者干脆黑屏但独显正常。
第二块是 PCH 配置。新架构处理器在芯片组侧的通道分配和老的不一样,固件里对应的配置项要跟着调。这一步最考验耐心,因为不同的板子布局不同,配置值抄别人的往往不灵。我的做法是找一份同芯片组、已经能正常支持新平台的固件,把相关配置项逐个对比,只改差异部分,改完在注释里记下改了哪几项。
第三块是集成度和功能裁剪。有些原厂固件里塞了一堆当前板子根本用不到的功能模块,删掉能腾出空间放新微码,但删的时候要看依赖关系,删了被别处引用的模块会导致启动早期报错。保守做法是只删明确独立的模块,不确定的一律留着。
注意:三块修改要分三次保存、三次校验,不要一次性全改完再验证。分批改才能定位到底是哪一步引入了问题。
4.3 重建卷校验和与整片封装
工具保存的时候通常会自动重算卷头校验,但不是所有工具都可靠。保存之后一定要用前一段的脚本再扫一遍,确认所有卷的校验都是 OK。
接下来是整片封装:把修改后的 BIOS 区按描述符表里的偏移回填到完整镜像中。这里的关键是长度必须完全一致。如果修改后 BIOS 区变短了,尾部用 0xFF 补齐到这个区的原始长度;变长了就说明删得不够,得回去接着删。
回填完成之后,做一次全片一致性检查:
# 对比原片与改后镜像的结构差异,只看偏移和长度,不看内容 python3 check_volumes.py modded.bin python3 dump_microcodes.py modded.bin > mc_new.txt python3 dump_microcodes.py stock.bin > mc_old.txt diff mc_old.txt mc_new.txt第一条命令确认卷头全部正常;后三条用来对比微码清单,输出里应该只多出你要加的那几个 CPUID,原有的一个都不能少。如果 diff 结果里出现原有微码的版本号变了或者消失了,说明替换过程中把别的块也带走了,得回退重做。
封装完成后还有一个隐蔽的坑:整片镜像的尾部可能有厂商自定义的数据块,某些板子的启动流程会去校验它。这部分如果被你的回填覆盖了,现象是第一次能点亮,断电再开就起不来。判断方法是把改后镜像和原片做逐字节对比,确认改动只发生在 BIOS 区范围内。
4.4 引脚处理与首次点亮验证
固件准备好了,还有一步硬件侧的处理常常被忽略。新老平台的处理器在插槽上有几个引脚的功能定义不同,某些检测引脚如果原样接触,主板会判定为不支持的处理器直接拒绝上电。常见的做法是用绝缘胶带把那两个引脚对应的触点贴住,位置要精确,贴错一个针脚范围可能影响内存通道。
这一步我不建议凭记忆做,一定要拿处理器底面的引脚图和插槽定义图对着看,用放大镜确认位置,贴完再复核一遍。见过太多因为贴错位置导致内存只认单通道、或者干脆不亮的例子,然后回头排查固件,白折腾好几天。
首次上电的验证顺序是:先不接硬盘、只插一条内存,看能不能过自检出画面;能出画面再关机插满内存;再进系统看设备管理器里 CPU 型号和核心数是否识别正确;最后跑个负载看会不会突然断电。每一步都记下现象,出问题时这些记录就是排查依据。
提示:第一次上电如果风扇转但无显示,先别急着拆芯片,等够三十秒。有些板子首次初始化内存训练耗时较长,提前断电反而会被误判为失败。
5. 避坑与排查:点不亮、反复重启、进系统掉电的现场还原
这一章把踩过的坑按现象归类,每条都写清楚怎么判断、为什么、怎么解。
5.1 现象:通电风扇转,屏幕始终无信号
原因通常有三层。最外层是微码没加载上,处理器停在早期初始化阶段;中间层是管理引擎区初始化失败,上电时序卡住;最内层是描述符表的偏移被改坏了,固件根本读不到 BIOS 区。
排查顺序从外往里:先把改后镜像和原片做逐字节对比,确认改动范围只在 BIOS 区内,描述符表那一小段必须一个字节都没变。然后单独验证微码——把微码文件换回原厂版本,其他修改保留,刷进去试。如果这样能点亮,说明问题出在微码块本身,多半是 CPUID 或平台标志位对不上。
如果换回原厂微码还是不亮,就怀疑管理引擎区。办法是临时把管理引擎区换回原厂的,只保留微码修改,再试一次。两次对照就能把问题锁死在哪一块。
5.2 现象:能点亮,但反复重启三四次后才进系统
这是典型的配置不匹配。固件在启动过程中做了某种自纠正,失败一次就重启换个参数再试,试到某个组合能过为止。出现这种情况说明你的修改「差不多对但没完全对」。
最常见的原因是内存相关的配置项和新 CPU 的内存控制器参数不一致。解决思路不是继续猜参数,而是把原厂固件里与内存初始化相关的那几个模块也一并替换成新平台对应的版本——很多时候魔改包不只需要微码,配套的初始化模块也得跟着走。
另一个可能是供电相关的限制项没调。某些板子默认的电流上限对新 CPU 来说太低,固件检测到超限就重启降档。这类问题在系统里看不出来,只能通过替换配置项来验证。
5.3 现象:进系统正常,一跑满载就断电
断电而不是降频,说明触发了硬件保护。两种情况:一是供电相数确实不够,新 CPU 的瞬时电流超过了板子的承受能力;二是固件里的保护阈值被设得过低,还没到硬件极限就主动切了。
区分办法很简单:进系统后看 CPU 的实际频率曲线。如果断电前频率是逐步下降的,属于软件限流;如果是满频运行几十秒后直接掉电,多半是硬件层面的保护。前者可以尝试调高固件里的限制项,后者只能换 CPU 或者接受降频使用。
老平台上新架构的高核心数处理器,供电是硬约束,改固件改不出供电能力。这一点要提前认清,别在固件上反复折腾。
5.4 现象:系统能进,但某几个 SATA 口或 PCIe 槽失灵
这是 PCH 通道配置没跟上的典型表现。新处理器在芯片组侧的通道划分和老的不同,固件里如果还按老的映射关系配置,就会出现部分接口无响应。
解决办法是找到固件里描述通道映射的配置项,逐项对照新平台的预期值修改。这项工作没有通用答案,必须结合具体板子的走线来。我一般的做法是先只启用最基本的几个接口,确认系统稳定后,再一个一个把剩余接口打开,每打开一个验证一次,出问题时能立刻定位到是哪一项配置有问题。
5.5 现象:刷完第一次能开机,冷启动后彻底黑屏
这种「一次性成功」最迷惑人。原因通常是固件里某个区域在首次启动时被写入了运行时数据,而这块区域在固件里标记为可写但你的镜像把它填成了固定内容,第二次启动读到的是被改写过的数据,校验对不上就拒绝启动。
判断方法是看原片里这块区域的内容是不是全 0xFF。如果是,说明它是留给运行时写入的,你的修改不应该覆盖它。解决方法是回填的时候把这块区域保持原样,或者把它标记为擦除态。
还有一种可能是备份固件区被触发了。部分板子在检测到主固件异常时会自动从备份区恢复,如果你的备份区也被刷成了魔改版本,恢复流程就会把问题放大。改固件时务必确认主备两区的处理策略。
6. 进阶:把一次魔改变成可复现的固件资产
单次改成功不算本事,能重复改成功才算。我现在的习惯是每做一块板子,都建一个独立目录,里面固定放四样东西:原厂镜像、改后镜像、修改记录、验证结果。修改记录不是写「改了微码」这种废话,而是精确到「偏移 0x3A2000 处的微码文件,原有 CPUID 0x506E3 保留,新增 0x906EA 与 0x906EC,文件长度由 0x3400 变为 0x4C00,所在卷头校验由 0x1A2B 重算为 0x0F3C」。这份记录的价值在于,半年后你想再改一版,或者别人拿着同型号板子来问,你能直接把差异复现出来。
验证结果这一项很多人省掉,其实最该留。我的做法是每次刷完跑同一组固定检查:自检耗时、内存识别容量与通道数、系统里 CPU 型号与核心数、满载十分钟的频率曲线、断电重启三次是否稳定。这五项记成一行文本,和镜像文件放在一起。时间长了你会发现,某些型号的板子在第三项上总是有偏差,那说明这个型号的微码替换方案还有问题,下次就不用重复踩。
更进一步的做法是把校验环节脚本化,做成一条命令跑完全部检查:
#!/usr/bin/env bash # verify.sh —— 对改后镜像做一次完整体检 set -e IMG="$1" echo "[1/4] 卷头校验" python3 check_volumes.py "$IMG" | grep -c 'OK' || true echo "[2/4] 微码清单" python3 dump_microcodes.py "$IMG" echo "[3/4] 与描述符表长度比对" python3 - "$IMG" <<'PY' import sys, struct data = open(sys.argv[1], 'rb').read() # 描述符表区域行固定从 0x10 开始,共 5 行,每行 4 字节 for i in range(5): base, limit = struct.unpack_from('<HH', data, 0x10 + i * 4) if base == 0 and limit == 0: continue print('区域 %d 起始 0x%05X 长度 0x%05X 结束 0x%05X' % (i, base << 4, (limit + 1) << 4, ((limit + 1) << 4) + (base << 4))) PY echo "[4/4] 整片哈希" sha256sum "$IMG"这段脚本把四件事串起来:卷校验数量、微码清单、区域表解析、整片哈希。描述符表里每个区域用「起始的高 16 位 + 长度的高 16 位」表示,实际地址要左移 4 位,这是很多人第一次读区域表时算错的地方,算错就会误判某个区越界。跑完之后把输出贴进那块板子的记录文件,下次直接对比。
从那以后我每次动固件之前都强制走一遍这套流程,读片两次比对、改前留原片、改后跑体检、刷完记五项。这套动作看着笨,但它把「凭感觉调」变成了「有据可查地调」,翻车的时候能省下大半天。希望帮到你。
本文还有配套的精品资源,点击获取