Android init介绍(下)

Posted 北落不吉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android init介绍(下)相关的知识,希望对你有一定的参考价值。

上一篇: <Android init介绍(上)>

5. AIL

在init启动过程中,系统服务等均是通过解析rc文件来启动,而rc文件则是由android初始化语言(Android Init Language)的脚本写成

5.1 格式介绍

AIL以Section为区分,由如下import、action和service三类Section

5.1.1 import section

主要用于导入其他rc文件

import <path>

上面的命令将导入path指定的文件然后被解析为action和service

5.1.2 action section

action section由trigger和一些command组成
以on开头,trigger是判断条件,command是具体执行一些操作;当满足trigger条件时,执行这些command

格式如下

on <trigger> [&& <trigger>]*
   <command>
   <command>
   <command>

trigger的内容包含如下

/* 
 * 事件触发器
 * -- 表示当trigger early或QueueEventTrigger("early")调用时触发
 */
on early

/* 
 * 属性触发器
 * -- 表示当sys.boot_from_charger_mode的值通过property_set设置为1时触发
 */
on property:sys.boot_from_charger_mode=1

/*
 * 多个条件用&&连接
 * -- 表示当zygote-start触发并且ro.crypto.state属性值为unencrypted时触发
on zygote-start && property:ro.crypto.state=unencrypted

command就是一些具体的操作,由BuiltinFunctionMap::Map(builtin_functions)定义来执行特定的操作

    // 终止charger服务
    class_stop charger
    // 开启watchdogd服务
    start watchdogd
    // 触发late-init
    trigger late-init

5.1.3 service section

service section由service加上一些option组成
以service开头,name是为服务名称,pathname为服务的执行文件路径,argument表示执行文件带的参数,option表示这个服务的一些配置,optionOptionParserMap::Map(option_parsers)定义

service <name> <pathname> [ <argument> ]*
   <option>
   <option>
   ...

5.2 文件解析

/*
 * 初始化Subcontext
 */
InitializeSubcontexts()
    SelinuxHasVendorInit()
        Subcontext::Subcontext()
            Subcontext::Fork()
                fork()
                execv("/init", {"/init", "subcontext", "u:r:vendor_init:s0", fd, nullptr})

// 创建ActionManager实例
ActionManager::GetInstance()
// 创建ServiceList实例
ServiceList::GetInstance()

LoadBootScripts()
    CreateParser(ActionManager, ServiceList)
    Parser::ParseConfig("/init.rc")
    Parser::ParseConfig("/system/etc/init")
    Parser::ParseConfig("/vendor/etc/init")
        Parser::ParseConfigFile()
            Parser::ParseData()

可以看出rc文件文件主要位于[/]、[/system/etc/init/]、[/vendor/etc/init/]

# tree /
.
+--- init.environ.rc
+--- init.rc
+--- init.recovery.hardware.rc
+--- init.usb.configfs.rc
+--- init.usb.rc
+--- init.zygote32.rc
+--- init.zygote64_32.rc
# tree /system/etc/init/
.
+--- android.hidl.allocator@1.0-service.rc
+--- atrace.rc
+--- atrace_userdebug.rc
+--- audioserver.rc
+--- blank_screen.rc
+--- bootanim.rc
+--- bootstat-debug.rc
+--- bootstat.rc
+--- cameraserver.rc
+--- com.android.car.powertestservice.rc
+--- com.android.car.procfsinspector.rc
+--- drmserver.rc
+--- dumpstate.rc
+--- gatekeeperd.rc
+--- gsi
|   +--- init.vndk-27.rc
+--- hwservicemanager.rc
+--- incidentd.rc
+--- init-debug.rc
+--- init.gsi.rc
+--- installd.rc
+--- keystore.rc
+--- lmkd.rc
+--- logcatd.rc
+--- logd.rc
+--- logtagd.rc
+--- mdnsd.rc
+--- mediadrmserver.rc
+--- mediaextractor.rc
+--- mediametrics.rc
+--- mediaserver.rc
+--- mtpd.rc
+--- netd.rc
+--- perfetto.rc
+--- perfprofd.rc
+--- racoon.rc
+--- recovery-persist.rc
+--- recovery-refresh.rc
+--- servicemanager.rc
+--- statsd.rc
+--- storaged.rc
+--- surfaceflinger.rc
+--- thermalservice.rc
+--- tombstoned.rc
+--- uncrypt.rc
+--- update_engine.rc
+--- update_verifier.rc
+--- usbd.rc
+--- vdc.rc
+--- vold.rc
+--- vr_hwc.rc
+--- wait_for_keymaster.rc
+--- wifi-events.rc
+--- wificond.rc
# tree /vendor/etc/init/
.
+--- android.automotive.evs.manager@1.0.rc
+--- android.hardware.audio@2.0-service.rc
+--- android.hardware.boot@1.0-service.rc
+--- android.hardware.broadcastradio@intel-service.rc
+--- android.hardware.camera.provider@2.4-external-service.rc
+--- android.hardware.camera.provider@2.4-service.rc
+--- android.hardware.cas@1.0-service.rc
+--- android.hardware.configstore@1.1-service.rc
+--- android.hardware.drm@1.0-service.rc
+--- android.hardware.drm@1.1-service.clearkey.rc
+--- android.hardware.dumpstate@1.0-service.rc
+--- android.hardware.gatekeeper@1.0-service.rc
+--- android.hardware.graphics.allocator@2.0-service.rc
+--- android.hardware.graphics.composer@2.1-service.rc
+--- android.hardware.health@2.0-service.`hardware`.rc
+--- android.hardware.keymaster@3.0-service.rc
+--- android.hardware.light@2.0-service.rc
+--- android.hardware.media.omx@1.0-service.rc
+--- android.hardware.memtrack@1.0-service.rc
+--- android.hardware.power@1.2-service.rc
+--- android.hardware.sensors@1.0-service.rc
+--- android.hardware.thermal@1.1-service.`hardware`.rc
+--- android.hardware.usb@1.0-service.rc
+--- android.hardware.wifi@1.0-service.rc
+--- daemon_cl.rc
+--- hostapd.android.rc
+--- host_server.rc
+--- hw
|   +--- init.coredump.rc
|   +--- init.crashlogd.rc
|   +--- init.dvc_desc.rc
|   +--- init.`hardware`.rc
|   +--- init.kernel.rc
|   +--- init.logs.rc
|   +--- init.npk.rc
+--- name_server.rc
+--- rild.rc
+--- SampleDriverAll.rc
+--- vndservicemanager.rc

