问题概览
首先说明,其实这个问题并不存在,按下 Power+VolUp 无法进入 Recovery 模式只是因为讯飞在 U-Boot 中把 VolUp 按键映射到了工厂测试模式(mode 17),而不是 Recovery 模式(mode 3),但同时 VolDown 按键被映射到了 Recovery 模式(mode 3)。
所以进入 Recovery 模式只需要先按下电源键 1 秒(等待进入 boot diag),然后按下 VolDown 就可以了。
但是如果你执意要让 Power+VolUp 能够进入 Recovery 模式,那就接着往下看吧。
U-Boot 启动模式体系
启动模式表
| 模式编号 | bootmode 参数 | 加载分区 | 说明 |
|---|---|---|---|
| 2 | (默认) | boot | 正常开机 |
| 3 | recovery | recovery | Recovery 模式 |
| 4 | (logo显示) | (fastboot) | Logo + Fastboot |
| 5 | alarm | boot | 闹钟开机 |
| 6 | charger | boot | 充电模式 |
| 7 | engtest | boot | 工程测试 |
| 8 | wdgreboot | boot | 看门狗重启 |
| 9 | apwdgreboot | boot | AP 看门狗重启 |
| 10 | special | boot | 特殊模式 |
| 11 | unknowreboot | boot | 未知原因重启 |
| 12 | panic | boot | 内核 Panic 重启 |
| 15 | (默认) | boot | 同模式 2(正常开机) |
| 16 | cali | recovery | 校准模式 |
| 17 | factorytest | recovery | 工厂测试模式 |
| 18 | (fastboot) | – | Fastboot扩展 |
| 19 | autotest | boot | 自动化测试 |
| 20 | iq | boot | IQ 测试 |
| 21 | – | – | 可达但没处理函数,13 和 14 直接不可达 |
| 22 | sprdisk | boot | 展讯外部 ramdisk 替换模式 |
| 23 | apkmmi_mode | boot | APK MMI 模式 |
| 24 | upt_mode | boot | UPT 模式 |
你可能会发现表格里没有 mode 1,这是故意的。mode 1 是兜底模式,如果所有检测手段都用尽了还是不知道为什么要开机,就会跳到 mode 1,强制关机。到了不可达的模式也会直接强制关机。
启动模式检测表
| Entry | 检测内容 |
|---|---|
| 0 | 电池电量检测 |
| 1 | check_reboot_mode + sysdump |
| 2 | miscdata 分区启动标志 |
| 3 | misc 分区 recovery 命令 |
| 4 | check_reboot_mode 特殊处理 |
| 5 | 充电器检测 |
| 6 | PC 检测 → 根据通信内容返回不同模式 |
| 7 | USB/充电 → 返回 6 |
| 8 | 硬件按键扫描(EIC) |
| 9 | 正常开机 → 返回 2 |
Entry 8 对应函数执行流程:
- check condition
- 等待 50ms
- 循环最多10次,每次调用 board_key_scan() 检测按键
- 如果检测到按键,调用按键映射函数把按键值映射成模式编号并返回
- 如果没检测到,返回 2(正常开机)
问题所在
跳到 0x9F003D44,在按键映射函数中,可以看到对于 VolUp 键返回的是 mode 17:

把这个伪代码翻译成人能看的:
int sub_9F003D44(int key) {
if (key == 115) return 17; // VolUp → factorytest (mode 17)
if (key == 102) return 4;
if (key == 114) return 3; // VolDown → recovery (mode 3)
return 0;
}
所以这个很好解决,把 MOV W0, #0x11 直接改成 MOV W0, #3 就行:

最后输入修改到原文件然后关闭 IDA Pro 就行,这个问题就这么愉快解决啦!
发表回复