做车载高通平台调试这几年,我最大的感受是:SA8838、SA8155、SA8295这套东西和手机平台虽然同源,但坑的密度完全不是一个量级。之前在实验室里帮人救一块8155开发板,UFS写一半USB线被踢掉,重启后设备管理器里只剩一个带感叹号的Qualcomm HS-USB QDLoader 9008,客户急得直跺脚——好在提前备份过QCN,折腾一晚上把系统拉回来,基带也没丢。类似的场景在这三款平台上是家常便饭,EDL变砖、QCN丢失、串口没输出、CAF kernel编译不过,每一个都能卡掉一批人。这篇就把我实际调过的高通车载平台常见问题梳理成16个实战记录,按从变砖到恢复的完整链路来写,从进EDL、烧录、QCN恢复,到日志抓取、内核与外设调试,都是能直接落到开发板上的实操操作。
1. EDL 变砖的根本原因:不是手一抖,是分区和引导链的底层逻辑
先说清楚一个概念:EDL在设备管理器里的表现是Qualcomm HS-USB QDLoader 9008。这个模式不是高通安卓生态独有的,它在SA8838、8155、8295这些车规芯片上同样存在。EDL模式由芯片内部PBL(Primary Boot Loader)固件触发,PBL烧在ROM里,正常手段根本抹不掉,所以只要芯片没物理损坏,EDL永远是你最后的救命通道。换句话说,变砖不可怕,可怕的是不知道怎么系统性地分析变砖原因,然后走错恢复方向。
1.1 问题1:手动改分区导致SBL1损坏,开机彻底没反应
有一段时间我为了精简8155的system分区,直接在fastboot下fastboot erase system,之后又手滑改了gpt分区表,重启后电流表没反应,屏幕黑屏,只有9008端口弹出来。查下来是SBL1分区被意外覆盖,引导链断在第一步。
高通平台的启动链路一般是PBL加载SBL1,SBL1再加载ABL(Bootloader),ABL拉起XBL和TZ,最后把kernel boot起来。这条链路上任何一个镜像损坏,都表现为开机无任何显示。PBL本身在EDL里能直接和烧录工具通信,所以只要9008在,SBL1和后面所有分区都能重刷。
实操建议:改分区前先把当前分区表完整导出,用fastboot getvar partition-size或读gpt备份。不要直接对sbl1、aboot这类关键引导分区做实验。尤其是在车规板上,有些厂商的刷机脚本会默认擦除整个UFS,一不当心就把persist也清了。
1.2 问题2:跨版本强刷导致ABL卡在启动早期
SA8155/8295平台上同时存在Android和QNX两套系统,很多兄弟从Android 10的工程版本直接降级刷到QNX版本,或者从较老的BSP跳到新版BSP,结果卡在ABL阶段——屏幕可能亮,但一直停在Logo或者循环重启。
本质原因是ABL、XBL、TZ这几个镜像之间存在版本耦合。高通的secure boot在车规平台普遍开启,旧XBL可能无法加载新TZ的签名镜像,甚至HAB校验直接拒绝启动。处理办法不是暴力刷写,而是先确认你手里的刷机包和当前硬件匹配:看sbl1、xbl、tz、hyp这四件套是否来自同一份发布版本,然后整包烧录,不要只挑其中一个分区刷。跨版本时尤其不要绕过ABL直接只刷kernel,否则就会出现能进fastboot但一选启动就黑屏的诡异情况。
1.3 问题3:烧录过程中掉电或USB线材劣质,写入一半直接中断
这个坑我见过不止一次,大多发生在客户现场。烧录SA8295这种平台,UFS数据量动辄几十GB,整个过程动辄二三十分钟,这时候一条接触不良的USB-A转Type-C线就能毁掉一次抢救计划。烧录中断在分区表写入阶段时,后果最严重:UFS的LUN映射错乱,后续即使重新烧录也可能出现容量识别异常、某些分区读不到。
正确做法是给开发板使用独立的稳定供电,如果用ATX电源或稳压电源,先确认电压电流足够,不要靠USB口供电支撑整个烧录过程。烧录线材选短而粗的USB线,避免经过Hub,最好直接插主板后面的USB2.0口。之前遇到过一次插USB3.0口导致QFIL在烧到persist分区时反复timeout,换到USB2.0口后一次通过,这个问题下面单独说。
2. 进 EDL 的三种姿势:短接、按键、命令行,以及识别不到 9008 的坑
进入EDL这件事听起来简单,但在车规主板上实际操作时远比手机麻烦。手机普遍支持音量键组合,开发板很多时候没有按键,只能靠短接测试点或者uboot/ABL下的指令。先把各平台的入口方式理清楚,才能临场不乱。
| 进入方式 | 适用场景 | 注意事项 |
|---|---|---|
| 按键组合(常见为音量上+开机键) | 带按键的工装板/开发板 | 不同平台按键逻辑不同,部分板子需按住5秒以上 |
| 短接测试点(DL/DP点) | 没有按键或系统彻底无法启动时 | 需硬件原理图,不同PCB设计短接点完全不同 |
| 系统内命令 | Android可开机,ADB可用 | adb reboot edl最省事;QNX下有时需要改boot参数 |
| ABL/fastboot命令 | 能进fastboot | fastboot reboot edl,但ABL故障时无效 |
2.1 问题4:EDL 9008短接点到底怎么找,为什么不通用
网络上有各种关于“9008短接哪两根线通用”的说法,我在这提醒一句:没有任何一种短接点是跨所有高通平台通用的。原因很简单,9008的触发原理是让PBL在启动时检测不到可信启动镜像,于是自动进入紧急下载模式。不同PCB设计会把对应的测试点放在不同位置,有的在SoC附近,有的隐藏在板层中间,甚至同型号不同批次都有差异。
最稳妥的通用做法是查开发板厂商的硬件手册,找到标注为“EDL Trigger”“DL”“FORCE_USB_BOOT”的测试点,短接到GND再上电。如果实在找不到文档,可以在板上找靠近PMIC或SoC的一排未焊接测试点,用万用表挨个测,找对地阻值接近0的点位短接测试,但这个方法需要格外小心,短接错点可能烧坏电源轨。实际调8155和8295时,我基本优先用ADB命令,只有在整机完全没响应时才拆盖短接。
2.2 问题5:9008端口时有时无,设备管理器识别成未知设备
有很多人进入EDL后,发现设备管理器里根本看不到9008,而是显示一个“Unknown Device”或者带黄色感叹号的“QHSUSB_BULK”。这种情况多数不是硬件问题,而是驱动没有正确加载。Windows 10/11对驱动签名要求更严格,而高通USB驱动老版本经常无法通过签名验证。
我是这么处理的:先把设备管理器里这个未知设备卸载,勾选“删除此设备的驱动程序软件”,然后拔掉USB线,重新插上,手动指定驱动路径指向QPST安装目录下的Drivers文件夹。不要用Windows自动搜索驱动,大概率会失败。另外,Win11容易出现驱动签名强制开启导致无法安装的情况,需要临时进入高级启动选项禁用驱动签名强制,装好驱动后再恢复。还有一点,9008模式的USB枚举对接口非常敏感,实测USB3.0口在半速枚举时容易超时,USB2.0口最稳定,优先选后用。
2.3 问题6:ABL无法响应按键交互,fastboot也进不去的Escape方案
部分8155/QNX系统的工程机把ABL里的fastboot按键检测阉割了,开机后直接进系统,想进EDL只能靠软件命令。但系统崩溃后进EDL就成了难题。这种情况下,如果之前给bootloader配置过panic触发逻辑,可以在ABL启动阶段连续按特定组合键强制触发EDL;没有的话就只能回到短接测试点的路子。
另外一类情况是烧录工具已经识别9008,但用户仍在EDL里反复重启,拔线后重新上电又变成未知设备。这通常是因为烧录完成后工具没有自动执行软复位,或者镜像里没有包含正确的reset指令。处理办法是拔线重插,短按复位键让SoC软复位,让ABL重新枚举为正常加载模式而不是又掉回EDL。
3. 从 9008 把系统捞回来:QFIL 烧录过程里的关键参数与报错
进入EDL只是第一步,真正折磨人的是烧录工具的选择和配置。QFIL、QPST、QFlash这几个工具我都用过,实际项目里最常用的是QFIL,因为它对Firehose协议支持得最好,SA8838/8155/8295这些平台都有对应的prog_firehose_ddr镜像。但工具版本乱、镜像配错的问题太常见了。
3.1 问题7:prog_firehose_ddr.elf与平台不匹配,报FLASH_IMG: ERR错误
QFIL烧录的第一步是把prog_firehose_ddr.elf下发给目标设备,这个elf相当于一个小型下载引导程序,让PC与目标板建立Firehose通信。如果elf版本不对,常见的报错是“FLASH_IMG: ERR: Failed to find partition”或“Firehose Fail: Device not in emergency mode”。这说明elf不仅管着底层协议,还决定分区表的读取方式。
不同平台甚至同一平台不同UFS配置,对应的elf都可能不同。比如SA8155的UFS版本和SA8295的UFS版本不一样,用同一个elf刷过去会直接报错。正确操作是严格按照发布BSP包里的prog_firehose_ddr.elf来,不要从网上随便下载所谓万能elf。另外,老版本QPST自带的QFIL可能不支持SA8295的新分区协议,遇到“Loader cannot load”这类报错优先考虑升级QFIL版本,确实有很多次是工具老的问题。
3.2 问题8:rawprogram0.xml、patch0.xml和contents.xml到底怎么选
QFIL图形界面里会让你选择加载XML配置,很多人在这一步栽跟头。简单梳理一下:
- rawprogram0.xml:定义了所有需要烧写的物理分区、起始地址和大小,是Firehose烧录的主索引。
- patch0.xml:负责对分区表、GUID、偏移做修正,多半用于量产工具生成,手动烧录时有时不需要加载。
- contents.xml:是Meta数据,描述一个可烧录包的完整性。
Flash Programmer类型选择上,一般选“flat build”和“dump”的组合,浏览分区表时勾选全部分区。如果只刷部分分区,比如只刷boot和dtbo,可以手动取消勾选其他分区,但绝对不能手动修改XML里的地址,否则轻则分区错位,重则直接抹掉Bootloader。我遇到过一次只刷system分区结果把vbmeta也带进去的情况,导致Secure Boot校验失败,最后还得整套重刷,反而耽误时间。
3.3 问题9:QFIL烧完不自动重启,或者重启后卡Logo无限重启
烧录完成后最激动人心的一刻,往往也是最容易出现反转的时候。QFIL显示Success但不自动重启,这是正常现象,说明固件里没有下发软复位指令,手动复位即可。复完位如果卡在开机Logo,多半不是烧录失败,而是persist分区数据有问题。
persist分区在车载平台上保存了Sensor校准数据、摄像头参数、部分平台还存有音频拓扑。很多BSP包在烧录时默认擦除了persist,重启后系统找不到关键配置就会反复重启。处理办法是在QFIL的分区列表里单独勾选persist分区并烧录一次厂家的persist.img,或者进入fastboot手动fastboot flash persist persist.img。另外注意,部分新的SA8295平台把persist换成了persist_1、persist_2这种多分区形态,别漏了。
4. QCN 备份与恢复:IMEI 归零、基带掉链子时的最后底牌
在所有“救砖”操作里,最让我紧张的不是系统起不来,而是基带配置丢失。QCN是高通平台的NV配置导出文件,包含射频校准、IMEI、mac地址、ode校准等关键信息。一旦丢了,轻则信号差,重则IMEI直接变成004999010640000,基带彻底无法註册网络。车载平台同样有这个风险,尤其是8155/8295的T-Box场景,QCN损坏意味着4G/5G、GNSS、Wi-Fi全乱套。
4.1 问题10:QXDM读取不到QCN,Diag端口没激活
QCN的备份通常通过QXDM工具连接手机的DIAG端口完成,但车规平台上调试端口默认可能没打开。遇到过连接后QXDM界面里Device下拉框是空的,Com Port那里什么都选不了的情况。原因多半是目标系统没有把USB口配置成DIAG模式,或者驱动枚举成了普通Modem端口。
解决方案是先确认系统里USB composition配置。Android平台上可以通过adb shell设置persist.vendor.usb.config为diag,adb并通过setprop重启USB;QNX平台则需要检查BSP里的usb配置。如果是通过外部串口转接板连DIAG口,要先在设备管理器里确认新增的COM口是“Qualcomm Diagnostics Interface”,如果显示的是“Qualcomm USB Modem”,说明当前枚举模式不对,需要进入系统设置里切换。QXDM的端口配置里也要手动把对应COM口选成DIAG,再点Connect。
4.2 问题11:QCN恢复后IMEI仍是0,基带服务还是起不来
有很多人备份了QCN也恢复了,但重启后IMEI依旧显示0,信号为空。这种情况十有八九是恢复时NV被系统启动后重新覆盖了,或者恢复的QCN文件本身就不完整。
正确的恢复流程是这样的:设备进入EDL或确保基带处于关闭状态,用Qualcomm工具将QCN写回NV分区,写完后不要直接启动到系统,而是先进到Bootloader/fastboot,执行fastboot erase modemst1和fastboot erase modemst2。这两个分区存的其实是运行时的NV缓存,开机后基带会从QCN备份位置重新恢复NV,所以必须把它清掉。之后再正常启动。一旦顺序反了,系统开机时用旧的modemst覆盖新写好的NV,IMEI就又回去了。另外,测试SIM卡无法註册网络时,还顺手检查一下APN和band配置,QCN里的RF校准时区对了但网络注册策略不对也会表现成搜不到网。
5. 串口日志、ADB 与无线调试:没有日志,问题排查无从谈起
系统能启动了,真正的调试才刚开始。车载平台调试最依赖两个通道:串口和ADB。串口能看到bootloader、kernel、QNX各个阶段的启动日志,ADB则负责Android层的日志和命令交互。这两个通道任何一个出问题,排查效率都会直线下降。
5.1 问题12:串口助手连上却无输出,线序、电平、波特率全排查
串口无输出是我接到咨询最多的问题,没有之一。拿sscom、XCOM这类串口调试助手连开发板UART口,开了端口却没有字符跳动。先别怀疑板子坏了,按这个顺序排查:
- 确认是TTL电平还是RS232电平,车载板多为TTL,直接连到USB转TTL工具上,电压3.3V,注意别用5V供电才不会烧引脚。
- 确认TX/RX是否交叉,板子的TX要接转接板的RX,板子的RX接转接板的TX,很多人忘记交叉。
- 确认波特率,高通平台常见的是115200和921600两种,其中BOOTROM阶段往往是115200,SBL跑起后切到更高波特率;sscom里要先设115200,看到SBL日志后关闭再重开921600才能继续看到后续内容。
值得专门提醒的一点是:有些转接板用了CP2102或CH340芯片,驱动兼容性不一样,CH340在部分Windows上延迟大、丢字符,排障时建议换一个FT232芯片的转接板,稳定性好很多。
5.2 问题13:ADB连不上或adb devices空列表,无线调试端口固定方法
车载平台ADB连不上的原因,一半是USB枚举配置,另一半是授权弹窗没点。检查persist.vendor.usb.config是否包含adb,然后在开发板上确认是否弹出RSA授权。如果device列表能看到设备但是显示offline,重启adb server,重新插拔USB接口通常能解决。
无线调试在车机上很好用,但要固定端口号,否则每次连接端口都变。Android 11以上支持adb pair配对,固定端口的方式是设置persist.adb.wifi.port,我一般设成5555,然后在桌面前台执行adb tcpip 5555,接着adb connect 开发板IP:5555。实测SA8295平台在Android Auto/CarPlay工况下无线调试偶尔出现断流,除了检查Wi-Fi休眠策略外,建议把开发板的Wi-Fi锁屏不断开选项打开,或通过adb shell svc wifi disable/enable重启Wi-Fi栈。
5.3 问题14:8155 QNX与Android双系统日志体系差异
SA8155/8295平台很多项目是QNX+Android混合部署,QNX跑在虚拟机里负责仪表和实时控制,Android跑在另一个虚拟机处理娱乐。串口日志在启动早期是QNX的slog信息,切到Android后则变成logcat体系。很多人刷完机看到串口一大片QNX日志以为系统卡死,其实只是还没切到Android阶段。
排查QNX侧问题抓sloginfo和slog2info,Android侧则用adb logcat配合高通特有logcat-service。用串口助手看到大量slog输出时,不要直接在串口里中断,否则可能把Hypervisor的核间通信打断。如果需要在Android启动后持续抓QNX日志,建议通过adb shell连接到QNX侧再输出到文件,别在物理串口上硬怼。另外一个经验:高通QNX平台启动时串口日志很容易淹没在几千行slog里,搜关键字时优先搜“panic”、“assert”、“fatal”,比从头翻高效得多。
6. 从 CAF kernel 到 CHI-CDK:编译和外设调试的实际体验
系统稳定运行后,跑不掉的还有内核编译和外设适配。高通车规平台的内核基于CAF分支,和主线Linux存在不少差异,驱动和DTS配置都有自己的规则。这一节讲两个最典型的调试场景:CAF kernel的编译,以及Camera子系统的CHI-CDK排障。
6.1 问题15:CAF kernel编译总在repo同步或GCC版本上报错
CAF(Code Aurora Forum)是高通开源代码的主阵地,8155/8295的内核分支在codelinaro上维护。很多人在拉代码时被repo sync的网速和存储空间劝退,SA8295的kernel源码加vendor模块动辄几十GB,同步到一半中断后git object损坏的情况很常见。我的做法是先单独拉kernel仓库,再拉vendor相关仓库,编译前确认gcc和clang版本。
高通从SM8250时代开始全面切换到Clang编译内核,用系统自带的gcc编译大概率报错,常见的是“unsupported option ‘-fconserve-stack’”。指定的交叉编译器要用发行BSP里带的prebuilt clang夹,或者从AOSP的prebuilts/clang/host/linux-x86拉对应版本。DTS编译报错也和CAF版本有关,老的BSP用kernel_headers生成dtbo,新版则统一用dtbimg。遇到编译错误先确认BSP文档要求的工具链和编译命令,不要只看README里的通用步骤。
6.2 问题16:Camera/CHI-CDK 调试和 4G LTE 模式开关的代码定位
最后说两个调试时经常被问到的点。第一个是Camera子系统。高通平台相机不走标准V4L2节点直出,而是通过CHI-CDK架构,把sensor、usecase、pipeline组合成XML方式配置。调试时log全在logcat的CamX、CHI标签下,想看sensor是否点亮,先抓QCamera3HAL相关日志,或者通过camxoverride配置强制打开一些调试项。如果新点sensor不出图,优先检查sensor驱动里的寄存器配置和camera ID的映射关系,很多“不出图”其实是GPIO或电源时序不对,CHI日志里会有power up failed之类的关键字。
第二个是车载4G LTE模式开关。很多人问“增强型4G LTE模式开关代码”在哪改,这个开关对应的是Settings里的“首选网络类型”和VoLTE相关配置。代码实现上,在Telephony层看CarrierConfigManager的KEY_ENHANCED_4G_LTE_MODE_VARIABLE和KEY_ENHANCED_4G_LTE_MODE_BOOL,默认是否开启由sim卡信息和运营商的carrier_config共同决定。如果T-Box上发现VoLTE开关灰掉,先检查modem侧的NV和carrier配置,确定不是用哪个工具把EFS里VoLTE disable flag改掉了。这个开关在调试modem和网络注册问题时极容易让人绕圈子,先确认系统属性persist.vendor.radio.enable_volte的值,再去看代码配置,能省不少时间。
车载高通平台的调试本质上是个系统工程,从EDL救砖到QCN恢复再到外设调优,每一环都有它的底层逻辑。上面这16个问题是我在SA8838、8155、8295实际项目中反复踩过的,记录成本文时又理了一遍。如果你正在调试这些平台,建议先备份QCN和分区表,再尝试各种实验性操作;遇到问题时顺着启动链路和日志体系去定位,比盲目重刷要靠谱得多。