5.3 事件触发

/*
 * am为ActionManager::GetInstance()
 * QueueEventTrigger构造了一个EventTrigger对象, 放到事件队列中
 * !!!注意此处并没有触发
 */ 
am.QueueEventTrigger("early-init");
am.QueueEventTrigger("init");
am.QueueEventTrigger("late-init");

/*
 * QueueBuiltinAction构造了一个Action对象, 放到事件队列和动作队列中
 * !!!注意此处并没有触发
 */ 
am.QueueBuiltinAction(wait_for_coldboot_done_action,  "wait_for_coldboot_done");
am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction,     "MixHwrngIntoLinuxRng");
am.QueueBuiltinAction(SetMmapRndBitsAction,           "SetMmapRndBits");
am.QueueBuiltinAction(SetKptrRestrictAction,          "SetKptrRestrict");
am.QueueBuiltinAction(keychord_init_action,           "keychord_init");
am.QueueBuiltinAction(console_init_action,            "console_init");
am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction,     "MixHwrngIntoLinuxRng");
am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");

while (true) {
    ...
    if (!(waiting_for_prop || Service::is_exec_service_running())) {
        // 依次触发early-init、init、late-init的命令
        am.ExecuteOneCommand();
    }
    ...
}

5.4 详细过程

Android启动过程中重要的trigger事件如下

- early-init
  +--- start ueventd
- init
- charger                   /* 当ro.bootmode为charger执行 */
- late-init
  +--- early-fs
  +--- fs                   /* 挂载系统分区 */
     +--- mount_all /vendor/etc/fstab.${ro.hardware}
  +--- post-fs              /* 执行依赖文件系统的命令 */
     +--- load_system_props
        +--- load_properties_from_file("/system/build.prop", NULL);
        +--- load_properties_from_file("/odm/build.prop", NULL);
        +--- load_properties_from_file("/vendor/build.prop", NULL);
        +--- load_properties_from_file("/factory/factory.prop", "ro.*");
        +--- load_recovery_id_prop();
     +--- start logd
     +--- start servicemanager
     +--- start hwservicemanager
     +--- start vndservicemanager
  +--- late-fs
     +--- class_start early_hal
  +--- post-fs-data         /* data分区初始化 */
     +--- start vold
     +--- installkey /data
     +--- bootchart start
     +--- init_user0
  +--- zygote-start
     +--- exec_start update_verifier_nonencrypted
     +--- start netd
     +--- start zygote
     +--- start zygote_secondary
  +--- load_persist_props_action
     +--- load_persist_props
     +--- LoadPersistentProperties()
     +--- start logd
     +--- start logd-reinit
  +--- firmware_mounts_complete
     +--- rm /dev/.booting
  +--- early-boot
  +--- boot

  +--- property:sys.boot_completed=1
     +--- bootchart stop

参考:
<Android系统启动流程>
<Android 9.0 init进程分析>
<Android 8.1 启动篇(一) -- 深入研究 init>

以上是关于Android init介绍(下)的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio片段没有响应后按按钮

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情

Android系统10 RK3399 init进程启动(三十六) 属性property操作API

Android:片段内的按钮操作

onActivityResult 未在 Android API 23 的片段上调用

Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段