Android 系统自动重启Bug(高通平台)
點擊打開鏈接
最近客戶反饋了一個Bug,我們的系統用著用著會自動重啟,尤其是在撥號的時候極容易死機或者進入下載模式。根據老大和高通的支持得到了一個解決方案。
? ?在Android系統中,有這么一個文件夾:sys/bus/msm_subsys/devices,里面分別有三個文件夾:subsys0、subsys1、subsys2,這三個都是android系統中運行的子系統。根據高通的解釋,subsys0主要是負責adsp(音視頻媒體的相關服務)的啟動和運行,subsys1主要負責modem(撥打電話和藍牙wifi等服務)的業務處理,subsys2主要管理wcnss的相關業務,當然還有很多其它模塊的子系統,就不一一舉例了。
??subsys0、subsys1、subsys2都有個叫restart_level的文件,用cat命令查看發現這些文件的內容都是SYSTEM,就是這個SYSTEM導致系統在遇到問題的時候死機或者下載模式,應該要把restart_level的設置為related,當系統遇到難于處理的問題的時候,比如打電話過程中遇到錯誤,那就只重啟subsys1子系統(子系統都是在后臺運行的,重啟過程用戶是看不到的),android系統本身是不重啟或進入下載模式的,這樣用戶體驗也好些。
? 那有人會問了,既然這樣那高通為什么不默認把這些值設為related呢?其實我也有相同的疑問,我老大說如果一遇到問題就讓子系統重啟那很多BUG就測不出來了,這樣做是讓有些BUG更好的浮出水面。
? 現在我們的機器經常在撥打電話的時候死掉或者進入下載模式(download模式),那應該就是subsys1這個子系統出了問題了。找subsys1的相關代碼,在init.qcom.ssr.sh中有調用,源碼位置:device/qcom/common/rootdir/etc/init.qcom.ssr.sh,是個腳本文件,代碼貼出來:
#!/system/bin/sh
# Copyright (c) 2013, The Linux Foundation. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# ? ? * Redistributions of source code must retain the above copyright
# ? ? ? notice, this list of conditions and the following disclaimer.
# ? ? * Redistributions in binary form must reproduce the above copyright
# ? ? ? notice, this list of conditions and the following disclaimer in the
# ? ? ? documentation and/or other materials provided with the distribution.
# ? ? * Neither the name of The Linux Foundation nor
# ? ? ? the names of its contributors may be used to endorse or promote
# ? ? ? products derived from this software without specific prior written
# ? ? ? permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NON-INFRINGEMENT ARE DISCLAIMED. ?IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
ssr_str="$1"
IFS=,
ssr_array=($ssr_str)
declare -i subsys_mask=0
# check user input subsystem with system device
ssr_check_subsystem_name()
{
? ? declare -i i=0
? ? subsys=`cat /sys/bus/msm_subsys/devices/subsys$i/name`
? ? while [ "$subsys" != "" ]
? ? do
? ? ? ? if [ "$subsys" == "$ssr_name" ]; then
? ? ? ? ? ? return 1
? ? ? ? fi
? ? ? ? i=$i+1
? ? ? ? subsys=`cat /sys/bus/msm_subsys/devices/subsys$i/name`
? ? done
? ? return 0
}
# set subsystem mask to indicate which subsystem needs to be enabled
for num in "${!ssr_array[@]}"
do
? ? case "${ssr_array[$num]}" in
? ? ? ? "1")
? ? ? ? ? ? subsys_mask=0
? ? ? ? ;;
? ? ? ? "riva")
? ? ? ? ? ? subsys_mask=$subsys_mask+1
? ? ? ? ;;
? ? ? ? "3")
? ? ? ? ? ? subsys_mask=63
? ? ? ? ;;
? ? ? ? "adsp")
? ? ? ? ? ? ssr_name=adsp
? ? ? ? ? ? if ( ssr_check_subsystem_name ); then
? ? ? ? ? ? ? ? subsys_mask=$subsys_mask+2
? ? ? ? ? ? fi
? ? ? ? ;;
? ? ? ? "modem")
? ? ? ? ? ? ssr_name=modem
? ? ? ? ? ? if ( ssr_check_subsystem_name ); then
? ? ? ? ? ? ? ? subsys_mask=$subsys_mask+4
? ? ? ? ? ? fi
? ? ? ? ;;
? ? ? ? "wcnss")
? ? ? ? ? ? ssr_name=wcnss
? ? ? ? ? ? if ( ssr_check_subsystem_name ); then
? ? ? ? ? ? ? ? subsys_mask=$subsys_mask+8
? ? ? ? ? ? fi
? ? ? ? ;;
? ? ? ? "venus")
? ? ? ? ? ? ssr_name=venus
? ? ? ? ? ? if ( ssr_check_subsystem_name ); then
? ? ? ? ? ? ? ? subsys_mask=$subsys_mask+16
? ? ? ? ? ? fi
? ? ? ? ;;
? ? ? ? "external_modem")
? ? ? ? ? ? ssr_name=external_modem
? ? ? ? ? ? if ( ssr_check_subsystem_name ); then
? ? ? ? ? ? ? ? subsys_mask=$subsys_mask+32
? ? ? ? ? ? fi
? ? ? ? ;;
? ? esac
done
# enable selected subsystem restart
if [ $((subsys_mask & 1)) == 1 ]; then
? ? echo 1 > /sys/module/wcnss_ssr_8960/parameters/enable_riva_ssr
else
? ? echo 0 > /sys/module/wcnss_ssr_8960/parameters/enable_riva_ssr
fi
if [ $((subsys_mask & 2)) == 2 ]; then
? ? echo "related" > /sys/bus/msm_subsys/devices/subsys0/restart_level
else
? ? echo "system" > /sys/bus/msm_subsys/devices/subsys0/restart_level
fi
if [ $((subsys_mask & 4)) == 4 ]; then
? ? echo "related" > /sys/bus/msm_subsys/devices/subsys1/restart_level
else
? ? echo "system" > /sys/bus/msm_subsys/devices/subsys1/restart_level
fi
if [ $((subsys_mask & 8)) == 8 ]; then
? ? echo "related" > /sys/bus/msm_subsys/devices/subsys2/restart_level
else
? ? echo "system" > /sys/bus/msm_subsys/devices/subsys2/restart_level
fi
if [ $((subsys_mask & 16)) == 16 ]; then
? ? echo "related" > /sys/bus/msm_subsys/devices/subsys3/restart_level
else
? ? echo "system" > /sys/bus/msm_subsys/devices/subsys3/restart_level
fi
if [ $((subsys_mask & 32)) == 32 ]; then
? ? echo "related" > /sys/bus/msm_subsys/devices/subsys4/restart_level
else
? ? echo "system" > /sys/bus/msm_subsys/devices/subsys4/restart_level
fi
if [ $((subsys_mask & 63)) == 63 ]; then
? ? echo 3 > /sys/module/subsystem_restart/parameters/restart_level
else
? ? echo 1 > /sys/module/subsystem_restart/parameters/restart_level
fi
代碼中有這么一段:
if [ $((subsys_mask & 4)) == 4 ]; then
? ? echo "related" > /sys/bus/msm_subsys/devices/subsys1/restart_level
else
? ? echo "system" > /sys/bus/msm_subsys/devices/subsys1/restart_level
fi
? 判斷subsys_mask和4的位運算來給subsys1賦值, 要么賦值related,要么賦值system。subsys_mask的值是通過調用這個腳本時傳進來的參數獲得的,再就是找到調用這個腳本的地方,init.qcom.rc, 源碼位置:device/qcom/common/rootdir/etc/init.qcom.rc,這里要說明一下,*.rc的文件中加載的都是系統的服務,里面的值都是寫在系統文件里的,比如build.prop文件,當這些值發生改變的時候(比如進入shell模式可以setprop xxx yyy來更改系統服務),這個服務就會重新執行一遍,以加載不同的文件屬性。
?里面有這么一段:
# SSR setting
on property:persist.sys.ssr.restart_level=*
? ? exec /system/bin/sh /init.qcom.ssr.sh ${persist.sys.ssr.restart_level}
? 這里就是調用那個腳本的地方,也就是說當property:persist.sys.ssr.restart_level這個屬性發生改變的時候就執行init.qcom.ssr.sh這個腳本,并且把自己當參數傳給ssr_str。再回到init.qcom.ssr.sh這個腳本文件,ssr_str是個數組,也就是說property:persist.sys.ssr.restart_level這個屬性可以是有多個參數的(參數之間以逗號分隔),不同的參數給subsys_mask賦不同的值,因為我們的問題是出在subsys1,所以要讓subsys_mask & 4 == 4,就需要將property:persist.sys.ssr.restart_level的參數設為modem,就會將/sys/bus/msm_subsys/devices/subsys1/restart_level的值設為related,讓subsys1子系統在遇到處理不了的問題的時候自行后臺重啟。
? 剩下的問題就簡單了,在系統中預先給property:persist.sys.ssr.restart_level賦值一個modem值,那系統屬性subsys1/restart_level的值就是related了,在buildspec.mk中加上這一句:ADDITIONAL_BUILD_PROPERTIES += persist.sys.ssr.restart_level=$(call add2prop,$(PWV_SSR_RESTART_LEVEL)),PWV_SSR_RESTART_LEVEL是自己定義的宏,其值就是modem,編譯,升級軟件,驗證OK。
? 覺得這些問題還是挺有價值的,就記錄下來,以便以后回味。
總結
以上是生活随笔為你收集整理的Android 系统自动重启Bug(高通平台)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Makefile常用函数总结
- 下一篇: Android4.3 屏蔽HOME按键返