AndroidL系统启动及加载流程分析
- 格式:docx
- 大小:348.41 KB
- 文档页数:10
Android L系统启动及加载流程分析
1、概述
Android L的启动可以分为几个步骤:Linux内核启动、init进程启动、native系统服务及java系统服务启动、Home启动,主要过程如下图:
图1
整个启动流程跟4.4及之前的版本相差不多,只是有个别不同之处,本文我们主要分析Linux内核启动之后的过程。
2、启动过程分析
2.1 init进程启动
当系统内核加载完成之后,会启动init守护进程,它是内核启动的第一个用户级进程,是Android的一个进程,进程号为1,init进程启动后执行入口函数main(),主要操作为:
图2
AndroidL上将selinux的安全等级提高了,设为了enforcing模式,4.4上是permissive模式。
解析rc脚本文件,即init.rc脚本,该文件是Android初始化脚本,定义了一系列的动作和执行这些动作的时间阶段e aryl-init、init、early-boot、boot、post-fs等阶段。init进程main 函数中会根据这些阶段进行解析执行。AndroidL上为了流程更清晰,增加了charger(充电开机)、ffbm(工厂模式)、以及late-init阶段,实际上这些阶段是对其他阶段的组合执行,比如late-init:
2.2 ServiceManager的启动
servicemanager的启动就是init进程通过init.rc脚本启动的:
源码在frameworks/native/cmds/servicemanager/service_manager.c中,servicemanager是服务管理器,它本身也是一个服务(handle=0),通过binder调用,为native和Java系统服务提供注册和查询服务的,即某个服务启动后,需要将自己注册到servicemanager中,供其他服务或者应用查询使用。AndroidL上servicemanger中在处理注册和查询动作之前添加了selinux安全检测相关的处理。
2.3 SurfaceFinger、MediaServer进程启动
Android4.4以前,surfacefinger的启动根据属性system_init.startsurfaceflinger,决定是通过init.rc启动还是systemserver进程启动,之后的版本包括AndoridL都是通过init.rc启动的:
启动后会向servicemanager进程注册服务中,该服务启动时主要功能是初始化整个显
示系统,并且在初始化完成后,启动开机动画进程:
当开机过程完成点亮屏幕之前,WindowManagerService通过binder通信通知SurfaceFinger停止开机动画,SurfaceFinger服务会调用bootFinished函数设置service.bootanim.exit属性,开机动画进程bootanim判断该属性为1后,停止播放开机动画。
MediaServer也是init启动较早的一个服务进程:
对应代码在frameworks/av/media/mediaserver/main_mediaserver.cpp,该服务启动时会创建一些音频、camera相关的native服务,这些native服务也会注册到servicemanager中。在播放开机动画时如果需要播放开机音,bootanim需要等待mediaserver初始化完成才会播放
音乐。
2.4 Zygote启动
Zygote是系统中最重要的服务,在开机过程中zygote进程创建之后系统才进入了java 环境,进入了Android环境,另一方面zygote是通过socket接收AMS发送的请求,fork新的应用程序、启动其他的java系统服务。
init进程通过init.${ro.zygote}.rc启动zygote:
AndroidL是64位系统,可以支持两个zygote进程,比以前的版本增加了一个zygote,如果芯片是64位的话,ro.zygote属性为zygote64_32,init则通过init.zygote64_32.rc启动zygote,该rc文件中定义了以下两个zygote服务:
分别通过app_process64,app_process32两个app_process进程来启动zygote、zygote_secondary,其中zygote为primary zygote,进程名为zygote64,会负责创建systemserver 进程,一般系统服务进程都是由zygote64进程fork出来,其他应用进程由另外一个zygote fork。
源码在frameworks/base/cmds/app_process/app_main.cpp。
该服务启动时的主要工作是创建AndroidRuntime、registerZygoteSocket创建socket端口、preload加载类和资源、创建Systemserver进程,下面根据处理的顺序进行逐步解析。
2.4.1 AndroidRuntime创建
AndroidRuntime是android的运行环境(ART),在app_main.cpp中通过
runtime.start("com.android.internal.os.ZygoteInit", args)启动AndroidRuntime。
源码在/frameworks/base/core/jni/AndroidRuntime.cpp
AndroidRuntime启动后会创建虚拟机:
Android4.4上还是默认使用Dalvik虚拟机,在开发者选项中兼容ART模式,AndroidL 上完全采用了ART,加载libart.so。
startVm( )函数,首先会完成虚拟机很多资源的分配,然后初始化ART相关的option、调用JNI_CreateJavaVM()创建ART虚拟机。
由于Dalvik VM的效率不高,在android4.4开始,google就开发了AndroidRuntime即android运行环境。Dalvik虚拟机下,应用每次运行都要将字节码转成机器码,ART不同,应用第一次安装的时候,通过dex2oat字节码就会转成机器码,并保存起来,理论上应用启动时会更快。(但是之前陈翔工针对ART和Dalvik作过对比测试,从对比数据上看,ART 下应用的启动速度提高没有很明显,而且由于安装时的dex2oat过程,导致应用的安装和系统的启动速度会较慢,可能后期的版本androidL有优化。)
2.4.2 registerZygoteSocket
AndroidRuntime启动完虚拟机之后,会创建的第一个虚拟机java进程就是ZygoteInit进程,这个ZygoteInit进程可以理解成真正的zygote,在zygoteInit的main函数中首先就是调用registerZygoteSocket(“zygote”),注册一个LocalServerSocket类型的Socket通道,变量命名为sServerSocket,作为Socket的服务端。当SystemServer进程创建后,在SystemServer 进程中则会创建一个Socket客户端LocalSocket,具体实现在Process.java中。
这样就创建了一个zygote和SystemServer进程的socket通信通道,所谓zygote是应用孵化器,就是利用该Socket 创建其他的应用进程。
当服务端LocalServerSocket端口准备好后,ZygoteInit的main()函数调用runSelectLoop ()进入非阻塞读操作循环,通过selectReadable()将文件描述符添加到select的列表中,如果有请求就调用ZygoteConnection类的runOnce()函数处理每一个Socket接收到的命令。
当要创建新应用时,客户端SystemServer进程中ActivityManagerService通过startActivity()一步步调用到的StartProcessLocked()函数进入Process.java,最终通过startViaZygote ->zygoteSendArgsAndGetPid,通过LocalSocket发给zygote进程,zygote在通过runOnce函数fork新进程。
2.4.3 preload预加载类和资源
创建完socket之后,zygote进程开始调用preload()函数加载类和资源等信息。