• Android系统启动过程分析


    1. 系统启动流程简介

    在linux里,每一个进程将有4G的空间,内核将这4G字节的空间分为两部分。最高的1G字节供内核使用,称为“内核空间”。而较低的3G字节供各个进程使用,称为“用户空间”。

    在Linux内核启动后,init 1 (1号进程)将作为第一个用户空间 的进程来启动Android系统,该启动流程可以分为如下5个阶段,如下图:




    (1) 启动准备:该阶段包括 创建文件系统的基本目录、打开基本输入、输出设备,初始化日志功能等;

    (2) 解析init.rc文件:该阶段对init.rc脚本文件进行解析,主要对Service(服务)和Action(动作)进行解析。其中,Service由命令(Command) 和 一系列服务的附加内容(Option,选项)组成,如:“service vold /system/bin/vold”为一个Service,而“socket vold stream 0660 root mount“则为配合该服务使用的Option; Action则由 一系列的命令 组成,如:“on init mkdir /system”为系统初始化时建立系统文件夹的Action;

    (3) 触发需要执行的action:Action需要在Triggers(触发条件)中调用,本阶段对需要执行的Action进行触发,并根据触发条件将需要执行的Action放入Action队列;

    (4) 执行在action队列中的命令:对上一阶段触发的Action以及Service进行执行。并在此过程中,派生了Zygote和Service Manager两个非常重要的进程;

    (5) 循环处理事件:init进程进入无限循环,处理设备插入/拔出,服务属性状态变化和signal事件等。

    2. 源码分析结果

    对android-2.3.3_r1版本中的如下源码文件进行分析:

    (1) init.c:路径为system/core/init/init.c

    (2) init_parser.c:路径为system/core/init/ init_parser.c

    (3) builtins.c:路径为system/core/init/ builtins.c

    (4) property_service.c:路径为system/core/init/property_service.c

    (5) keycords.c:路径为system/core/init/keycords.c

    (6) signal_handler.c:路径为system/core/init/signal_handler.c

    总结得出系统启动流程对应的源代码文件及函数如下(注:以下函数间的顺序执行关系使用“>”表示;函数间的调用执行关系使用“à”表示)

    2.1 第一阶段(启动准备)

    具体的函数执行过程如下:

     mkdir > mount > open_devnull_stdio > log_init

    2.2 第二阶段(解析init.rc文件)

    具体的函数调用过程如下:

     init_parse_config_fileàparse_configà parse_new_sectionàparse_service (或者parse_action)-> parse_line_service(或者parce_line_action)

    2.3 第三阶段(触发需要执行的action)

    具体的调用过程如下:

     action_for_each_trigger("boot", action_add_queue_tail);à action_add_queue_tail ( class_start default) à action_remove_queue_head à do_class_start

    2.4 第四阶段(执行在action队列中的命令)

    具体的调用过程如下:

     execute_one_commandà action_remove_queue_head àdo_class_start àservice_for_each_classà service_start_if_not_disabledà service_start

    2.5 第五阶段(循环处理)

    具体的循环处理过程如下:

    1. for (; ;) { 
    2. poll > handle_property_set_fd > handle_keychord > handle_signal 

    2.6 主要函数介绍

    函数名 所在文件 功能概述
    main system/core/init/init.c 1号进程init的入口函数。主要分析init.rc配置文件,执行基本的action和启动必备的native service,然后进入一个infinite loop 处理来自property, signal的event 
    mkdir system/core/init/init.c 建立文件系统的基本目录
    mount system/core/init/init.c 装载文件系统
    open_devnull_stdio system/core/init/init.c 打开基本输入、输出设备
    log_init system/core/init/init.c 初始化日志功能
    init_parse_config_file system/core/init/ init_parser.c 读取init.rc文件内容到内存数据区
    parse_config system/core/init/ init_parser.c 识别init.rc文件中的 Section(service and action series )和Text
    parse_new_section system/core/init/ init_parser.c 识别section类别
    parse_service system/core/init/ init_parser.c 对service section第一行进行分析
    parse_line_service system/core/init/ init_parser.c 对service section的option选项进行分析
    parse_action system/core/init/ init_parser.c 对action section第一行进行分析
    parse_line_action system/core/init/ init_parser.c 对action section的每一行独立的命令进行分析
    action_for_each_trigger system/core/init/ init_parser.c 触发某个action的执行 
    action_add_queue_tail system/core/init/ init_parser.c 将某个action的从action_list加到action_queue
    execute_one_command system/core/init/init.c 执行当前action的一个command
    action_remove_queue_head system/core/init/ init_parser.c 从action_queue链表上移除头结点(action)
    do_class_start system/core/init/ builtins.c class_start default对应的入口函数,主要用于启动native service
    service_for_each_class system/core/init/ init_parser.c 遍历service_list链表上的所有结点
    service_start_if_not_disabled system/core/init/ builtins.c 判断service的flag是否disabled,如果不是,则调用相关函数,准备启动service
    service_start system/core/init/init.c 启动service的主要入口函数,设置service数据结构的相关数据结构后,调用fork创建一个新的进行,然后调用execve执行新的service
    fork Lib function(ulibc) 进程创建函数
    execve Lib function(ulibc) 调用执行新的service
    poll Lib function(ulibc) 查询property_set_fd,signal_fd和keychord_fd文件句柄是否有服务请求
    handle_property_set_fd system/core/init/property_service.c 处理系统属性服务请求,如:service, wlan和dhcp等等
    handle_keychord system/core/init/keycords.c 处理注册在service structure上的keychord,通常是启动service
    handle_signal system/core/init/signal_handler.c 处理SIGCHLD signal
  • 相关阅读:
    CoreBluetooth
    IOS Monkey 测试
    Ruby+appium实现截图、滑屏、长按、日志输出到本地文件夹
    maven中GroupID 和ArtifactID怎么写
    MAC安装Eclipse及对其进入相关配置
    单元测试断言利器 AssertJ
    python+appium app自动化的方法实例运用
    美团接口自动化测试实践
    appium滑动操作总结
    Appium+python自动化-Appium Python API
  • 原文地址:https://www.cnblogs.com/liulaolaiu/p/11744968.html
Copyright © 2020-2023  润新知