RK3288 android 6.0 卡死在开机logo画面问题处理
Description
烧录固件后,会概率性出现卡死在开机画面无法启动的问题,但是烧录新固件后会恢复正常。对比不同机型,发现只有带摄像头功能的机型会有这个问题。
Root cause
经过大量测试和排查,发现卡死问题源自一个文件, /data/camera/media_profiles.xml
, 这是一个空文件,删除后系统就正常启动了。
通过使用 logcat
结合系统源码发现,该文件是摄像头配置文件,如果为空会导致系统循环检测该文件,并尝试从中获取摄像头配置,但是由于文件为空,导致一直获取失败,最后陷入死循环。
$ cd /data/camera
$ ls
media_profiles.xml
经过排查源码,发现系统在检查到有摄像头接入后,会将默认配置文件 /etc/media_profiles_default.xml
拷贝至 /data/camera/media_profiles_tmp.xml
, 然后根据实际情况修改该tmp文件,并最终写入到 /data/camera/media_profiles.xml
文件中。相关函数 ProduceNewXml
如下:
// hardware/rockchip/camera/CameraHal/CameraHal_board_xml_parse.cpp
int camera_board_profiles::ProduceNewXml(camera_board_profiles* profiles)
{
char temp_dst_file[50];
char dst_file[50];
char default_file[50];
int err=0;
int res=0;
//CheckSensorSupportDV
AddConnectSensorToVector(profiles);
size_t nCamNum =profiles->mDevideConnectVector.size();
//verrify media_xml_device is supported by board xml
for(int i=0; (i<profiles->xml_device_count && i<2); i++)
{
res |= ConnectDevHaveDev(profiles, (profiles->mXmlDevInfo + i));
}
if(res == RK_RET_SUCCESS && profiles->xml_device_count==(int)nCamNum){
return RK_RET_SUCCESS;
}
int fileexit = access(RK_DST_MEDIA_PROFILES_XML_PATH, 0);
ALOGD("judge the media profile xml fileexit = %d\n", fileexit);
//if((int)nCamNum>=1){
if((int)nCamNum>=1 && fileexit == -1){
LOG1("enter produce new xml\n");
//new xml file name
strlcpy(default_file, RK_DEFAULT_MEDIA_PROFILES_XML_PATH, sizeof(default_file));
strlcpy(dst_file, RK_DST_MEDIA_PROFILES_XML_PATH, sizeof(dst_file));
strlcpy(temp_dst_file, RK_TMP_MEDIA_PROFILES_XML_PATH, sizeof(temp_dst_file));
for(int i=0; i<(int)nCamNum; i++){
CheckSensorSupportDV(profiles->mDevideConnectVector[i]);
}
//write name to xml
err = WriteDevNameTOXML(profiles, default_file, temp_dst_file);
if(err){
ALOGE("write dev name to xml failed\n");
goto end;
}
//modify xml
err = ModifyMediaProfileXML( profiles, temp_dst_file, dst_file);
if(err){
ALOGE("modify xml failed\n");
goto end;
}
LOG1("exit produce new xml\n");
}
end:
return err;
}
其中使用了宏定义变量,定义如下:
// hardware/rockchip/camera/CameraHal/CameraHal_board_xml_parse.h
#define RK_DEFAULT_MEDIA_PROFILES_XML_PATH "/etc/media_profiles_default.xml"
#if defined(ANDROID_5_X)
#define RK_DST_MEDIA_PROFILES_XML_PATH "/data/camera/media_profiles.xml"
#define RK_TMP_MEDIA_PROFILES_XML_PATH "/data/camera/media_profiles_tmp.xml"
#else
#define RK_DST_MEDIA_PROFILES_XML_PATH "/data/media_profiles.xml"
#define RK_TMP_MEDIA_PROFILES_XML_PATH "/data/media_profiles_tmp.xml"
#endif
至于为何会出现该空文件,有可能是在写入过程中掉电导致的,但是目前没有重现。
reproduce
手动重现的方法比较简单,就是新建一个空文件 data/camera/media_profiles.xml
, 新建后无论什么机型都会卡死在logo界面,这个bug应该是系统原生就有的。
cd /data/camera/
touch media_profiles.xml
related
files
相关文件如下:
# line 676 MediaProfiles::getInstance
frameworks/av/media/libmedia/MediaProfiles.cpp
hardware/rockchip/camera/CameraHal/*
hardware/rockchip/camera/CameraHal/CameraHal_board_xml_parse.h
hardware/rockchip/camera/CameraHal/CameraHal_MediaProfile.cpp
# int camera_board_profiles::LoadSensor(camera_board_profiles* profiles)
# 01-10 16:08:27.266 205 205 D CameraHal: read cam name from xml(/data/camera/media_profiles.xml)
hardware/rockchip/camera/CameraHal/CameraHal_board_xml_parse.cpp
$ cd /media/hdd1/wugt/rk3288-android6.0-sdk/out/target/product/rk3288
$ grep -rn media_profiles.xml
Binary file obj/lib/camera.rk30board.so matches
Binary file obj/lib/libmedia.so matches
Binary file obj/PACKAGING/systemimage_intermediates/system.img matches
Binary file obj/SHARED_LIBRARIES/camera.rk30board_intermediates/LINKED/camera.rk30board.so matches
Binary file obj/SHARED_LIBRARIES/camera.rk30board_intermediates/PACKED/camera.rk30board.so matches
Binary file obj/SHARED_LIBRARIES/camera.rk30board_intermediates/CameraHal_board_xml_parse.o matches
Binary file obj/SHARED_LIBRARIES/camera.rk30board_intermediates/CameraHal_Module.o matches
Binary file obj/SHARED_LIBRARIES/libmedia_intermediates/LINKED/libmedia.so matches
Binary file obj/SHARED_LIBRARIES/libmedia_intermediates/PACKED/libmedia.so matches
Binary file obj/SHARED_LIBRARIES/libmedia_intermediates/MediaProfiles.o matches
Binary file system.img matches
Binary file system/lib/hw/camera.rk30board.so matches
Binary file system/lib/libmedia.so matches
Binary file symbols/system/lib/hw/camera.rk30board.so matches
Binary file symbols/system/lib/libmedia.so matches
logs
相关log如下:
130|root@rk3288:/ # logcat |grep profile &
[1] 1070 1071
root@rk3288:/ # 01-07 11:08:57.330 205 205 E CameraHal: camera_get_number_of_cameras(695): board profiles cam num 7
01-07 11:08:57.330 205 205 D CameraHal: read cam name from xml(/data/camera/media_profiles.xml)
01-07 11:08:57.352 205 205 D CameraHal: camera_get_number_of_cameras(1146): meida_profiles_xml_control time (43839)us
01-07 11:08:59.981 171 171 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:08:59.982 171 171 D MediaProfiles: getInstance(713): Create instance from /data/camera/media_profiles.xml
01-07 11:09:01.087 543 543 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:09:01.088 543 543 D MediaProfiles: getInstance(713): Create instance from /data/camera/media_profiles.xml
01-07 11:09:06.287 558 558 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:09:06.287 558 558 D MediaProfiles: getInstance(713): Create instance from /data/camera/media_profiles.xml
01-07 11:09:11.466 584 584 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:09:11.466 584 584 D MediaProfiles: getInstance(713): Create instance from /data/camera/media_profiles.xml
01-07 11:09:15.695 610 610 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:09:15.695 610 610 D MediaProfiles: getInstance(713): Create instance from /data/camera/media_profiles.xml
01-07 11:09:20.920 636 636 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:09:20.920 636 636 D MediaProfiles: getInstance(713): Create instance from /data/camera/media_profiles.xml
01-07 11:09:26.222 671 671 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:09:26.222 671 671 D MediaProfiles: getInstance(713): Create instance from /data/camera/media_profiles.xml
01-07 11:09:31.403 696 696 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:09:31.403 696 696 D MediaProfiles: getInstance(713): Create instance from /data/camera/media_profiles.xml
01-07 11:09:35.640 725 725 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:09:35.640 725 725 D MediaProfiles: getInstance(713): Create instance from /data/camera/media_profiles.xml
01-07 11:09:40.841 748 748 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:09:40.841 748 748 D MediaProfiles: getInstance(713): Create instance from /data/camera/media_profiles.xml
01-07 11:09:46.009 770 770 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:09:46.009 770 770 D MediaProfiles: getInstance(713): Create instance from /data/camera/media_profiles.xml
01-07 11:09:51.775 797 797 E CameraHal: camera_get_number_of_cameras(695): board profiles cam num 7
01-07 11:09:51.775 797 797 D CameraHal: read cam name from xml(/data/camera/media_profiles.xml)
01-07 11:09:51.782 797 797 D CameraHal: camera_get_number_of_cameras(1146): meida_profiles_xml_control time (21590)us
root@rk3288:/ #
root@rk3288:/ #
root@rk3288:/ # cd /data/camera/
root@rk3288:/data/camera #
root@rk3288:/data/camera # 01-07 11:10:18.581 794 794 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:10:18.581 794 794 D MediaProfiles: getInstance(713): Create instance from /data/camera/media_profiles.xml
[ 85.094068] init: couldn't write 0 to /dev/cpuset/foreground/tasks: No such file or directory
01-07 11:10:19.342 1079 1079 E CameraHal: camera_get_number_of_cameras(695): board profiles cam num 7
01-07 11:10:19.342 1079 1079 D CameraHal: read cam name from xml(/data/camera/media_profiles.xml)
01-07 11:10:19.350 1079 1079 D CameraHal: camera_get_number_of_cameras(1146): meida_profiles_xml_control time (21315)us
root@rk3288:/data/camera # 01-07 11:10:19.861 1077 1077 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:10:19.861 1077 1077 D MediaProfiles: getInstance(713): Create instance from /data/camera/media_profiles.xml
root@rk3288:/data/camera #
root@rk3288:/data/camera # [ 90.250059] init: couldn't write 0 to /dev/cpuset/foreground/tasks: No such file or directory
01-07 11:10:24.556 1207 1207 D CameraHal: camera_get_number_of_cameras(1146): meida_profiles_xml_control time (20242)us
01-07 11:10:25.081 1208 1208 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:10:25.081 1208 1208 D MediaProfiles: getInstance(713): Create instance from /data/camera/media_profiles.xml
root@rk3288:/data/camera #
root@rk3288:/data/camera #
root@rk3288:/data/camera # rm media_profiles.xml
root@rk3288:/data/camera # [ 95.425765] init: couldn't write 0 to /dev/cpuset/foreground/tasks: No such file or directory
01-07 11:10:29.853 1343 1343 E CameraHal: camera_get_number_of_cameras(695): board profiles cam num 7
01-07 11:10:29.853 1343 1343 D CameraHal: read cam name from xml(/data/camera/media_profiles.xml)
01-07 11:10:29.860 1343 1343 D CameraHal: camera_get_number_of_cameras(1146): meida_profiles_xml_control time (22146)us
01-07 11:10:30.372 1344 1344 D MediaProfiles: CameraGroupFound(618): media_profiles_id: 0x0
01-07 11:10:30.372 1344 1344 E MediaProfiles: WARNING!!!! getInstance(689): cameraHal version(1.65.1) after(0.3.0x33),but don't have file(/data/camera/media_profiles.xml)
[ 116.602227] healthd: battery l=100 v=0 t=42.4 h=2 st=2 chg=a 2022-01-07 03:10:50.769561638 UTC
[ 116.814715] lowmemorykiller: lowmem_shrink: convert oom_adj to oom_score_adj:
[ 116.814743] lowmemorykiller: oom_adj 0 => oom_score_adj 0
[ 116.814754] lowmemorykiller: oom_adj 1 => oom_score_adj 58
[ 116.814764] lowmemorykiller: oom_adj 2 => oom_score_adj 117
[ 116.814773] lowmemorykiller: oom_adj 3 => oom_score_adj 176
[ 116.814803] lowmemorykiller: oom_adj 9 => oom_score_adj 529
[ 116.814813] lowmemorykiller: oom_adj 15 => oom_score_adj 1000
workaround
临时解决方案:在出现问题后通过 adb
指令删除文件 /data/camera/media_profiles.xml
, 或者使用默认配置文件覆盖它。
cd /data/camera
rm media_profiles.xml
# or
cp /etc/media_profiles_default.xml /data/camera/
solution
最终解决方案,就是在检查到 /data/camera/media_profiles.xml
后,查看文件大小,如果为空或者小于某个值,则认为该文件异常,将其删除。
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index fe0126a..3258b71 100755
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -688,6 +688,17 @@ MediaProfiles::getInstance()
ALOGE("WARNING!!!! %s(%d): cameraHal version(%s) after(0.3.0x33),but don't have file(%s)",
__FUNCTION__,__LINE__,camerahal_value,defaultXmlFile);
}
+ else {
+ fseek(fp, 0L, SEEK_END);
+ int size = ftell(fp);
+
+ if (size < 1000) {
+ ALOGE("WARNING!!!! %s(%d): file(%s) size(%d) is too small, delete it",
+ __FUNCTION__,__LINE__,defaultXmlFile,size);
+ fp = NULL;
+ remove(defaultXmlFile);
+ }
+ }
} else {
if (fp == NULL)
ALOGD("THIS IS RIGHT: %s(%d): cameraHal version(%s) before(0.3.33),so don't have file(%s)",
删除后,系统能够正常启动,并且在下次启动后,会自动生成新文件。
版权声明:本博客所有文章除特殊声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明出处 litreily的博客!