做车机座舱平台调试这几年,我解锁了不少奇怪成就。最离谱的一次,是在一个 SA8838 预研项目上,因为赶工把一个 8295 的 mbn 直接塞进了 8155 的开发板,一分钟不到,板子就变砖了。当时整个实验室都安静了,只有串口工具在疯狂刷 9008 枚举失败的日志。后来我从 EDL 进 9008、用 QFIL 把分区表救回来,又因为 WiFi 打不开发现 QCN 早就不见了,折腾了整整两个晚上。
所以这篇文章我就想把 SA8838、8155、8295 这几个平台上做系统/驱动调试时最常踩的坑,尤其是 EDL 变砖和 QCN 恢复这条链路,好好整理一遍。内容会覆盖平台间差异、高通启动链路、QCN 备份恢复、以及 16 个我实测过的问题和对应的排查思路。不管是刚接触高通车载平台的新人,还是已经在刷机救砖路上反复横跳的老手,看完应该都能少走很多弯路。
1. 平台全景:SA8838、8155、8295 的调试体系
1.1 三颗芯片的定位差异与调试影响
高通这三颗平台在车载座舱里算是最常碰到的了。8155 也就是 SA8155P,第三代座舱平台,7nm 工艺,很多前几年的量产车都在用,QNX Hypervisor 加 Android 的双系统方案非常成熟。8295 也就是 SA8295P,5nm 工艺,GPU 和 NPU 性能比 8155 强了一大截,开始支持更复杂的多屏多域融合,现在不少新车型的主机就是它。SA8838 相对新一些,可以理解成 8295 之后的迭代平台,算力规格继续往上走,但底层的 PBL、XBL、ABL 启动链路没有本质变化。
这块对调试最重要的影响不是性能,而是分区表、镜像格式、签名校验方式可能有差异。SA8838 因为是新平台,早期工程样机的 EDL 烧写逻辑和 8155、8295 会有细节差别,比如 firehose programmer 的固件版本不对会导致无法枚举;8295 的 GPT 分区数量和命名和 8155 也不太一样,如果拿 8295 的 rawprogram0.xml 去刷 8155,分区索引直接错位,轻则开机卡 logo,重则把 bootloader 区域写穿。真实项目里很多“变砖”不是芯片烧了,而是分区表乱了。
另外 NPU 架构这几代也有变化,8155 是 Hexagon 690,8295 升级到了更高算力的 Hexagon,SA8838 又继续加核心。调试 NPU 相关应用时,驱动和固件版本必须和芯片匹配,否则 even 在 Android 侧能起来,进了 QNX 侧跑模型还是会崩。这些差异决定了一个原则:同一个刷机包,绝对不能跨平台混用。
1.2 调试环境与工具链:不只是 QPST 和 QFIL
高通车载调试常用的工具其实就那几样,但版本搭配很讲究。Qualcomm USB Driver 是基础,QPST 2.7.496 配合 QFIL 是刷机救砖的主力,QXDM 用于抓 NV 和 RF 日志,QACT 做 RF 校准的时候会用到。再往上就是 CAF kernel 源码、QNX SDK、以及各 Tier1 自己的编译工具链。开源这边 bkerler 的 edl 工具链也挺好用,适合做脚本化烧写,但车规项目里我一般还是以 QFIL 为准,因为生产端和售后端都认这个流程。
很多新人会把 QPST 和 QFIL 混着说,其实 QFIL 是 QPST 套装里的一个独立工具,专门通过 9008/EDL 端口做镜像烧录和 QCN 备份恢复。它不依赖设备能不能进 Android 或 QNX,只要 SoC 的 PBL 还活着,就能通过 USB 枚举出 9008 端口来做底层救援。这也是为什么 EDL 模式是整个救砖链路里最核心的一环,只要 9008 能出来,大部分砖都还有救。
还有一点容易被忽略:调试主机上如果有多个版本的 QPST、多个版本的 usb_driver 混装,设备枚举会非常不稳定,可能出现“QPST 能看见但 QFIL 刷一半断连”这种问题。我的习惯是准备一台专门的 Windows 调试机器,不装其它手机助手类软件,USB 驱动固定在某个版本,实测下来省掉很多玄学问题。
2. EDL 变砖:救砖之前的底层逻辑
2.1 高通启动链路:PBL、XBL、ABL 的分工
要理解变砖和救砖,先要捋清楚高通平台的启动顺序。SoC 上电后最先跑的是 PBL,也就是 Primary Bootloader,它固化在芯片内部 ROM 里,出厂就写死了,正常情况下没法改。PBL 负责初始化最基础的硬件,然后在外部存储里找下一级 bootloader,也就是 XBL(eXternal Boot Loader)。XBL 和 SBL 相关概念经常一起出现,在现在的高通平台上一般指 XBL,存储在 boot 分区里,负责 DDR 初始化、存储初始化、安全启动校验等。
XBL 跑起来之后加载 ABL,也就是 Application BootLoader,它其实是一个 UEFI 应用,负责读取开机按键状态、显示开机 logo、加载 Hypervisor 和后续系统。ABL 之后才是 QNX Hypervisor,再由它拉起 QNX 实时系统、Android 系统或者 Linux 系统。PBL 和 XBL 的区别可以简单理解成:PBL 是芯片里的“开机只读固件”,XBL 是存储里的“外置引导程序”,一个改不了,一个能刷坏。
这也解释了为什么 EDL 模式这么重要。当 PBL 发现存储里没有可信的 XBL,或者检测到特定的 EDL 触发条件时,它不会继续往下引导,而是直接进入 Emergency Download Mode,通过 USB 枚举出一个 9008 端口,等待主机发送 programmer(也就是 firehose 固件)来接管后续操作。所以 EDL 其实不是高通专门设计的“救砖后门”,而是 PBL 一条保底的下载通道。
2.2 EDL 模式进入与验证
上车规平台,进入 EDL 最常见的方法有这么几种。第一种是硬件短接,开发板上基本都会预留 EDL 测试点,有的是两个裸露焊盘,有的是一个按键,短接或按住的同时上电,设备就会进入 EDL。第二种是软件命令,如果系统还能起来,adb 里执行adb reboot edl,或者在 fastboot 里执行fastboot reboot edl,也可以直接切到 EDL。第三种是刷机工具触发,QFIL 通常在检测到 9008 后才会真正开始刷写。
进入 EDL 之后怎么验证?最简单就是打开设备管理器,看到端口下面出现Qualcomm HS-USB QDLoader 9008,或者类似的 9008 端口,说明 PBL 已经在等待下载了。如果设备管理器里出现的是QUSB_BULK或者未知设备,那说明驱动没认上,需要手动指定驱动目录安装 Qualcomm USB Driver。
有一点要提醒:进入 EDL 后不要立刻拔线或者断电,尤其不要在半分钟内反复插拔。因为有些平台的 PBL 进入 EDL 后还要做存储初始化,过早断电可能出现 EDL 状态没写完整的情况,导致下次上电直接进快速启动失败。遇到这种情况,重新插拔一般能恢复,但次数多了对 UFS 也有压力。
2.3 变砖的本质:从 GPT 到 Secure Boot
变砖这件事,听起来很吓人,但绝大多数情况不是硬件损坏,而是引导链断了。最常见的变砖原因有三个:GPT 分区表被破坏、XBL 或 ABL 镜像被写坏、secure boot 校验失败。GPT 分区表相当于整块存储的目录,如果它坏了,后续所有分区都找不到,系统自然起不来。XBL 被写坏则更直接,PBL 找不到有效的下一级引导程序,只能停在 EDL 或完全不响应。
Secure Boot 是一个常见的坑。很多车规项目的板子默认开启了 secure boot,也就是 XBL、ABL、Hypervisor 镜像都需要通过高通签名验证。如果刷入了没有正确签名的镜像,启动时会直接卡在Image authentication failed,看起来也是变砖,但实际硬件完全正常。这时候不能盲目重刷,要先确认当前板子的 secure state 是 locked 还是 unlocked,再决定用签名镜像还是先解锁。
救砖的逻辑也因此清晰了:恢复的目标不是“重装系统”,而是先把引导链恢复完整。也就是先通过 9008 烧入正确的 GPT 分区表,再烧入 XBL、ABL 等 bootloader 相关镜像,确保 PBL 能把下一级引导跑起来,然后继续烧 Hypervisor 和用户系统。只要这个链路恢复了,后面的问题就好解决。
3. QCN 恢复:系统能启动才是第一步
3.1 QCN 文件里到底是什么
很多人在板子能开机之后就以为大功告成,结果发现 WiFi 打不开、蓝牙搜不到设备、MAC 地址全是 00:00:00:00:00:00,这才意识到 QCN 丢了。QCN 是高通的 NV 配置备份文件,里面存的是 RF 前端校准数据、WLAN/BT 的 NVM 参数、MAC 地址、以及和硬件强相关的射频配置。在车机上,QCN 里最关键的其实就是 WiFi 和蓝牙的校准数据,以及 SoC 对应模组的物理地址。
QCN 和 modem 的 NV 项有直接关系,虽然车机不像手机那样依赖 IMEI,但 WLAN/BT 的 MAC 地址就存在 EFS 分区对应的 NV 项里。刷机过程如果格式化了 persist 分区,或者擦除了 EFS,QCN 里的关键信息就没了。另外有些刷机包里的 fastboot 脚本会主动 erase persist,本意是清掉 Android 侧的缓存数据,但误操作之下很容易把 RF 相关的校准数据一起清掉。
这里有个容易混淆的点:QCN 文件并不是系统镜像的一部分,它属于板级个性化数据。每块板子的 QCN 理论上都不一样,因为无线校准结果和 MAC 地址是出厂写入的。所以同一个刷机包可以量产几百块板子,但 QCN 不能像 system 镜像一样通用烧写。
3.2 备份 QCN 的时机和操作
我的习惯是拿到一块新板子,第一件事不是跑分或者连调试工具,而是先备份 QCN。具体操作:让板子进入 EDL 模式,打开 QFIL,在 Tools 菜单里选择 QCN Backup,选择一个保存路径,工具会自动读取板子的 NV 配置并保存成一个 .qcn 文件。整个过程大概十几秒,比后面出了问题再折腾一晚上划算太多。
备份的文件命名一定要规范,我的建议是“项目名+板子序列号+日期”,比如A18_SN12345_20250115.qcn。千万不要用backup.qcn这种名字,因为一旦项目里有多块板子,三个月后你根本分不清哪个文件对应哪块板。更规范一点的做法是建一个 QCN 备份目录,每块板子一个子目录,里面同时放一份硬件版本记录和刷机包版本记录。
如果板子比较多,也可以写一个小脚本去调 QFIL 的命令行接口做自动化备份,但前提是 QFIL 版本要稳定、USB 枚举要可靠。手动备份虽然慢一点,但胜在稳定,我自己在项目初期都是手动备份关键板子,等到 SOP 跑顺了再考虑脚本化。
3.3 QCN 恢复的完整流程
QCN 恢复和备份一样,必须通过 9008 端口操作。先把板子进入 EDL,让 QFIL 识别到设备,然后在 Tools 菜单里选择 QCN Restore,选中之前备份的 .qcn 文件,点击开始。恢复完成后不要急着拔线,正常重启一次,让系统重新读取 NV 配置并写入到 EFS 分区,再检查 WLAN MAC 地址是否已经恢复正常。
恢复过程中有几件事需要特别注意。第一个是版本匹配,QCN 文件必须和当前板子的硬件版本、模组型号一致,否则即使恢复了,WiFi 信号强度可能异常、蓝牙连接不稳定,比不恢复还难排查。第二个是路径问题,QFIL 对中文路径和长路径支持不是很好,QCN 文件路径最好全英文,目录层级不要太深。第三个是恢复后的确认,不要只看 WiFi 能不能打开,最好用 RF 测试仪或者至少用ip link/hcitool确认 MAC 地址和信号底噪是否正常。
如果 QCN 没有备份,也不是完全没有办法。可以从同型号、同硬件版本的另一块正常板子上备份一份 QCN,然后恢复到目标板子上。这样做 MAC 地址会变成和源板卡一致,对于功能验证场景可以接受,但如果设备要量产或者需要唯一 MAC,还得走产线的校准流程重新生成。
4. 16 个实战问题排查实录
下面这 16 个问题,都是我在 SA8838、8155、8295 平台调试过程中实测遇到的,对应现象和处理思路整理成了一个速查表,方便大家直接对照。
| 编号 | 典型现象 | 常用解决方向 |
|---|---|---|
| 1 | 设备管理器看不到 9008,只看到 QUSB_BULK | 手动安装 Qualcomm USB 驱动,换线换口 |
| 2 | QFIL 卡在 Sahara protocol,报错 90/91 | 确认 programmer 选对,重新枚举设备 |
| 3 | 刷写中断,设备完全无响应 | 换短粗 USB 线,独立电源,重新进 EDL |
| 4 | 跨平台误刷后 GPT 错乱 | 用对应平台 programmer 重新烧分区表 |
| 5 | 刷完卡在 fastboot,无法进入系统 | 检查 boot/dtb/vbmeta 是否烧全 |
| 6 | UFS 写入 timeout,报 ECC 错误 | 擦除 UFS 重烧,检查供电稳定性 |
| 7 | QNX Hypervisor 起不来,启动卡 logo | 确认 OS 镜像和 hypervisor 版本匹配 |
| 8 | QNX 串口无输出 | 检查 UART 波特率和调试口定义 |
| 9 | Camera 闪退,camx 报 CSL buffer 错误 | 检查 csid/csiphy 配置,清 persist |
| 10 | 修改 DTBO 后触摸屏失效 | 检查 i2c 控制器和 gpio 中断配置 |
| 11 | WiFi/蓝牙 MAC 变成 00,无法打开 | 恢复 QCN,或从同型号板子备份恢复 |
| 12 | 重启后时间重置,modem 异常 | 重新烧 persist,确认 EFS 分区 |
| 13 | QPST 能看见但 QFIL 不稳定 | 统一 QPST/QFIL 版本,重装驱动 |
| 14 | secure boot 开启,镜像验证失败 | 检查 secure state,刷签名镜像 |
| 15 | 量产机没有 EDL 测试点 | 软件方式进 EDL,如 reboot edl |
| 16 | WLAN/BT 恢复后信号异常 | QCN 与硬件版本匹配,重新校准 |
4.1 刷机与救砖阶段的 6 个问题
问题 1:设备管理器看不到 9008,只看到 QUSB_BULK。这是典型的驱动没装好。Qualcomm 驱动如果没正确安装,设备会以未知设备或 QUSB_BULK 形态出现,9008 端口没有正常枚举出来。解决方法是右键设备,选择更新驱动,手动指向 Qualcomm USB Driver 所在目录,注意勾选“始终信任来自 Qualcomm 的软件”。如果手动安装后还是不行,可以换一个 USB 口,有些主板的前置 USB 口供电不稳定,会导致枚举失败。
问题 2:QFIL 卡在 Sahara protocol,报错 90 或 91。这个报错一般出现在 QFIL 刚开始连接设备、准备发送 programmer 的阶段。常见原因是 programmer 文件选错,比如 8155 的工程选了 8295 的 prog_firehose_ddr.elf,设备不认。另一种情况是设备在 Sahara 模式下等待超时,解决方法是拔掉 USB 线,重新进入 EDL,再重新打开 QFIL。注意 QFIL 的 log 窗口会提示它在等待什么文件,仔细看报错信息比乱试更高效。
问题 3:刷写中断,设备完全无响应。刷到一半断电、USB 线接触不良、镜像文件本身不完整,都可能造成中断。中断之后最怕的是 GPT 写了一半,设备可能连 9008 都进不去。我的经验是先按住 EDL 键再上电,强制让 PBL 进入下载模式,然后用一根短粗的 USB 线重新刷。镜像文件在刷之前一定要校验 MD5,尤其是从网盘或者同事那边拷来的包,不校验就是在赌运气。
问题 4:跨平台误刷后 GPT 错乱。这篇文章开头提到的事故就是这个问题。不同平台的 GPT 分区布局不一样,用 8295 的 rawprogram0.xml 刷 8155,分区表索引整体偏移,bootloader 区域可能被写进别的数据。处理方式是在 9008 模式下,用对应平台的 programmer 重新烧写 GPT 分区表,再烧 bootloader 和系统镜像。关键点:programmer、rawprogram0.xml、patch0.xml 这三个文件必须来自同一个平台同一套发布包,不能混搭。
问题 5:刷完卡在 fastboot,无法进入系统。烧写完成后重启,串口停在Fastboot: processing commands,一般是 boot 或者 dtbo 分区没写对。有些刷机包会把 boot 和 dtbo 合成在一个镜像里,有些是分开的,如果漏烧了 dtbo,内核可能起不来。还有一种情况是 vbmeta 校验失败,需要确认当前镜像是不是签名镜像,或者先烧一个关闭 verity 的 vbmeta 再验证问题。
问题 6:UFS 写入 timeout,报 ECC 错误。这个问题在长期使用的板子上比较常见,也可能是供电不足导致 UFS 写入异常。QFIL 的 firehose 配置里有 timeout 参数,可以适当调大,但如果是坏块问题,单纯调 timeout 没有意义。做法是先做一次 UFS erase,再重新烧写,如果同一位置反复报 ECC 错误,基本可以判断存储颗粒有问题,换板子比继续耗时间更实际。
4.2 QNX/Android 系统层的 6 个问题
问题 7:QNX Hypervisor 起不来,启动卡 logo。刷完系统屏亮了,但一直停在启动 logo,这种问题多半是 Hypervisor 和 QNX OS 镜像版本不匹配。高通发布的固件包里通常包含 hypervisor、qnx 系统镜像、改配置用的 qcf 文件,这三者必须配套。排查方式是把串口接到调试 UART,看 Hypervisor 打印到了哪一步,如果卡在加载 OS 镜像的路径上,多半是 qcf 里的启动参数和实际分区不匹配。
问题 8:QNX 串口无输出。板子看起来在跑,但串口终端一片空白。先检查波特率,8155/8295 平台默认常用 115200,但有些开发板是 921600。再检查是不是接错口了,很多板子有 main UART 和 debug UART,QNX 的启动日志从 debug UART 出,如果接到 main UART 上自然什么都没有。还有个小技巧:先按一下回车键,如果 QNX 的 shell 已经起来,有可能会刷新出一行提示符。
问题 9:Camera 闪退,camx 报 CSL buffer 错误。Android 侧打开相机应用直接闪退,logcat 里能看到 camx 报 CSL buffer 相关错误。这个方向优先检查 sensor 供电和时钟配置,也就是 dtsi 里 cam_supply 相关的节点。还有一个常见原因是 persist 分区残留了上一版 sensor 配置,清掉 persist 再重启可能就好了。如果还不行,用vendor.qti.hardware.camera.provider@2.x的 service 重启日志定位到具体 sensor 节点。
问题 10:修改 DTBO 后触摸屏失效。触摸屏是走 I2C 的,修改 DTBO 之后触摸没反应,基本是 I2C 控制器编号、中断 GPIO 或者 reset GPIO 配置和实际原理图对不上。先在 Android 侧用dmesg搜 i2c 设备节点,看有没有 probe 失败。没有明显报错的话,量一下中断 GPIO 的电平变化,触摸时有没有跳变。很多时候问题就出在 GPIO 复用的 pinctrl 配置错了,导致中断信号根本没送到 SoC。
问题 11:WiFi/蓝牙 MAC 变成 00,无法打开。这是 QCN 丢失最典型的症状。出现这种问题不要急着刷系统,先检查一下 EFS 分区是否正常,如果 persist 已经被格式化,就先从备份恢复 QCN。没有备份的情况下,从同型号板子备份一个 QCN 过来恢复,至少能让 WiFi/蓝牙功能恢复正常。恢复完记得确认 MAC 地址不再是全 0。
问题 12:重启后时间重置,modem 异常。开机时间回到 1970 年,通常是 RTC 校准数据或 persist 分区里的配置丢失。如果同时还伴随 modem 异常、序列号读取失败,就需要重新烧 persist 分区。烧完 persist 之后进系统,把/misc/vendor下和 modem 相关的缓存目录清掉再重启,让系统重新生成配置。
4.3 驱动、Secure Boot 与环境相关的 4 个问题
问题 13:QPST 能看见但 QFIL 不稳定。这种情况一般是 QPST 和 QFIL 版本不一致导致的,QLoader 驱动被高版本或低版本的服务覆盖,两边识别到的设备状态不一致。解决方法是完全卸载 QPST,重启电脑,再安装一个统一版本的完整套装。装驱动的时候不要在设备管理器里右键更新,直接把 usb_driver 的安装包跑一遍更干净。
问题 14:Secure Boot 开启,镜像验证失败。如果板子开启了 secure boot,刷入非签名镜像会看到Image authentication failed的报错。先通过 fastboot 确认secure: yes还是secure: no,是 yes 就只能刷高通签名的原厂镜像。部分车规平台提供解锁命令,但解锁会清空数据,而且不一定适用于所有项目。所以在项目初期就要确认手里的刷机包是不是签名包,免得刷到一半才发现根本过不了校验。
问题 15:量产机没有 EDL 测试点。量产板为了防水防尘,常常没有引出 EDL 短接点。如果系统还能启动,优先试adb reboot edl,大多数平台是支持这条命令的。如果 adb 不可用但 fastboot 可用,就试fastboot reboot edl。还有一些平台支持在 U-Boot 或者 ABL 阶段通过按键组合进入 EDL,具体要查对应平台的上电时序和按键定义。硬件上彻底没有入口的情况,就只能靠售后工具通过原厂协议进 EDL,这种场景下常规 QFIL 不一定有效。
问题 16:WLAN/BT 恢复后信号异常。恢复 QCN 之后 WiFi 能打开,但信号弱、吞吐量低,蓝牙连接经常断。这个问题大概率是 QCN 里的校准数据和当前模组不匹配。要确认备份 QCN 的源板子和目标板子的 WLAN/BT 模组型号一致,甚至硬件版本号也要一致。如果功能验证能接受,可以先用同型号板子的 QCN 顶着,但要做正式调试或者产测,还是得走一遍完整的 RF 校准流程。
5. 写在最后的避坑底线
把这些经验固化成项目 SOP 之后,后面再刷 SA8838、8295 的板子,基本就不会翻车了。最后说几个我个人觉得最重要的习惯:每次动分区之前,先把当前板子的重要分区和 QCN 完整备份一遍;QCN 文件名必须带板子序列号和日期,别偷懒;桌面上常备一根短粗的 USB 线,充电线看着能用,刷机时容易被坑;调试电源尽量带电流显示,电流异常能提前发现问题;串口模块多备一个,坏一个换一个不耽误进度。
车载平台的调试就是这样,很多问题看起来吓人,但底层逻辑通顺之后,无非就是引导链、分区表、NV 数据这三件事。把这三件事管好,EDL 变砖和 QCN 丢失都不是过不去的坎。