HTC老机型刷机全链路:S-ON解锁、Recovery覆盖与RUU救砖
发布时间:2026/11/3 22:06:13 锦皓数字建站

1. 抽屉里那台老 HTC真正的门槛从来不是“解锁”这一步每年总有那么几次会有人抱着一台屏幕已经有点发黄的老机器来找我说想把它救活。型号多半是 One 系列、Desire 系列或者 Butterfly——这些机器放在今天连当备用机都勉强但当年确实是一批很有个性的产品。他们的诉求也很统一解锁 bootloader、刷 recovery、刷 ROM把原厂那套早就不更新的系统换掉。我这些年帮人折腾下来最常见的误区就是大家都把注意力全部放在“解锁”上。觉得只要拿到解锁码、跑完那几行 fastboot 命令后面就是顺水推舟。实际情况恰恰相反解锁往往是全流程里最省心的一步真正让人卡住的是解锁之后那台机器开始不听话——recovery 明明刷进去了一重启却变回原厂ROM 包明明刷完了机器卡在开机动画上十几分钟不动或者更极端的刷完之后连 fastboot 都进不去只能当镇纸用。这篇内容我想讲清楚的就是 HTC 这一系列机型从 S-ON 到刷完第三方 ROM 的完整链路。不是那种“复制粘贴六行命令就完事”的速通攻略而是把每一步背后的分区机制、安全标志位、固件匹配逻辑都摊开来讲。因为 HTC 在安卓阵营里算是把“安全限制”做得最重的一批厂商它的 S-ON/S-OFF 双状态、CID/MID 双重校验、固件版本绑定这几层门槛叠在一起形成一个任何一环没对上就会失败的链条。你只有理解了这层结构才知道报错码 160 和 170 的区别在哪才知道为什么有些机型解锁之后依然刷不进 recovery。适合读这篇的人大概分两类。一类是手上正好有一台 HTC 老机器想把它刷活需要一份能照着走的完整流程另一类是对安卓底层分区、bootloader 安全机制感兴趣想拿一台结构清晰的机器当样本研究。两类人的目标不同但需要的底层知识是同一套。我下面会尽量把原理和操作穿插着讲遇到必须动手的地方给出具体命令和预期输出遇到容易翻车的地方单独拉出来说。先说一个总的判断HTC 刷机的难点不在于“会不会敲命令”而在于信息核对。你得先知道自己手上这台机器是什么 CID、什么 MID、固件版本到哪一档这三个信息决定了你能刷什么、不能刷什么。跳过这一步直接开刷后面所有的坑基本都是这么埋下的。1.1 S-ON 与 S-OFF两张不同权限的门禁卡理解 HTC 刷机绕不开 S-ON 和 S-OFF 这对概念。S 指的是 Security本质上是 bootloader 里的一个安全标志位它决定了哪些分区对你开放写入权限。用生活化的说法S-ON 状态下的手机像一栋门禁管理严格的小区你只有自己那一户的钥匙公共区域boot、system、recovery的门是锁死的官方解锁相当于给你办了一张访客卡能进大堂和几部电梯但配电房、水泵房radio、hboot、splash 这些底层分区依然进不去S-OFF 则是给你配了物业总钥匙整栋楼随便走。这三种状态能做的事情差别很大我整理成表更直观权限状态boot 分区system 分区recovery 分区radio / hboot / splash典型用途S-ON 未解锁不可写不可写不可写不可写只能用官方 OTAS-ON 已解锁可写可写可写不可写刷第三方 ROM 的主流状态S-OFF可写可写可写可写刷固件包、改 CID、救砖这里有个关键点很多人没意识到官方解锁得到的是 S-ON 状态下的有限写入权限它并没有把 S 标志位改成 OFF。所以你在 bootloader 界面看到的依然是 S-ON只是多了一行 UNLOCKED。这也解释了为什么解锁之后你能刷 recovery 和 ROM却刷不了 radio 和 hboot——那些分区不在访客卡的授权范围里。S-OFF 在 HTC 的历史上是个敏感话题。早期有通过特定 HBOOT 版本漏洞实现的方案后来主流是通过付费工具或者特定机型的工程模式实现。这块我不展开讲具体手段因为不同批次、不同 HBOOT 版本的路径差异极大而且操作本身风险不低——S-OFF 过程中断电或者操作失误机器变砖的概率明显高于普通刷机。对于绝大多数“我只想刷个第三方 ROM”的需求来说S-ON 加官方解锁完全够用没必要为了追求 S-OFF 去冒额外的风险。这是我个人非常明确的一个建议。1.2 CID 和 MID决定“这个包能不能进”的两道门如果说 S-ON/S-OFF 决定的是“能往哪写”那 CID 和 MID 决定的就是“允许谁写”。MIDModel ID是机型标识比如同一代 One 系列不同地区版本、不同运营商版本的 MID 可能都不一样。CIDCustomer ID是客户标识通常和销售区域、运营商绑定。常见的 CID 形式像HTC__001、HTC__621、CWS__001、T-MOB101这种前面几位基本能看出归属。这两个值在刷 ROM 时的作用体现在 ROM 包的 updater-script 里通常会有一段 assert 校验assert(getprop(ro.product.device) m7 || getprop(ro.build.product) m7); assert(htc_getcid() HTC__001 || htc_getcid() HTC__621);如果你的机器 CID 不在这份白名单里recovery 会直接中断刷入报一个Status 7错误。很多人第一次遇到这个错误会懵以为是包坏了其实是 CID 对不上。查 CID 和 MID 的方法很简单进 fastboot 模式后跑fastboot getvar cid fastboot getvar mid预期输出大概是这样cid: HTC__621 mid: PN0710000把这两个值记下来后面选 ROM 包、判断 RUU 能不能用全靠它们。至于 superCID——把 CID 改成11111111以绕过所有 CID 校验——属于 S-OFF 之后才能做的操作而且改完之后部分官方 OTA 会失效。我一般不建议新手碰这个除非你确实遇到了“找不到对应 CID 的 RUU”这种死局。1.3 固件版本一道看不见但有硬性约束的天花板第三层限制是固件版本。HTC 的 bootloader 和 radio 打包在一起叫固件firmware不同大版本的固件对应的分区布局、boot 镜像格式可能不一样。举个具体例子一台机器如果固件停在 5.x 这一档你直接刷一个要求 7.x 固件的 ROM 包最常见的结果是刷入过程顺利、重启后卡在第一屏白底绿字那个 HTC logo 界面无限循环。因为新 ROM 的 boot.img 里内核期望的分区布局和老固件不匹配内核起不来。查固件版本用fastboot getvar version-main输出类似6.09.401.5。这个号要和 ROM 包说明里要求的固件版本对得上差一个大版本基本就不能刷。所以一个完整的选包逻辑应该是先看版本号能不能对上再看 CID 在不在白名单最后看 MID 是否匹配。三步都过了再动手能省掉后面大量的排错时间。我见过太多人反过来——先下载一个看起来不错的 ROM刷不进去再回头查信息结果查出来是自己的固件版本差了两档白折腾一晚上。2. 开工前的三件事驱动、平台工具、机型信息存档动手之前的环境准备是整个过程里最枯燥但最不能省的部分。HTC 这一系列机器对驱动和 USB 环境的要求比同期很多品牌都要挑剔。我遇到过不止一次“命令没错、包没错就是 fastboot devices 死活不显示设备”的情况最后查出来都是驱动或者 USB 口的问题。2.1 Windows 下的驱动别指望系统自动装Windows 10/11 对安卓设备的通用驱动支持其实还行但 HTC 进 fastboot 模式后的设备标识和正常开机时不一样系统经常会认成一个未知设备。表现就是adb devices能看到机器fastboot devices一片空白。我的做法是手动装驱动路径是设备管理器里找到那个带黄色感叹号的设备右键更新驱动手动指向解压好的驱动目录。驱动来源有两个选择一个是 HTC 官方曾经提供的同步工具里自带的驱动包另一个是通用的安卓 USB 驱动需要手动编辑 inf 文件把 HTC 的厂商 ID 加进去。HTC 的 USB 厂商 ID 是0bb4。在 inf 文件里加一段大概长这样;HTC %SingleAdbInterface% USB_Install, USB\VID_0BB4PID_0FF0 %CompositeAdbInterface% USB_Install, USB\VID_0BB4PID_0FF0MI_01改完之后记得关掉驱动签名强制检查否则装不上。这里还有一个特别容易被忽略的细节别用 USB 3.0 口也别用前置面板的口更别接集线器。HTC 老机型在 fastboot 模式下对 USB 3.0 controller 的兼容性很差插上去大概率识别不稳定表现为命令能发出去但设备中途掉线。我一般固定用主板后置的 USB 2.0 口一条质量好点的短线这个组合的成功率最高。2.2 平台工具的版本不是越新越好安卓的平台工具包platform-tools更新很频繁但新版本对老设备的兼容性反而可能出问题。特别是一些老 HTC 机型在极新的 fastboot 版本下会出现FAILED (remote: unknown command)这种莫名其妙的错误。我自己的习惯是备一份相对老一些的版本专门用来刷这类机器大概在 30 左右的版本号那一档用下来最稳。新版留着刷新机器用。这个不是玄学老版本对老协议的兼容处理确实更宽容。另外提醒一下平台工具解压出来之后建议把整个目录加到系统环境变量里或者干脆把命令都在这个目录下执行。我见过有人把 fastboot.exe 单独复制到桌面用结果因为找不到同目录下的 AdbWinApi.dll 而报错排查了半天。2.3 把机器档案完整存一份下来这一步是我强烈建议所有人都做的在动任何东西之前先把fastboot getvar all的完整输出存成一个文本文件。fastboot getvar all my_htc_info.txt输出里会包含 CID、MID、version-main、imei、serialno、分区大小等一大堆信息。这份文件的价值在于万一后面刷出问题需要救砖你可以拿它去比对 RUU 包的匹配条件万一需要找人求助把这份文件发出去对方一眼就能判断你的机器状态。getvar all的输出里有些字段涉及设备唯一标识分享给别人的时候记得把 imei 和 serialno 那两行删掉。顺带说一句HTC 的getvar all在某些 HBOOT 版本上会有字段截断或者输出乱序的情况属于正常现象不影响使用。3. 官方解锁的完整走法以及那几个卡人的返回码HTC 曾经提供过一条官方的 bootloader 解锁通道流程是注册账号、提交设备标识、等待邮件、刷入解锁令牌。这套流程在当年算是比较开放的但也设置了若干限制条件。虽然现在这条通道的实际可用性因机型而异但流程本身值得完整讲一遍因为里面涉及的 token 机制、返回码含义是理解 HTC bootloader 安全模型的最好样本。3.1 从设备上取出标识 token第一步是在 fastboot 模式下取设备标识fastboot oem get_identifier_token执行后终端会输出一大段以 Identifier Token Start 开头、 Identifier Token End 结尾的内容中间是一堆十六进制字符块。这段内容需要原样完整复制包括起始和结束标记行中间不能有多余的空格或者换行错位。我见过有人复制的时候不小心把某一行合并了提交上去直接报 token 无效。取完 token 之后把它粘贴到官方解锁页面的提交框里。如果设备型号在该渠道的支持列表内几分钟到几小时内会收到一封邮件附件是一个叫Unlock_code.bin的文件。3.2 刷入解锁令牌时屏幕会接管操作拿到Unlock_code.bin之后把它放到平台工具目录下机器保持 fastboot 模式执行fastboot flash unlocktoken Unlock_code.bin这条命令的执行结果和普通 fastboot 命令不太一样——它会先输出发送成功的提示然后手机屏幕上会弹出一个确认界面问你是否确认解锁。这个界面上需要用音量键移动光标电源键确认选择。这个设计当年是为了防止误操作但也坑了不少人有些人在电脑前等了半天没反应以为命令失败了实际上手机屏幕在等他们按电源键。所以执行完这条命令眼睛要盯着手机屏幕不是盯着终端。选择确认之后手机会自动重启并清空所有数据。注意是清空所有数据包括内置存储里的照片文件。这一步没有撤销余地动手之前该备份的一定要备份。3.3 返回码是诊断信息不是故障编号解锁过程中最常遇到的几个错误码含义其实很明确但官方从来不好好解释我按实际遇到的情况整理一下返回码实际含义处理方向Error Code: 160MID 不在该渠道的支持列表该机型不支持官方解锁只能找其他路径Error Code: 170CID 不在支持列表运营商定制机常见需先改 CID要 S-OFFError Code: 130token 校验失败多半是复制粘贴时格式错位重新取一次Error Code: 155设备已是解锁状态无需重复操作Error Code: 159电池电量过低充到 50% 以上再来这里面 170 是最让人无奈的。运营商定制机在出厂时就锁死了 CID官方渠道不给解锁而改 CID 又需要先有 S-OFF形成一个闭环。这类机器的处理路径会复杂很多不是简单几步能解决的。还有一个细节解锁成功之后bootloader 界面会显示*** UNLOCKED ***同时 S 状态依然是 S-ON。很多人看到 S-ON 就以为没成功反复重刷其实已经到位了。4. recovery 刷进去了又“消失”分区覆盖机制与真实原因这是整个流程里最高频的翻车点也是我最想重点讲清楚的部分。现象很统一fastboot flash recovery xxx.img提示成功紧接着fastboot reboot等系统起来之后关机再进 recovery——变回原厂那个简陋的蓝色 recovery 了第三方 recovery 凭空消失。第一次遇到这个现象的人通常会怀疑是镜像文件有问题反复换包重刷折腾半天没有进展。其实这不是刷失败是刷成功了然后被覆盖了。4.1 覆盖机制的来龙去脉安卓系统里有一个机制叫 recovery-from-boot作用是保证系统更新后 recovery 分区能自动恢复成官方版本。具体实现是 system 分区里放了一份官方 recovery 的备份通常叫recovery-from-boot.p在系统启动过程中由某个脚本检测 recovery 分区是否被改动如果改动过就用备份覆盖回去。这个机制的初衷是好的——防止恶意软件替换 recovery。但对刷机的人来说就是个障碍。关键在于触发条件它是在正常启动进入系统时触发的。所以如果你刷完 recovery 之后立刻重启进入 recovery而不是重启进入系统这个覆盖就不会发生。正确的操作节奏是这样fastboot flash recovery twrp.img fastboot boot twrp.img # 部分机型支持直接从内存引导 # 或者刷完后手动断电用组合键直接进 recoveryHTC 大部分机型不支持fastboot boot从内存引导 recovery所以实际操作是刷完之后拔数据线长按电源键强制关机然后按住音量下加电源进 bootloader再用音量键选 RECOVERY 进去。进去之后要做一件事立刻在 recovery 里刷入一个能阻止覆盖的东西或者直接把 system 分区挂载为可写并删掉那个备份文件。TWRP 里通常在高级设置或者文件管理器里能操作路径是system/recovery-from-boot.p和system/etc/install-recovery.sh这两个删掉或者改名都行。4.2 除了覆盖还有两种“recovery 消失”的假象第一种假象是根本没写进去。HTC 部分机型的 recovery 分区有额外的写保护fastboot flash recovery会返回 OKAY但实际上什么都没写。判断方法是刷完之后不要重启直接选 RECOVERY 进去看看如果还是原厂的那就是没写进去。这种情况多见于 S-ON 状态并且 bootloader 版本较新的机器。第二种假象是进了错误的 recovery。有些 HTC 机型在 boot 分区里内置了一个简易的恢复模式当检测到 recovery 分区损坏或者校验失败时会自动跳到这个内置模式。这个界面长得和原厂 recovery 很像容易让人误判。区分方法是看界面上的版本号和菜单项内置模式的菜单通常只有三四项而且没有 adb 支持。4.3 我总结的一套稳定操作顺序折腾了这么多台之后我固定用下面这个顺序成功率最高确认机器已解锁bootloader 显示 UNLOCKED进 fastboot刷入 recovery不重启直接强制关机组合键进 bootloader选 RECOVERY进入 TWRP 后第一件事挂载 system删掉覆盖脚本再做后续的 ROM 刷入操作第 3 步的“强制关机”看起来粗暴但它能确保刷入的 recovery 不被系统启动流程干扰。长按电源键 10 到 15 秒屏幕黑了就松手这个操作对硬件没有损害。还有一点提醒刷 recovery 之前先确认电池电量。HTC 老机器电池老化严重标称 30% 电量可能实际只剩几分钟。在 recovery 里刷 ROM 的过程中断电是变砖的高发场景。我一般要求电量显示在 50% 以上才动手。5. 刷 ROM 的完整链路固件匹配、boot 分区和首次开机刷 ROM 这件事说简单也简单recovery 里点几下就完事。但它包含了最多的隐性条件任何一个条件不满足结果都是同一个——卡第一屏。5.1 S-ON 状态下 boot 分区要单独刷这是 HTC 刷机区别于其他品牌的一个关键点很多人不知道直接导致刷完开不了机。在 S-ON 已解锁的状态下虽然 recovery 有能力写入 boot 分区但部分机型的 bootloader 会在 recovery 环境下对 boot 分区做额外保护导致 ROM 包里的 boot.img 写入失败——而且这个失败是静默的刷机脚本不会报错。结果就是 system 分区更新了boot 分区还是旧的内核和系统版本对不上开机直接卡死。解决办法是刷完 ROM 包之后单独把 boot.img 提取出来用 fastboot 再刷一次# 从 ROM zip 里提取 boot.img unzip rom.zip boot.img # 刷入 fastboot flash boot boot.img fastboot erase cache fastboot rebootfastboot erase cache这一步不要省。HTC 的 cache 分区里存着上一次启动的一些状态数据跨版本刷机之后不清 cache很容易出现开机动画循环或者应用频繁崩溃。5.2 双清清的是哪几个分区顺序有讲究recovery 里的“双清”这个说法其实不太准确实际操作涉及的分区不止两个。我一般按下面的顺序清Factory Reset / Wipe Data——清 data 和 cache这是必须的Wipe Cache——单独再清一次 cache确保干净Wipe Dalvik Cache——清虚拟机缓存跨版本刷机必做Format System——格式化 system 分区可选但建议做关于最后一项要说一句format system 之后如果没有成功刷入 ROM机器是开不了机的会一直卡在开机界面。所以如果你对自己的 ROM 包没把握可以先不清 system等确认包能刷成功之后再考虑彻底格式化。另外清 data 会删掉内置存储里的所有东西包括你自己放进去的 ROM 包。所以刷机包要放在外置 SD 卡上或者刷之前先确认包在哪个分区。这个错误我见过太多次了清完 data 发现包没了只能重新拷。5.3 首次开机慢到什么程度算正常刷完 ROM 第一次开机需要重建 dalvik 缓存、初始化应用数据耗时明显长于日常开机。一台老 HTC 上这个过程花 5 到 15 分钟都算正常。判断标准是看开机动画有没有在动。如果动画在循环播放说明系统还在初始化耐心等如果画面完全静止、卡在某个画面不动超过 20 分钟那就是有问题了大概率是 boot.img 不匹配或者固件版本对不上。遇到卡死的情况我的排查顺序是先确认固件版本和 ROM 要求是否一致再确认 boot.img 有没有单独刷过最后才怀疑 ROM 包本身有问题。顺序很重要因为前两个原因占了绝大多数。还有个小技巧如果机器支持 adb卡开机的时候可以尝试adb logcat看内核日志。能连上说明 adb 服务起来了日志里通常会直接写明是哪个分区挂载失败比盲目试错高效得多。6. 变砖抢救RUU、rebootRUU 和返回码对照刷机刷到进不去系统、也进不去 recovery只剩 fastboot 能用的状态行话叫“半砖”。这种状态其实还有救只要 fastboot 还认设备通过 RUU 恢复官方固件的成功率很高。RUU 是 HTC 官方发布的完整固件包包含 bootloader、radio、system 所有分区。它的限制条件很明确CID 和 MID 必须完全匹配固件版本不能低于当前版本部分情况可以同版本刷。6.1 从 RUU 可执行文件里把 rom.zip 掏出来官方 RUU 通常是一个 exe 自解压程序直接运行会走图形界面但那个界面在老机器上失败率很高。更可靠的做法是把里面的 rom.zip 提取出来手动刷。提取方法运行 RUU exe等它解压到临时目录后通常在你用户目录的临时文件夹下会生成一个名字很长的随机目录把里面的rom.zip复制出来。如果 exe 运行到一半就报错退出可以在它解压的瞬间去临时目录里找动作要快。拿到 rom.zip 之后确认一下包里的android-info.txt里面写着这个包要求的 CID 和 MIDmodelid: PN0710000 cidnum: HTC__001 cidnum: HTC__621 mainver: 6.09.401.5对照你自己记下来的机型档案能对上才能刷。6.2 为什么同一个包要刷两遍手动刷 RUU 的流程是这样fastboot oem rebootRUU fastboot flash zip rom.zip第一条命令会让手机进入一个黑底银字的 RUU 模式。第二条命令刷入时第一次执行大概率会在中途返回FAILED (remote: 90 hboot pre-update!)。这个 90 不是错误是提示。它的意思是 hboot 部分已经更新完成需要重新执行一次刷写来继续处理剩下的分区。所以看到 90 不要慌再跑一遍同样的命令fastboot flash zip rom.zip第二次会完整跑完最后输出OKAY。然后执行fastboot reboot如果两次都返回 90那可能是包和机型不匹配需要回头检查 CID/MID。6.3 常见返回码与症状对照返回码 / 症状可能原因处理方式90 hboot pre-update正常的分段更新提示重新执行一次 flash zip12 signature error包签名校验失败包被修改过换官方原始包41 model id check failMID 不匹配换对应机型的包42/43 CID check failCID 不在白名单换对应 CID 的包或先改 CID99 unknown fail分区写入异常检查 USB 连接换线换口重试刷完卡第一屏boot.img 与 system 版本不匹配单独刷对应版本的 boot.img进不了 recovery 但能进系统recovery 被覆盖见第 4 节的覆盖处理最后说一个我自己的经验。老机器的 eMMC 闪存经过这么多年坏块概率明显上升。如果同一个包反复刷都在同一个进度百分比失败而且换包换线都一样那要考虑是不是闪存本身出问题了。这种情况下再怎么折腾软件层面都是徒劳的唯一的办法是接受它当前的系统版本或者换一块主板。还有一种情况值得单独提有些机器刷完之后能开机、能用但基带没了表现为无信号、IMEI 显示未知。这一般是 radio 分区在刷写过程中被意外擦除。S-ON 状态下没法直接刷 radio只能通过对应版本的 RUU 整包恢复。所以刷 ROM 之前把 RUU 包先下载备好这个习惯能救不少急。折腾这类老机器说到底是个信息核对和耐心的活。命令本身没几条难的是知道每条命令背后动了哪个分区、为什么必须按这个顺序。我自己这些年刷下来最深的体会是动手前花二十分钟把 CID、MID、固件版本、分区布局查清楚能省掉后面两小时的排错。急着按教程复制粘贴的人最后往往要花更多时间在“为什么我不一样”这个问题上。至于那些实在救不回来的机器也别太执着它们该退休了。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。