资源冲突导致启动黑屏问题

问题记录:资源冲突导致启动黑屏问题

1. 问题发生

终端客户反馈:上电后中控没有启动,仍为黑屏;

进一步获取信息如下:

  1. 836版本软件6台机器进行自动化开关机实验测试,其中3台出现此问题;
  2. 客户同样方式煲机9台(Debug版本),一晚上未出现问题;
  3. 客户将其中6台机替换为836版本软件,测试5小时,4台出现此现象;
  4. HW排查异常机器,晶振没有工作,MCU有正常给AP供电;

2. 问题分析

2.1 排除board 影响

由于HW排查出现晶振没有工作的情况,担心board存在问题,立即到现场进行处理,首先排除board设计问题:

  1. 将两台机器连接串口打印,进行开关机测试;
  2. 其中机器A在10分钟左右出现问题,此时量取晶振,是有在工作的
    说明并非board 晶振不振导致系统停止工作,而是其他原因导致异常,而后系统不再工作,需要分析log情况,进一步确认问题点;

2.2 排查方向

根据当前所了解到的信息排查方向如下:

  1. 根据log信息正面排查,确认异常逻辑;
  2. 从获取信息来看,debug版本和user版本表现有差异,可以进行交叉对比实验缩小范围;

2.3 具体分析

反复测试多次,log基本都卡在相同位置:
资源冲突导致启动黑屏问题
从这个位置来看存在几种可能性:

  1. 异常环节在lk中,从这个log信息来看,还没有进入kernel;

    需要打开lk中log信息进一步确认;

  2. 异常环节在kernel中,由于kernel在uart初始化完成之前将log信息存储在内存中,如果这个阶段出现block,可能也是卡在这个位置的;

    需要打开early console打印kernel中log确认;

  3. 异常环节在tee中,由于客户会修改这部分使用,所以也存在这种可能性(较小);

    由于debug版本没有此问题,可以交叉替换tee.img测试

2.3.1 打开log操作

  1. Kernel 打开early console,并设置默认输出log:

    kernel-4.9/arch/arm/configs/$(Device)_defconfig 添加 CONFIG_SERIAL_MTK_EARLY_CONSOLE=y
    drivers/tty/serial/ 中添加 mtk_earlycon.c
    将disable_uart设置为0 资源冲突导致启动黑屏问题

  2. LK打开log分析,目前怀疑这部分的可能性比较大:

    /vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/$Project/default.mak 设置CFG_UART_DYNAMIC_SWITCH :=0
    资源冲突导致启动黑屏问题

    /vendor/mediatek/proprietary/bootable/bootloader/lk/project/$Project.mk DEBUG:=1 这里会控制log的打印,默认0的情况会把loglevel设置为2:
    资源冲突导致启动黑屏问题

2.3.2 实验排除部分可能性

  1. Tee 初始化时还没有运行到客户修改的部分,理论上这部分可能性比较小;
  2. 机器A出现问题后烧录Debug版本测试未出现问题,存在两种可能性:
    1. Format all操作将emmc清空后重新烧录,即format all操作修复问题;
    2. 烧录为新的image,修复问题;
    3. 测试2小时后还是出现问题,则上述怀疑点排除;
  3. 由于烧录image有verify限制,所以需要首先替换preloader,替换为对应disable verify版本
    1. 机器A在683版本上烧录preloader_disable debug版本tee.img,半小时后复现到了问题,排除tee部分影响;
    2. 机器A在683版本上烧录上述添加log后的 preloader、lk、boot三个分区
    3. 将lk和preloader替换为原来683异常版本,半小时内出现问题

此实验得出结论:为preloader + lk影响

2.3.3 跟踪改动宏部分逻辑

由于lk & preloader使用为683版本,仅为进行了上述操作问题消失,则存在如下两种可能性:

  1. 为打开log影响;
  2. 上述宏的开关还会影响到其他部分;

源码目录搜索该宏,可以看到只有如下部分有使用:
资源冲突导致启动黑屏问题

  1. 在platform.h中定义了一个变量:log_dynamic_switch:
    资源冲突导致启动黑屏问题
  2. Print.c中定义了一个变量g_log_switch,在set_log_switch将其设置为1:
    资源冲突导致启动黑屏问题
  3. 推测启动过程中一定会用到这个变量来进行操作,依次查看这几个宏控制位置,我们需要找到的是控制lk log的位置,主要怀疑这个位置:platform_set_boot_args_by_atag,字面意思是通过这里往lk继续传递参数,tags->u.log_com.log_dynamic_switch = (u8)get_log_switch()

实验验证:

  1. 将宏仍然设置为0,然后将这个参数配置为1,结果可以正常输出lk log信息,说明就是这里控制的;
  2. 将宏设置为1,这里参数配置为0,结果无法输出lk log信息,并且很快复现到一次问题;

则这部分实验说明:

  1. Lk部分log控制实际就是tags->u.log_com.log_dynamic_switch
  2. 问题大概率是由log触发的

进一步在lk部分查看这个变量的作用:
资源冲突导致启动黑屏问题

从流程上来看仅仅是管控log信息,但是为了保险起见我们继续做两个实验:

  1. Log_dynamic_switch设置为1,然后uart两个判断直接返回;
  2. Log_dynamic_switch设置为0,然后uart两个判断强制执行;

结果:实验2的情况下有log打印,且未测到异常现象;实验1无log输出,且可以复测到问题;

则经过上述几个对比实验,说明问题受是lk部分的log信息打印影响,这也进一步佐证了为什么debug版本无问题而user版本有问题,而log信息对于系统的影响主要是时序,所以接下来两个方向排查:

  1. 对比lk部分的改动,是否有可能造成系统block的可能性
  2. 逐步关闭log信息排查,缩小范围;

结果比较顺利,对于lk部分的改动内容较少,I2C部分的改动非常值得怀疑,由于将其去除后短时间内如果测试不到问题,则很难说明问题,所以反向测试,在添加log信息的情况下将这部分对I2C的操作修改为循环处理持续2分钟:
结果必现问题,则说明确实为lk中添加的I2C操作影响,由于I2C部分在ARM9中也有操作,则同时操作同一组I2C的时候会出现资源冲突问题;

抓取相关波形证明问题:
资源冲突导致启动黑屏问题

3. 问题处理

经过上述分析,确认问题原因为ARM9 与 A53在lk阶段同时操作I2C模块,导致系统崩溃,block住10分钟后系统不再工作;
由于存在两个核之间同时操作某IP的可能性,建议客户将对于I2C操作均放在ARM9中,避免在LK中使用,修改后安排9台机器煲机两天未出现此问题;

4. 整理

上述过程中获取如下信息:

  1. Lk部分的log信息管理是如何进行的,相关控制关键位置;
  2. 由于ARM9会对UART I2C SPI等接口进行通信,需要限制资源竞争冲突,避免出现此类问题;
  3. log打印会影响到时序进而影响程序结果;