Android进程启动流程

一.Android 系统架构图

​虽然 Android 系统非常庞大且错综复杂,但整体架构设计清晰。Android 底层内核空间以 Linux Kernel 作为基石,上层用户空间由 Native系统库、虚拟机运行环境、框架层组成,通过系统调用(Syscall)连通系统的内核空间 与 用户空间。对于用户空间主要采用 C++ Java 代码编写,通过 JNI 技术打通用户空间的 Java层 和 Native(C++/C),从而连通整个系统。为了能让大家整体上大致了解Android系统涉及的知识层面,先来看一张Google官方提供的经典分层架构图:

Linux内核层

Android系统是基于Linux操作系统的,严格来说,它属于Linux操作系统的一个变种。

好处:

避免了与硬件直接打交道;基于Linux系统的驱动开发可扩展性很强;

硬件抽象层

通过定义硬件“驱动”的接口来进一步降低Android系统与硬件的耦合度;

由于Linux遵循的是GPL协议,而Android开源项目基于Apache协议,意味着其下的所有驱动都应该开源,

这一点对于部分厂商来说无法接受;

系统运行库

这层中包含了支持整个系统正常运行的基础库,由于这些库多数都由C/C++实现,因此也被一些开发人员

成为“C库层”,以区别于应用程序框架层。

应用程序框架层

与系统运行库被称为“C库层”相对应,应用程序框架层往往被冠以“JAVA库”的称号。这是因为框架层

所提供的组件一般都是以JAVA语言编写而成,他一方面为上层应用程序提供了API接口;

另一方面也囊括了不少系统级服务进程的实现,是与Android应用程序开发者关系最直接的一层

应用程序层

应用是用java语言编写的运行在虚拟机上的程序,比如Email客户端,SMS短消息程序,日历等

二.Android 启动流程

Android启动流程图:

1.Boot Rom:按电源键上电后,引导芯片从固化在ROM的预设代码开始执行,加载引导程序到RAM

2.SML:初始化TrustZone TEE运行环境,运行时切换非安全世界(Android/Linux)和安全世界(TOS),支持CPU core power uppower downsuspendresumeCPU电源管理功能,控制部分芯片安全硬件模块

3.TOS:实现Trusty OS基本模块,包括线程调度、中断处理、MMU、内存子系统、Timer以及系统调用等。完成安全启动、指纹、人脸、安全存储、数据加解密等安全业务

4.Bootloader:引导程序,主要作用是初始化flash、将内核kernel拷贝到内存中、启动内核

5.启动kernel:主要是启动内核线程kernel_initkernel_init函数完成设备驱动程序的初始化,并调用init_post启动用户空间的init进程

6.启动init进程:在Linux系统中,所有的进程都是由init进程直接或间接fork出来的。init进程负责创建系统中最关键的几个子进程,尤其是zygote进程,另外它还提供了property service

7.启动surfaceflinger进程:init在解析rc过程中,在boot阶段通过class_start core接口启动surfaceflinger进程。当surfaceflinger启动之后会通过init设置“service.bootanim.exit属性为0,同时调用ctl.start接口通知init启动bootanimationservices(开机动画显示服务)。

8.启动zygote进程:当init进程创建之后,会fork出一个zygote进程,这个进程是所有Java进程的父进程。

9.启动SystemServer进程:SystemServer进程由zygote进程fork,这个进程在整个Android系统中非常重要,系统里面的服务都是在这个进程里面开启的,例如AMSActivity Manager Service,活动管理服务)、WindowsManager等。

10.运行Home Activity:最后AMS会通过Home intent启动launcher

三.Init进程启动过程

 

 init进程是Android系统中用户空间的第一个进程,进程号为1,是Android系统启动流程中的一个关键的步骤,作为第一个进程,它被赋予了很多极其重要的工作职责,比如创建Zygote(孵化器)和属性服务等。init进程是由多个源文件共同组成的,这些源文件位于源码目录system/core/init中。

kernel_init初始化如上图:

