Android系统启动

  • 一.Android系统启动概述
  • 1.启动电源以及系统启动
  • 2.引导程序BootLoader
  • 3.Linux内核启动
  • 4.init进程启动
  • 5.Zygote进程启动
  • 6.SystemServer进程启动
  • 7.AMS启动Launcher进程
  • 二.Android系统启动详解
  • 1.init进程的启动过程
  • init进程的main函数(init.cpp)执行过程:
  • 2.Zygote进程的启动过程
  • (C层)app_main.cpp中main函数的执行过程:
  • (java层)ZygoteInit.java中main方法的执行过程:
  • 3.SystemServer进程的启动过程
  • ZygoteInit.java中handleSystemServerProcess方法的执行过程:
  • ZygoteInit.java中zygoteInit方法的执行过程:
  • RuntimeInit.java中invokeStaticMain方法的执行过程:
  • ZygoteInit.java的main方法捕获Zygote.MethodAndArgsCaller异常的过程:
  • SystemServer进程main方法(SystemServer.java)的执行过程:
  • 4.Launcher进程的启动过程
  • ActivityManagerService.java中systemReady方法的执行过程:
  • startHomeActivityLocked方法的执行过程:
  • startHomeActivityLocked方法的执行过程


一.Android系统启动概述

android 开机启动sh android系统启动_java

1.启动电源以及系统启动

当按下电源时,引导芯片的代码从ROM预定义的位置开始执行。加载引导程序BootLoader到RAM中。

2.引导程序BootLoader

引导程序BootLoader把系统OS拉起并运行

3.Linux内核启动

当内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。在内核完成系统设置后,首先在系统文件中寻找init.rc文件,并启动init进程

4.init进程启动

1)创建和挂载启动所需的文件目录
2)初始化和启动属性服务
3)解析init.rc配置文件并启动Zygote进程

5.Zygote进程启动

1)创建AppRuntime并调用其start方法,启动Zygote进程
2)创建Java虚拟机并为Java虚拟机注册JNI方法
3)通过JNI调用ZygoteInit的main方法进入Zygote的Java框架
4)通过registerZygoteSocket方法创建服务端Socket,并通过runSelectLoop方法等待AMS的请求来创建新的应用程序进程
5)启动SystemServer进程

6.SystemServer进程启动

1)启动Binder线程池
2)创建SystemServiceManager
3)启动各种系统服务(AMS,PMS…)

7.AMS启动Launcher进程

1)通过PMS获取app的信息,将app的图标显示在界面上


二.Android系统启动详解

1.init进程的启动过程

    init进程是Android系统中用户空间的第一个进程,进程号为1。
在内核完成系统设置后,首先在系统文件中寻找init.rc文件,并启动init进程,执行init进程的入口函数main。init.rc配置文件是由Android初始化语言(Android Init Language)编写的脚本。

init进程的main函数(init.cpp)执行过程:

1)创建和挂载启动所需的文件目录
    挂载了tmpfs,devpts,proc,selinuxfs五种文件系统
2)初始化属性服务
    init进程调用property_init函数初始化属性服务。
    内部调用__system_property_area_init函数初始化属性内存区域。
3)设置子进程信号处理函数
    防止init的子进程成为僵尸进程
    僵尸进程:在Linux中,父进程使用fork创建子进程,在子进程终止时,若父进程不知道子进程终止,此时子进程虽已退出,但系统进程表仍保存子进程的信息。造成资源浪费,最终系统可能无法创建进程。
4)启动属性服务
    init进程调用start_property_service函数启动属性服务。
    a)内部首先创建非阻塞的Socket,调用listen函数进行监听连接,使之成为服务端提供属性服务,同时设置最大服务数为8。调用epoll函数监听数据变化,当有数据到来时,init进程将调用handle_property_set_fd函数进行处理。
    b)handle_property_set_fd函数内部将数据读出,交给handle_property_set函数处理。
    c)handle_property_set函数内部分成两部分处理,一部分处理控制属性(属性名以“ctl.”开头),一部分处理普通属性。当处理控制属性时,若权限满足,则调用handle_control_message函数处理。当处理普通属性时,若权限满足,则调用property_set函数处理。
    d)property_set函数内部首先会调用__system_property_find函数查找属性,判断属性存不存在,若不存在,则调用__system_property_add函数添加属性。若存在则判断属性名是否不能修改(以“ro.”开头,表示只读,不能修改),若不能修改,则直接返回,否则调用__system_property_update函数更新属性值。若属性名以“persist.”开头,则调用write_persistent_property函数处理。若属性名称以“persist.”开头,当设置这个属性时,其值也将写入/data/property。
