AndroidL系统启动及加载流程分析

  • 格式:docx
  • 大小:348.41 KB
  • 文档页数:10

下载文档原格式

  / 13
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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()函数加载类和资源等信息。