启动原因确定

Android通过三个属性来确定启动原因。

  • ro.boot.bootreason:系统启动过程中,Init进程会将内核启动命令行中的androidboot.bootreason= 转化为ro.boot.bootreason。启动命令行中的bootreason由一般芯片供应商提供,内核在断电前会将启动原因写入专用的硬件资源或约定的内存地址。下次启动时,Bootloader就可以读取相应的资源来确定启动原因,然后添加到内核启动命令行中。如果芯片供应商不支持启动原因写入,androidboot.bootreason就可能不存在。
  • sys.boot.reason:系统启动时先将ro.boot.bootreason复制给sys.boot.reason。因为ro.boot.bootreason可能不存在,或者可能提供不准确、不可解析或不合规范的信息,在启动完成后会进一步更新sys.boot.reason。更新后的sys.boot.reason将提供准确可靠的、符合规范的启动原因。
  • persist.sys.boot.reason:Android系统在重启前会将重启原因写入到persist.sys.boot.reason中。这个属性可以用来在ro.boot.bootreason不存在时,协助确定启动原因。

准确的启动原因应该通过属性sys.boot.reason来获取,并且只有在用户数据加载完成后才能提供可靠信息。该属性的更新通过命令bootstat完成,可以在init.rc中找到启动的过程。

# Record boot complete metrics.on property:sys.boot_completed=1 && property:sys.logbootcomplete=1    # Converts bootloader boot reason to system boot reason    # Record boot_complete and related stats (decryption, etc).    # Record the boot reason.    # Record time since factory reset.    # Log all boot events.    exec_background - system log -- /system/bin/bootstat --set_system_boot_reason --record_boot_complete --record_boot_reason --record_time_since_factory_reset -l 

Bootstat对sys.boot.reason处理的简单流程如下,

  1. 读取ro.boot.bootreason,将其转化为符合规范的reason。
  2. 如果reason是watchdog,检查是否需要增加security标签。
  3. 如果reason是kernel_panic,从last klog中查找详细信息。
  4. 如果reason属于弱集(包含空值),从last klog中查找信息,检查是否电池耗尽引起死机,根据persist.sys.boot.reason修正reason。
  5. 如果上述操作依然无法确定reason,将值设置为reboot,
  6. 如果reason属于内核集,重写persist.sys.boot.reason

启动原因格式

在 Android 9 中,ro.boot.bootreason 的规范化启动原因格式使用以下语法:

,,

格式设置规则如下:

  • 小写
  • 无空格(可使用下划线)
  • 全部为可打印字符
  • 以英文逗号分隔reason、subreason,以及一个或多个detail。

    • reason是必须的,表示设备为什么必须重启或关机,优先级最高的原因。
    • subreason为选用,表示设备为什么必须重启或关机的简短摘要(或重启/关闭设备的人员)。
    • 一个或多个选用的 detail 值。detail 可以指向某个子系统,以协助确定是哪个具体系统导致了 subreason。您可以指定多个 detail 值,这些值通常应按照重要程度排序。不过,也可以报告多个具有同等重要性的 detail 值。

Reason分类

reason值必须是以下集合(分为内核原因、强原因和弱原因)之一:

  • 内核集:

    • "watchdog":通常表示触发了硬件watchdog引起重启。
    • "kernel_panic":表示系统发生了kernel panic。
  • 强集:

    • "recovery":通常为通过reboot接口或命令进入recovery模式。
    • "bootloader":通常为通过reboot接口或命令进入bootloader。
  • 弱集:

    • "cold":通常表示完全重置所有设备,包括内存。
    • "hard":通常表示硬件重置了状态,并且 ramoops 应保留持久性内容。
    • "warm":通常表示内存和设备保持某种状态,并且 ramoops(请参阅内核中的 pstore 驱动程序)后备存储空间包含持久性内容。
    • "shutdown"
    • "reboot":通常意味着 ramoops 状态和硬件状态未知。该值是与 coldhardwarm 一样的通用值,可提供关于设备重置深度的提示。

引导加载程序必须提供内核集或弱集 reason,强烈建议引导加载程序提供 subreason(如果可以确定的话)。例如,电源键长按(无论是否有 ramoops 备份)的启动原因为 "reboot,longkey"

第一个跨度 reason 不能是任何 subreasondetail 的组成部分。不过,由于用户空间无法产生内核集原因,因此可能会在弱集原因之后重复使用 "watchdog" 以及源代码的详细信息(例如 "reboot,watchdog,service_manager_unresponsive""reboot,software,watchdog")。

启动原因应该无需专家级内部知识即可解读,并且(或者)应该能让人看懂并提供直观报告。示例:"shutdown,vbxd"(糟糕)、"shutdown,uv"(较好)、"shutdown,undervoltage"(首选)。

Reason-Subreason组合

Android 保留了一组 reason-subreason 组合,在正常使用情况下不应过量使用这些组合;不过,如果组合能准确反映相关状况,则可根据具体情况加以使用。保留组合的示例包括:

  • "reboot,userrequested"
  • "shutdown,userrequested"
  • "shutdown,thermal"(来自 thermald
  • "shutdown,battery"
  • "shutdown,battery,thermal"(来自 BatteryStatsService
  • "reboot,adb"
  • "reboot,shell"
  • "reboot,bootloader"
  • "reboot,recovery"

参考文档:

Canonical Boot Reason

更多相关文章

  1. android 获取蓝牙已连接设备
  2. android获取版本信息、屏幕信息和设备编号
  3. Android 三星128G SD卡格式化为内部存储设备,显示为256G
  4. AS 3.0 INSTALL_FAILED_TEST_ONLY真正原因
  5. cryptfs-password-manager, Android设备加密密码管理器
  6. 判断android设备是否支持硬解码
  7. ueventd.rc 处理硬件设备权限和android init 对其解析
  8. 笔记,atmel4android,内核

随机推荐

  1. 我是如何自学Android,资料分享(2015 版)
  2. Android(安卓)通过百度地图SDK 实现地图
  3. android ANR产生原因和解决办法
  4. SystemServer分析
  5. Android(安卓)系统框架介绍
  6. LeakCanary使用详细教程(附Demo)
  7. Android(安卓)创建定时任务
  8. Android中通过view.getContext获取Activi
  9. Android中JNI的使用方法
  10. Android(安卓)LayoutInflater深入分析及