不久前做指纹识别功能时考虑不周导致挖的一个坑使得别的项目同事在clone新项目出现不开机的情况,我也因此被接连追杀讨伐,汗..这里记录总结下事故发生原因过程,算是给自己一个提醒,希望以后考虑问题可以更加全面谨慎。
由于Android N的过CTS的原因,指纹识别需要拿到trustzoone实现,其中有一个重要的事情就是需要改TA(trust app)内存映射起始地址及增大缓存size, 否则会出现TA load failed 的错误:
[ 28.210673] scm_call failed: func id 0x72000101, ret: -2, syscall returns: 0xffffffffffffffe0, 0x0, 0x0
[ 28.219084] QSEECOM: qseecom_load_app: scm_call to load app failed
===>
0xffffffffffffffe0 is QSEE_RESULT_FAIL_IMAGE_ALLOC
#define QSEE_RESULT_FAIL_IMAGE_ALLOC 0xFFFFFFE0
It happens usually it means you don't have enough TA memory for all TA.
该改动涉及到的地方有三个:lk,kernel,trustzoon,而且必须完全一致,否则出现不开机现象,而且还很不好查错,下面分别给出说明:
lk:
bootable/bootloader/lk/platform/msm8952/include/platform/iomap.h
#ifdef FINGERPRINT_SUPPORT
#define APP_REGION_ADDR platform_get_tz_app_add()
#define APP_REGION_SIZE platform_get_tz_app_size()
#define APP_REGION_ADDR_8952 0x84A00000
#define APP_REGION_SIZE_8952 0x1900000
#define APP_REGION_ADDR_8937 0x84A00000
#define APP_REGION_SIZE_8937 0x1900000
#else
#define APP_REGION_ADDR platform_get_tz_app_add()
#define APP_REGION_SIZE platform_get_tz_app_size()
#define APP_REGION_ADDR_8952 0x85E00000
#define APP_REGION_SIZE_8952 0x500000
#define APP_REGION_ADDR_8937 0x85B00000
#define APP_REGION_SIZE_8937 0x800000
#endif /*FINGERPRINT_SUPPORT*/
TA 映射地址 :0x85B00000-> 0x84A00000, SIZE :0x800000 (8MB) -> 0x1900000 (25MB) 这里有个地方需要注意下,有点bt,虽然平台名称是8937,但是实际代码跑得却是8952目录下的 iomap.h文件(8953平台有自己的目录)。APP_REGION_ADDR 跟 APP_REGION_SIZE 都有多个,那么具体你的平台是跑得哪一个就最靠谱的就是看下代码逻辑:
bootable/bootloader/lk$ xxgrep APP_REGION_ADDR
./platform/msm8996/include/platform/iomap.h:213:#define APP_REGION_ADDR 0x86600000
./platform/msm8952/platform.c:261: return APP_REGION_ADDR_8937;
./platform/msm8952/platform.c:263: return APP_REGION_ADDR_8952;
uint32_t platform_get_tz_app_add()
{
if(platform_is_msm8937() || platform_is_msm8917())
return APP_REGION_ADDR_8937;
else
return APP_REGION_ADDR_8952;
}
uint32_t platform_get_tz_app_size()
{
if(platform_is_msm8937() || platform_is_msm8917())
return APP_REGION_SIZE_8937;
else
return APP_REGION_SIZE_8952;
}
所以,从上面代码显然可以看到,当前平台走的是哪一支宏定义.
kernel:
./arm/boot/dts/${project}/msm8937.dtsi:1559: qcom_seecom: qseecom@84A00000{
other_ext_mem: other_ext_region@0 {
compatible = "removed-dma-pool";
no-map;
- reg = <0x0 0x85b00000 0x0 0xd00000>;
+ reg = <0x0 0x84A00000 0x0 0x1E00000>;
};
- qcom_seecom: qseecom@85b00000 {
+ qcom_seecom: qseecom@84A00000{
compatible = "qcom,qseecom";
- reg = <0x85b00000 0x800000>;
+ reg = <0x84A00000 0x1900000>;
};
Trustzone :
TZ.BF.4.0.5/trustzone_images/core/securemsm/trustzone/qsee/mink/oem/config/msm8937/oem_config.xml:35: <props name="OEM_pil_secure_app_load_region_start" type=DALPROP_ATTR_TYPE_UINT32>
<props name="OEM_pil_secure_app_load_region_start" type=DALPROP_ATTR_TYPE_UINT32>
- 0x85B00000
+ 0x84a00000
</props>
<props name="OEM_pil_secure_app_load_region_size" type=DALPROP_ATTR_TYPE_UINT32>
- 0x800000
+ 0x1900000
</props>
问题原因:由于之前${project}的lk部分使用的是项目控制宏 ${project}_XXX, 所以导致clone项目到${project2}后该宏不再生效,而trustzoon部分是提交到公共仓库的,如此导致了lk部分跟tz部分的地址不一致,从而导致不开机的现象。
解决方案:
TZ部分修改放到project私有的目录:如:device/qcom/${project}/non_hlos/TZ.BF.4.0.5/,
kernel部分维持放到对应的project私有目录:如 ./arm/boot/dts/${project}/msm8937.dtsi ,
lk部分使用指纹功能宏控制:FINGERPRINT_SUPPORT, 但是由于其特殊性,无法使用一个统一的宏开关同步关闭所有涉及的改动,所有凡是有指纹的项目,该宏不可关闭,否则就会导致不一致的情况。不支持指纹的项目关闭该开关后,需要check确保三个地方一并移除,为避免此原因导致该问题二次发生,项目clone后可以把本文档作为惯例检查点以规避该问题.