重启进入recovery reboot,反复循环
前言
输入 – 内化 – 输出 – 价值
xmind:
1. 问题现象:
- 编译user版本image并烧录;
- 开机过程中出现重启;
- 重启后界面显示清除中;
- 上述清除过程完成后,重启;
- 一直重复上述2~4循环;
从现象来看:
1. 系统遇到异常,该异常比较严重会触发重启;
2. 重启后会进入recovery界面(也可能是恢复出厂设置),做清除动作;
2. 分析过程
结合现象和初步log,找到怀疑点,通过实验的方式逐步缩小范围,最终定位并解决问题;
2.1 串口打印初步分析:
第一步:查看重启原因:
打印信息为:ARCH_RESET,且命令为recovery,这一段打印在函数arch_reset中:
(200709_09:11:00.173)[ 101.418221] <0>-(0)[1:init]ARCH_RESET happen!!!
(200709_09:11:00.173)[ 101.418795] <0>-(0)[1:init]arch_reset: cmd = recovery
(200709_09:11:00.173)[ 101.419441] <0>-(0)[1:init]CPU: 0 PID: 1 Comm: init Tainted: G W O 4.9.117 #3
(200709_09:11:00.173)[ 101.420456] <0>-(0)[1:init]Hardware name: AC8257V/WAB (DT)
(200709_09:11:00.173)[ 101.421149] <0>-(0)[1:init]Call trace:
(200709_09:11:00.173)[ 101.421643] <0>-(0)[1:init][] dump_backtrace+0x0/0x294
(200709_09:11:00.173)[ 101.422492] <0>-(0)[1:init][] show_stack+0x18/0x20
(200709_09:11:00.173)[ 101.423300] <0>-(0)[1:init][] dump_stack+0xcc/0x104
(200709_09:11:00.173)[ 101.424119] <0>-(0)[1:init][] arch_reset+0x48/0x164
(200709_09:11:00.173)[ 101.424934] <0>-(0)[1:init][] mtk_arch_reset_handle+0x24/0x40
(200709_09:11:00.173)[ 101.425861] <0>-(0)[1:init][] atomic_notifier_call_chain+0x4c/0x84
(200709_09:11:00.173)[ 101.426838] <0>-(0)[1:init][] do_kernel_restart+0x24/0x2c
(200709_09:11:00.173)[ 101.427717] <0>-(0)[1:init][] machine_restart+0x40/0x50
(200709_09:11:00.173)[ 101.428575] <0>-(0)[1:init][] kernel_restart+0x16c/0x17c
(200709_09:11:00.173)[ 101.429442] <0>-(0)[1:init][] SyS_reboot+0x140/0x20c
(200709_09:11:00.174)[ 101.430267] <0>-(0)[1:init][] el0_svc_naked+0x34/0x38
(200709_09:11:00.174)[ 101.431099] <0>-(0)[1:init]we can get console_sem
(200709_09:11:00.174)[ 101.431695] <0>-(0)[1:init]mtk_rtc_common: rtc_mark_recovery
(200709_09:11:00.174)[ 101.432412] <0>-(0)[1:init]mtk_rtc_hal_common: hal_rtc_set_spare_register: cmd[2], set rg[0x5b4, 0x3 , 4] = 0x1
(200709_09:11:00.174)[ 101.434382] <0>-(0)[1:init]mtk_rtc_hal_common: mon = 1, day = 20481, hour = 16384
其中对应arch_reset中cmd为recovery的处理是:rtc_mark_recovery 这个function在两个地方有实现:
- mtk_rtc.h中定义为:#define rtc_mark_recovery() ({0;}) 这里直接返回0;由配置CONFIG_MTK_RTC控制;
- mtk_rtc_common.c中定义为:rtc_mark_recovery() 这里有实际实现;
- 打印function name;
- hal_rtc_set_spare_register() 这个就是实际读写寄存器操作;
- clear alarm setting
- 将time写入rtc 寄存器;
所以实际这里就是rtc的写入操作,则需要找到的就是arch_reset的触发者;
第二步:根据刚才的信息继续往前看init进程的操作
是从system_server中拿到的sys.powerctl=‘reboot,recovery’ 说明是sys