5)解析init.rc文件,启动Zygote进程
    a)init进程解析init.rc配置文件,当解析Zygote进程的Service语句时,根据参数构造一个Service对象,根据选项域的内容填充Service对象,最后将Service对象加入Service链表中。
    b)init进程解析init.rc配置文件,当解析Command指令 class_start main时,遍历Service链表,因为Zygote进程的classname为main,所以会找到Zygote对应的Service,若Service没有在其对应的.rc文件中设置disabled选项,则会调用start函数启动Service。
    c)start函数内部会调用fork函数创建Service子进程,再调用execve函数启动Service子进程,进入Service的main函数中执行,在Service的main函数(app_main.cpp)中,会调用runtime的start函数启动Zygote进程。

2.Zygote进程的启动过程

    在Android系统中,DVM、ART、应用程序进程及SystemServer进程都是由Zygote进程创建。Zygote进程的初始名称为“app_process”,当Zygote进程启动后,Linux下的pctrl系统会调用app_process,将其名称替换为zygote。
    在init.rc配置文件中通过import命令引入了Zygote启动脚本。
    init.rc不会直接引入一个固定的文件,而是根据属性ro.zygote的内容引入。
ro.zygote的属性值有四种
    init.zygote32.rc:支持纯32位程序
    init.zygote32_64.rc:既支持32位程序,也支持64位程序。将启动两个Zygote进程,一个名为zygote,执行程序为app_process32,作为主模式。一个名为zygote_secondary,执行程序为app_process64,作为辅模式。
    init.zygote64.rc:支持纯64位程序
    init.zygote64_32.rc:既支持64位程序,也支持32位程序。将启动两个Zygote进程,一个名为zygote,执行程序为app_process64,作为主模式。一个名为zygote_secondary,执行程序为app_process32,作为辅模式。

(C层)app_main.cpp中main函数的执行过程:

1)判断若为Zygote进程,则调用AppRuntime对象的start函数启动Zygote进程
    a)调用startVm函数启动Java虚拟机
    b)调用startReg函数为Java虚拟机注册JNI方法
    c)获取类名为com.android.internal.os.ZygoteInit的类,并找到它的main方法
    d)通过JNI调用ZygoteInit.java的main方法

(java层)ZygoteInit.java中main方法的执行过程:

1)调用zygoteServer的registerServerSocket方法创建一个名为zygote的服务端socket
    用于等待AMS请求Zygote进程创建新的应用程序。
    a)通过传入的socketName拼接fullSocketName。(为ANDROID_SOCKET_zygote)
    b)将fullSocketName转换为环境变量的值
    c)将环境变量的值转换为文件描述符的参数
    d)创建文件描述符,并设置参数
    e)创建服务端Socket(LocalServerSocket),传入文件描述符作为参数。
2)调用preload方法预加载类和资源
3)调用startSystemServer方法启动SystemServer进程
    a)创建args数组
    用于保存SystemServer的启动参数
    SystemServer进程的用户id和用户组id被设置为1000。
    并且拥有用户组1001~1010、1018、1021、1032、3001~3010的权限。
    进程名为system_server。
    启动的类名为com.android.server.SystemServer。
    b)将args数组封装成Arguments对象
    c)调用Zygote的forkSystemServer方法,传入Arguments对象,创建SystemServer进程
    d)调用handleSystemServerProcess方法处理SystemServer进程
4)调用zygoteServer的runSelectLoop方法等待AMS请求创建新的应用程序
    a)保存创建的服务端Socket的文件描述符到ArrayList
    b)无限循环等待AMS的请求
        i)通过poll机制监听文件变化
        ii)若有客户端Socket连接了服务端Socket,则调用acceptCommandPeer方法创建一个ZygoteConnection对象。并将对象保存到ArrayList,对象的文件描述符保存到ArrayList。
        iii)否则调用ZygoteConnection对象的runOnce方法创建新的应用程序进程。若创建成功,则将该对象及其文件描述符从ArrayList和ArrayList中移除。

3.SystemServer进程的启动过程

    SystemServer进程主要用于创建系统服务

ZygoteInit.java中handleSystemServerProcess方法的执行过程:

1)调用createPathClassLoader创建PathClassLoader
2)调用ZygoteInit的zygoteInit方法,传入PathClassLoader

ZygoteInit.java中zygoteInit方法的执行过程:

1)调用ZygoteInit的nativeZygoteInit方法启动Binder线程池
2)调用RuntimeInit的applicationInit方法进入SystemServer的main方法
    a)调用invokeStaticMain方法

RuntimeInit.java中invokeStaticMain方法的执行过程:

1)通过类名获取SystemServer类
2)找到SystemServer类的main方法
3)通过抛异常的方式启动SystemServer进程
    创建Zygote.MethodAndArgsCaller对象,传入SystemServer类的main方法作为参数,抛出Zygote.MethodAndArgsCaller异常。

ZygoteInit.java的main方法捕获Zygote.MethodAndArgsCaller异常的过程:

1)调用MethodAndArgsCalls对象的run方法
    a)通过反射(invoke方法),调用SystemServer类的main方法

    为什么要采用抛异常的方式而不是直接在invokeStaticMain方法中调用SystemServer类的main方法?
    通过抛异常的处理会清除所有的设置过程需要的堆栈帧,让SystemServer的main方法看起来像是SystemServer进程的入口方法。

SystemServer进程main方法(SystemServer.java)的执行过程:

1)创建SystemServer类对象
2)调用SystemServer对象的run方法
    a)调用Looper的prepareMainLooper方法创建消息Looper
    b)调用System的loadLibrary方法加载动态库(libandroid_servers.so)
    c)调用createSystemContext方法创建系统的Context
    d)将Context作为参数,创建SystemServiceManager对象
    用于对系统服务进行创建、启动和生命周期的管理
    e)调用startBootstrapServices方法启动引导服务
    Android中将系统服务分为三种:引导服务、核心服务、其他服务,共100多种。
    i)Installer:系统安装apk的一个服务类,启动完Installer服务后才能启动其他的系统服务
    ii)ActivityManagerService:负责四大组件的启动、切换、调度
    iii)PowerManagerService
    iv)LightsService:管理和显示背光LED
    v)DisplayManagerService
    vi)UserManagerService:管理多用户
    vii)SensorService:提供传感器服务
    viii)PackageManagerService:用来对APK进行安装、解析、删除、卸载等

    f)调用startCoreServices方法启动核心服务
    核心服务共四种:
    i).DropBoxManagerService:用于生成和管理系统运行时生成的一些日志文件
    ii).BatteryService:管理电池相关的服务
    iii).UsageStatsService:收集用户每一个App的频率和使用时长
    iv).webViewUpdateService:WebView更新服务
    g)调用startOtherServices方法启动其他服务
    i).CameraService:摄像头相关服务
    ii).AlarmManagerService:全局定时器管理
    iii).InputManagerService:管理输入事件
    iv).WindowManagerService:窗口管理服务
    v).VrManagerService:VR模式管理服务
    vi).BluetoothService:蓝牙管理服务
    vii).NotificationManagerService:通知管理服务
    viii).DeviceStorageMonitorService:存储相关管理服务
    ix).LocationManagerService:定位管理服务
    x).AudioService:音频相关管理服务

系统服务的两种启动方式:
1)调用SystemServiceManager对象的startService方法
    a)保存传入的SystemService对象到ArrayList中
    b)调用传入的SystemService对象的onStart方法
2)调用指定系统服务的main方法
    a)自检初始的设置
    b)将自身注册到ServiceManager中

4.Launcher进程的启动过程

    SystemServer进程在启动时会先后启动AMS和PMS,PMS启动后会将系统中的应用程序安装完成。之后AMS将会启动Launcher进程。
    Launcher进程的入口为AMS的systemReady方法,该方法在SystemServer.java的startOtherServices方法中被调用。

ActivityManagerService.java中systemReady方法的执行过程:

调用ActivityStackSupervisor对象的resumeFocusedStackTopActivityLocked方法

resumeFocusedStackTopActivityLocked方法的执行过程:
调用ActivityStack对象的resumeTopActicityUncheckedLocked方法

resumeTopActicityUncheckedLocked方法的执行过程:
调用resumeTopActicityInnerLocked方法

resumeTopActicityInnerLocked方法的执行过程:
调用ActivityStackSupervisor对象的resumeHomeStackTask方法

resumeHomeStackTask方法的执行过程:
调用ActivityManagerService对象的startHomeActivityLocked方法

startHomeActivityLocked方法的执行过程:

1)判断系统的运行模式和要启动的Activity的Action是否满足要求
    系统的运行模式有三种:非工厂模式、低级工厂模式、高级工厂模式
2)调用getIntent方法获取启动Launcher进程所需的Intent
    Action为Intent.ACTION_MAIN,category为Intent.CATEGORY_HOME
3)调用ActivityStarter对象的startHomeActivityLocked方法启动Launcher进程

startHomeActivityLocked方法的执行过程

1)调用ActivityStackSupervisor对象的moveHomeStackTaskToTop方法,Launcher放入HomeStack中
2)调用startActivityLocked方法,进入到启动一般的Activity的流程,最终调用Launcher进程Activity的onCreate方法,显示界面