背景

有一台欧版的小米 17 Ultra,安装国行 OS4,但遇到了麻烦:

  • 使用 OS4 CN17 原版基带,系统可以启动,但无法识别 SIM 卡
  • 换入 OS3 EEA17 基带后,设备无法进入第二屏,第一屏后黑屏或卡死
  • Recovery 仍然可以进入,因此启动链没炸

涉及的主要版本如下:

用途版本Android 大版本
EEA 基带来源OS3.0.332.0.XPAEUXM17
CN 系统OS4.0.0.10.XPACNXM17
交叉验证来源OS3.0.303.0.WPAEUXM16

此前已知 OS3 EEA Android 16 的基带可以用于 OS3 CN Android 16,但同一份 EEA16 基带放到 OS4 CN17 上无法开机。这意味着问题不太像单纯的 Android 版本差异,更可能来自 OS3 到 OS4 之间的底层固件布局变化。

调查

分区:modem.img 与 modemfirmware.img

  • modem.img 包含范围更广的固件内容。实际比较中,EEA17 与 CN17 在 ADSP、CDSP、可信应用、IPA GSI 等组件上都有大量版本差异
  • modemfirmware.img 是 FAT16 文件系统,内部 /image 目录包含 MPSS 主体、modem DTB、MCFG 和射频相关配置

恢复 CN17 的 modem.img、继续保留 EEA modemfirmware.img 后,设备仍然在第一屏崩溃。这一步把开机失败进一步缩小到了 modemfirmware.img。

最终方案因此选择保留 OS4 CN17 的 modem.img,只对 modemfirmware.img 做针对性混合。

diag 给出的决定性证据

连续多次启动生成的 last_kmsg 都在开机约 16~18 秒时出现相同错误:

qcom_q6v5_pas 4080000.remoteproc-mss: fatal error received:
modem_ac.c:293:Access Control Error: Could not protect the region specified:
Start:84a00000 End:89f00000, Ret:8

随后 MPSS remoteproc 崩溃并尝试恢复,最终触发 Apps watchdog。也就是说,真正阻止开机的不是后续的 Android Framework、SELinux 或普通 init 警告,而是 Qualcomm modem 在启动阶段申请受保护内存失败。

对 EEA17 和 CN17 的 modem_dtb 做语义比较后,核心差异只有三项:

字段OS3 EEA17OS4 CN17
DSM 起始地址0x84a000000x85000000
DSM 大小0x055000000x04f00000
OEMPD carveout0x00c000000x00600000
DSM 结束地址0x89f000000x89f00000

CN17 把 DSM 起点向上移动了 6 MiB,同时把 OEMPD carveout 缩小了 6 MiB。EEA DTB 仍然尝试保护从 0x84a00000 开始的旧区域,而 OS4 CN17 所搭配的安全固件/内存分配不再接受这个范围,于是返回 Ret:8。

用 EEA16 做交叉验证

为了排除“只是 EEA17 基带自身有问题”,又从 EEA16 的 MODEM-FW.bin 中提取了 modem_dtb.b01。

结果是 EEA16 和 EEA17 的 modem_dtb.b01 逐字节完全相同,而 CN17 的版本不同。相同的 EEA DTB 在 OS3 CN16 上可用、在 OS4 CN17 上失败,进一步证明兼容性边界发生在 OS3 与 OS4 的安全固件/内存布局之间,而不是 Android 16 与 Android 17 之间,也不是 EEA17 的偶发回归。

为什么 CN17 原版能开机,却显示无 SIM

CN17 原版 modem.img + modemfirmware.img 不会触发上述 DSM 崩溃,但 Radio 日志呈现的是另一种故障:

  • vendor.peripheral.modem.state=ONLINE,MPSS 表面上已经在线
  • qcrild 和 qcrild2 都在运行,双 IMEI 也存在
  • 设备正确识别了物理区域:ro.boot.hwc=GL、persist.vendor.radio.hwc=GL
  • persist.radio.skhwc_matchres=MATCH,并非简单地把 EEA 硬件误判为 CN
  • 两路 Radio HAL 从启动开始就报告 UNAVAILABLE
  • 日志中没有出现真正的 GET_SIM_STATUS 请求
  • RADIO_POWER on=true 等待数分钟后以 SYSTEM_ERR 失败
  • vendor.radio.qcril_pre_init_lock_held=1 长时间没有释放

因此 UI 中的“无 SIM”不是一次真实的 SIM/ATR 检测结果。Radio 栈在进入 UIM 读卡流程之前就没有完成核心 QMI 预初始化,Telephony 只能在收到 RADIO_UNAVAILABLE 后销毁卡状态。

日志中的 QMIClientBase: qmi_client_init_instance failed with error -3 确实表示 QMI 超时,但该日志来自蜂窝安全组件 libCsecClient.so,单凭这一条还不足以把它认定为唯一根因。