kernel_init启动后,完成一些init的初始化操作。启动后去系统根目录下依次找ramdisk_execute_commandexecute_command设置的应用程序,如果这两个目录都找不到,就依次去根目录下找/sbin/init/etc/init/bin/init/bin/sh,只要这些应用程序有一个启动了,其他就不需启动了。当log中出现以下信息说明init启动成功。

00736 <0> [12.935128][01-01 08:00:11.935] run init

00737 <14> [12.961677][01-01 08:00:11.961] init: init first first stage started!Android系统一般会在根目录下放一个init的可执行文件,也就是说Linux系统的init进程在内核初始化完成后,就会直接执行该init文件。

内核启动init进程

 

 

四.zygote启动流程 

zygote启动流程
init进程启动后,zygote是最重要的一个进程,它是所有Android Java进程的父进程。SystemServer和其他所有Dalivik虚拟机进程都是由zygotefork而来。
zygote是由app_process启动。zygote按C/S模型工作,它作为服务端,其他进程作为客户端。其他进程向zygote发出fork请求,zygote收到请求后fork一个新的进程。

init进程启动后,会解析init.rc文件,然后创建和加载service字段指定的进程。zygote进程就是以这种方式,被init进程加载的。
在/system/core/rootdir/init.rc中,通过如下引用来加载zygote的rc。import /system/etc/init/hw/init.${ro.zygote}.rc其中,${ro.zygote}由各个厂家使用,现在主流厂家基本使用zygote64_32,相应的${ro.zygote}.rc文件为init.zygote64_32.rc。

init.zygote64_32.rc
Primaryzygote
进程名:zygote进程通过/system/bin/app_process64来启动,支持64位程序。
启动参数:-Xzygote/system/bin --zygote--start-system-server --socket-name=zygote
socket名称:zygote

Secondary zygote

进程名:zygote_secondary

进程通过/system/bin/app_process32来启动,支持32位程序。

启动参数:-Xzygote/system/bin --zygote--socket-name=zygote_secondary --enable-lazy-preload

socket名称:zygote_secondary

init.zygote64_32.rc中的以下内容可以看出,zygote是通过进程文件/system/bin/app_process64/system/bin/app_process32来启动的。

zygote进程重启

有些services发生异常重启时会同时重启zygote,其对应的rc文件中有“onrestart restart zygote”的字样。以surfaceflingerservice为例,surfaceflinger.rc相关内容如下。

如上述rc文件所示,当surfaceflingerservice发生异常重启时会同时重启zygote

zygote进程的重启时机如下

zygote的工作内容

zygote是所有Android Java进程的父进程,是Java世界的入口。zygote启动后的工作内容

zygote流程图

 startVM()
该函数主要是初始化VM参数。需重点关注dalvik heapsize的初始化,如果VM参数未配置正确或使用默认参数很有可能导致手机无法进入Launcher。目前app占用的heapsize都比较大,使用默认参数很容易出现内存不足,导致应用不断重启。


startReg()
注册JNI(Java Native Interface,Java原生接口)函数,遍历gRegJNI数组中JNI register方法注册JNI method。注册JNI后,会通过JNI调用java class(zygoteInit)的main函数进入java世界。


registerServerSocket()
通过获取环境变量值得到zygote文件描述符,根据该文件描述符创建socket,用来和ActivityManagerService通信。AMS通过Process.start来创建新的进程,而Process.start会先通过socket连接到zygote进程,并最终由zygote完成进程创建。


preload()
预加载类和资源,zygote通过预加载类和资源可以加快子进程的执行速度和优化内存。因为预加载的类和资源较多,在开机优化过程中也需要重点关注preload的耗时。
预加载Class文件路径:/system/etc/preloaded-classes预加载resource文件路径:frameworks/base/core/res/res/values/arrays.xml


forkSystemServer()
启动system_server进程,Android Java系统服务都将驻留在该进程中,是Android framework核心。设置systemserver进程的uid、gid、process name和class name。

参考链接

Android 系统启动到App 界面完整详解~

Android系统启动流程简述 - 简书

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值