zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    centos7.6 使用yum安装mysql5.7
    解决hadoop本地库问题
    docker-compose 启动警告
    docker 安装zabbix5.0 界面乱码问题解决
    docker 部署zabbix问题
    zookeeper 超时问题
    hbase regionserver异常宕机
    (转载)hadoop 滚动升级
    hadoop Requested data length 86483783 is longer than maximum configured RPC length
    zkfc 异常退出问题,报错Received stat error from Zookeeper. code:CONNECTIONLOSS
  • 原文地址:https://www.cnblogs.com/liulaolaiu/p/11744967.html
Copyright © 2011-2022 走看看