问题:
该现象存在于进行随机上下电的测试中,板子会进入recovery系统。影响其他测试,需要进行规避
分析:
1.查看kernel log,并没有发现什么异常导致系统启动分区被损坏导致无法正常进入android系统
2.查看userdata分区,根据屏幕显示的userdata分区异常,需要人工进行修复。因此可以假设是由于userdata分区损坏导致进入recovery系统的。进行假设印证:在recovery模式下手动挂载userdata分区,发现分区无法挂载,可能是由于userdata分区异常导致的。
3.查看uefi log,此时发现Recovery:1,对比正常机器的Recovery:0,可能是这个地方导致系统判断需要进入recovery。
代码分析:
1.根据上面的分析,只能进入abl内进行代码搜寻,从LinuxLoader.c中开始查看,发现在启动内核之前,会进行一个RecoveryInit操作,上面的Recovery:1也是打印RecoveryInit的结果。查看RecoveryInit函数
2.在RecoveryInit中,着重关注ReadFromPartition 函数,为什么要在这里读取分区数据?读取的是哪个分区?添加打印,将ReadFromPartition (&Ptype, (VOID **)&PartitionData, (PageSize * 2))中的Ptype,Ptype被初始化为EFI_GUID Ptype = gEfiMiscPartitionGuid;gEfiMiscPartitionGuid可以从BootLib.inf中找到,而gEfiMiscPartitionGuid的赋值操作在QcomModulePkg.dec 中,并且对比分区表,可以发现这个gEfiMiscPartitionGuid正是对应了partition.xml内的misc分区的type。因此可以分析得到在abl阶段会执行RecoveryInit函数,而这里面会根据misc分区内的数据来判断系统是否正常,是否需要进入recovery模式
3.既然是misc分区出现问题,那么就将misc分区导出,对比一下正常的与异常的misc分区存在什么差异。通过对比发现,正常启动的misc分区内是空的,而异常的misc分区内数据如下
boot-recovery
--prompt_and_wipe_data
--reason=enablefilecrypto_failed
那么再去看看这个reason=enablefilecrypto_failed代表什么意思,百度得知这个是userdata的fbe加解密失败的意思。
那么整个流程就理得通了:1.随机上下电测试是没有时机可言的,从刚进入kernel的一瞬间再到系统完全起来之间都有可能发生随机掉电。那么如果刚好在userdata分区加密的时候掉电了,或许就会导致userdata的分区加解密失败,导致第二次启动的时候系统无法挂载userdata分区,将错误信息写入misc分区,在下一次启动的时候,RecoveryInit检测到misc分区内存在错误信息,从而做出进入recovery模式的判断。
解决思路:
1.建议修改测试手法
2.移除FBE功能(不建议,因为可能还有其他的异常也会导致进入recovery,这里不分析)
2.添加规避逻辑,在RecoveryInit的时候对misc内的数据同时进行判断,如果发现是由于FBE加解密失败导致userdata分区损坏进入的,则格式化userdata分区,并且对misc分区内的数据进行清空(否则即使格式化userdata分区了。依然会进入recovery模式)
总结:
上述的解决思路仅仅适合测试阶段,不考虑用户体验。android存在这样的机制,进入recovery的话如果是异常进入的,会提示用户,而我们只是为了自动化测试的进行