CN 系统中的 NTN/卫星相关报错也是一个干扰项。使用 JADX 反编译 xiaomi-telephony-common.jar 后确认,ModemSarPreInit 找不到 device_ntn_sar_config.xml 时只会记录错误并返回,不会持有 QCRIL 初始化锁,也不会终止电话服务。

综合来看,CN17 的 modem payload 能配合 OS4 的安全内存布局启动,但不能在这台 EEA 物理设备上完成可用的 Radio/QMI 初始化;EEA payload 适合物理硬件,却携带了 OS3 的旧 modem DTB。两边各缺一半。

修复

混合方案

最终组合如下:

组件来源原因
modem.imgOS4 CN17保持 OS4 相关的整套外围固件版本
modemfirmware.img 主体OS3 EEA17保留 EEA MPSS、RF、MCFG 和硬件适配内容
modem_dtb.* 签名元组OS4 CN17使用 OS4 能接受的 DSM/OEMPD 内存布局

需要整体移植下面四个文件:

/image/modem_dtb.mdt
/image/modem_dtb.b00
/image/modem_dtb.b01
/image/modem_dtb.b02

不能只修改 b01 中的地址,也不建议只替换单个分段。Qualcomm 的 .mdt 包含分段信息、哈希和签名关系;直接修改 DTB 字节会破坏内部认证。整体复制 CN17 原厂签名元组则可以保留这条内部信任链。

重打包

两个 modemfirmware.img 都是 FAT16 文件系统。先从 CN17 镜像中完整提取 modem_dtb 四件套,再使用 mtools 检查 EEA17 镜像中对应文件的簇链:

mcopy -i cn17-modemfirmware.img ::/image/modem_dtb.mdt ./cn17/
mcopy -i cn17-modemfirmware.img ::/image/modem_dtb.b00 ./cn17/
mcopy -i cn17-modemfirmware.img ::/image/modem_dtb.b01 ./cn17/
mcopy -i cn17-modemfirmware.img ::/image/modem_dtb.b02 ./cn17/

mshowfat -i eea17-modemfirmware.img ::/image/modem_dtb.b00
mshowfat -i eea17-modemfirmware.img ::/image/modem_dtb.b01
mshowfat -i eea17-modemfirmware.img ::/image/modem_dtb.b02
mshowfat -i eea17-modemfirmware.img ::/image/modem_dtb.mdt

这两个版本中的四个文件长度一致,因此可以根据 FAT 参数和簇链计算各文件在镜像中的位置,原位覆盖文件内容。这样无需重建文件系统,也不会重新分配簇或改变目录项:

cp eea17-modemfirmware.img modemfirmware-hybrid.img

dd if=cn17/modem_dtb.b00 of=modemfirmware-hybrid.img \
  bs=1M seek=<重新计算的位置> oflag=seek_bytes conv=notrunc

dd if=cn17/modem_dtb.b01 of=modemfirmware-hybrid.img \
  bs=1M seek=<重新计算的位置> oflag=seek_bytes conv=notrunc

dd if=cn17/modem_dtb.b02 of=modemfirmware-hybrid.img \
  bs=1M seek=<重新计算的位置> oflag=seek_bytes conv=notrunc

dd if=cn17/modem_dtb.mdt of=modemfirmware-hybrid.img \
  bs=1M seek=<重新计算的位置> oflag=seek_bytes conv=notrunc

完整性与启动链校验

生成后做了三层检查:

  1. 从成品中重新提取四个 modem_dtb 文件,确认与 CN17 原件逐字节一致。
  2. 比较 EEA17 原图和混合图,确认变化只发生在四个目标文件的内容范围内。
  3. 遍历 FAT 文件系统,确认目录和文件均可正常读取。

关于启动链:

  • avbtool info_image 确认 modemfirmware.img 自身没有 AVB footer
  • OS4 CN17 的 vbmeta.img 和 vbmeta_system.img 中没有名为 modemfirmware 的 Hash/Hashtree 描述符
  • Qualcomm 安全启动仍会检查 modem DTB 内部的 .mdt/.bXX 签名关系,但移植的是 CN17 原始签名元组,没有重新签名或篡改其内容

结论

实机验证表明,这个组合成功跨过了两个原方案各自的故障点:

  • CN17 modem DTB 使用 0x85000000 起始的 DSM 布局,不再触发 modem_ac.c:293 Access Control Error。
  • EEA17 MPSS、RF 和 MCFG 主体继续匹配 EEA 物理硬件,避免了 CN17 原版 Radio 长时间处于 UNAVAILABLE 的问题。
  • OS4 CN17 正常启动,跨区基带适配成功。

这次问题的关键不在“Android 17 基带能否搭配 Android 17 系统”,而在三个彼此独立的兼容面:物理射频硬件、MPSS/HLOS 接口,以及安全世界认可的 modem 内存布局。版本号相同并不能保证三者同时兼容;反过来,只要找出真正变化的边界,也不一定需要把整套旧固件粗暴搬进新系统。

最后修改:2026 年 10 月 04 日
如果觉得我的文章对你有用,请随意赞赏