一、简介

众所周知,Android系统的本质是一个基于Linux系统的、自由且开放源代码的应用程序,它的启动和运行都是依托Linux系统为内核而实现的,因此,Android 系统的启动流程主要包括Linux内核启动和Android框架启动两大阶段。


 

二、Linux内核启动

 1、 加载内核引导程序bootloader

当电源按下,引导芯片代码开始从预定义的模块开始执行,加载引导程序到RAM中去执行,因此在启动Linux内核系统之前会加载内核引导程序bootloader ,加载完成后进入Linux 内核程序。

 

Android引导程序可以在\bootable\bootloader\legacy\usbloader找到。
传统的加载器包含的个文件,需要在这里说明:

init.s   初始化堆栈,清零BBS段,调用main.c的_main()函数;

main.c          初始化硬件(闹钟、主板、键盘、控制台),创建linux标签。

 

2、加载Linux内核

 Linux内核加载主要包括初始化kernel核心(内存初始化,打开中断,初始化进程表等)、初始化驱动、启动内核后台(daemons)线程、安装根(root)文件系统等。

Linux加载的最后阶段启动执行第一个用户级进程init(内核引导参数上一般都会设置“init=/init”,由kernel自动执行,PID为1,是所有进程的父进程)。由此进入Android框架的启动阶段。

 

三、Android框架的启动

Android框架层启动阶段是Android系统启动中最复杂、也是最重要的部分,Android框架层的启动始于init进程,启动过程概括起来可以分为以下几个主要的阶段:

 

1、    启动init进程

对于Linux系统的运行来说,init程序是最基本的程序之一,它是内核启动的第一个用户级进程,因此,init进程也是Android系统中用户空间的第一个进程,它的进程号PID是1。

init进程可以在/system/core/init找到,其的入口函数是/system/core/init/init.c中的main函数;

init.rc文件路径:/system/core/rootdir/init.rc;

 

总体而言, init进程执行了以下工作:

1、创建 "/dev/socket" 文件夹,并挂载设备;

2、parse_config_file("/init.rc")解析配置文件init.rc;

3、parse_config_file(tmp)解析硬件配置 init.hardware.rc

4、执行各阶段的配置,如:创建Zygote进程;

5、property_init()   初始化相关属性;

6、start_property_service()启动属性服务。

此后,init进程将会进行无限循环,并等待配置解析完成、某些服务的启动和后续相关联的操作发生。如初始化开机首画面、处理来自socket监听等。

 

2、解析init.rc脚本

init.rc脚本文件中配置Andoid系统Framework层重要的系统服务,init进程通过创建子进程启动这些服务,这里创建的service都属于native服务,运行在Linux空间,通过socket向上层提供特定的服务,并以守护进程的方式运行在后台。

通过解析init.rc脚本,系统启动了以下几个重要的服务:

1)ServiceManager:启动binder IPC,管理所有的Android系统服务

2)Mountd:设备安装Daemon,负责设备安装及状态通知

3)Debuggerd:启动debug system,处理调试进程的请求

4)Rild:启动radio interface layer daemon服务,处理电话相关的事件和请求

5)MediaServer:启动AudioFlinger,MediaPlayerService and CameraService,负责多媒体播放相关的功能,包括音视频解码、显示输出

6)Zygote:进程孵化器,启动Android Java VM Runtime进程和SystemServer子进程,负责Android应用进程的孵化工作。

 


3、启动zygote服务

在Android系统中,所有的应用程序进程以及系统服务进程(SystemServer进程)都是由Zygote进程孕育(fork)出来的,这也就是为什么要把它称为Zygote(受精卵)的原因。

在Java中,不同的虚拟机对象会为不同的应用分配不同的内存。假如Android应用应该尽可能快地启动,但如果Android系统为每一个应用启动不同的Dalvik虚拟机实例,就会消耗大量的内存以及时间。因此,为了克服这个问题,Android系统创造了”Zygote”。

Zygote是一个虚拟机进程,他在系统引导的时候启动,他的存在让Dalvik虚拟机共享代码、低内存占用以及最小的启动时间成为可能。

Zygote进程孵化了所有的Android应用进程,是Android Framework的基础,该进程的启动也标志着Framework框架初始化启动的开始,Zygote预加载以及初始化了Android Framework层最常用的、最核心的库。

Zygote服务进程的主要功能:

(1)注册底层功能的JNI函数到虚拟机:registerZygoteSocket():为zygote注册一个Socket服务器;

(2)预加载java类和资源:preloadResources():预加载本地主题、布局以及android.R文件中包含的所有东西,此时,我们可以看到 bootanimation 开机动画;

(3)fork并启动SystemServer系统核心进程;

(4)作为守护进程监听处理“孵化新进程”的请求。


4、启动SystemServer进程

SystemServer进程在Android的运行环境中扮演了“神经中枢”的作用,Android应用能够直接交互的大部分系统服务都在该进程中运行,如WindowManagerServer、ActivityManagerSystemService、PackageManagerServer等,这些我们经常用到的系统服务,都是以独立线程的方式存在于SystemServer进程中。

 

System Server进程的主要功能:

(1)调用本地 init1(system_init) 函数,加载android servers底层函数库;

(2)调用本地 init1(system_init) 函数,启动android系统中的本地服务 native service:AudioFlinger / MediaPlayerService / Ca'meraService等;

(3)调用 init2(...) 函数,创建ServerThread线程,在run(...)方法中创建Android系统服务SystemService ,并注册到ServiceManager,它们都运行在独立的线程中

(4)调用 init2(...) 函数,创建ServerThread线程,在run(...)方法中建立Looper消息循环:通过Looper.prepare和Looper.loop来实现,用于处理System Server进程中的事件消息;


四、启动Home应用层

在SystemServer进程中, init2(...) 函数创建了ServerThread线程,创建并注册了众多的系统服务,当所有的系统服务在内存中运行起来后,Android系统就完成了开机引导。

此后,run()函数会在调用到ActivityManagerService中的systemReady()方法,该方法实现了如下代码用于启动第一个Activity:mMainStack.resumeTopActivityLocked(null);


由于系统刚启动时没有任何Activity对象,代码最终会调用ActivityManagerService中的startHomeActivityLocked()函数启动Android系统APK层的首个Home应用:Launcher,即系统首页。