Android系统的启动流程(开机流程)

上图,先大致了解一下Android点击电源键开机到创建出system_server进程的流程,里面细化的子流程和system_server之后发生的事情我们后面再讲:

android fde开机过程 android开机启动流程_apache

Boot Rom:当电源键按下时,引导芯片就会启动,引导芯片代码会从预定义的地方开始执行(代码存在Rom),加载引导程序BootLoader到RAM。换句话说,就是启动的时候,会把引导程序代码由ROM中移动到RAM中,再去执行引导程序BootLoader。

ROM可以简单理解为硬盘,断电后内部的数据是不会丢失的。

RAM可以简单理解为运行时内存,断电后内部的数据就会丢失。

具体他们的含义是什么,这里就不再赘述,大家感兴趣自己去查一下吧

BootLoader:BootLoader是在Android操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行。BootLoader执行后,就会启动我们的操作系统。

idle进程:当操作系统启动后,就会启动系统的第一个进程,idle进程,它的进程号为0。当这个进程启动后,就会再次启动另外两个进程,一个是kthreadd进程,一个是init进程(当idle进程被启动后,会在系统文件中寻找 init.rc 文件,用来启动init进程)。

kthreadd进程:它跟idle一样,都是位于内核层。它主要是用来创建内核工作线程、软中断线程等内核相关的工作,我们不需要太过关注。

init进程:idle进程属于nativer层。它的主要工作是初始化进程管理,内存管理,加载Binder Driver、Display、Camera Driver等。它是首个开辟用户空间的进程,是用户空间的鼻祖

init进程:它的进程号为1。在init进程内部,会fork出我们所熟知的一个进程:zygote进程。

zygote进程:又名孵化器,它是java进程的鼻祖。在zygote中,它第一个fork出来的进程是SystemServer进程。同时,我们设备上的app进程都是由zygote进程来创建的。

SystemServer进程:Android中常用系统服务(AMS/WMS/PMS )都是由SystemServer这个进程启动的,所以它相当重要,SystemServer这个我们后面的篇幅再细说

Zygote/SystemService启动流程

下面我们跟进一下源码(以下源码基于Android 11),看一下从init进程开始,到Zygote进程和SystemService进程创建的过程,先看图:

android fde开机过程 android开机启动流程_android_02

启动init进程过程中,会进入system/core/init/init.cpp文件的main()方法中,关键代码如下:

1、执行frameworks/base/cmds/app_process/app_main.cpp中的main()方法**(此时处于init进程中)**

1、初始化AndroidRuntime(Android运行时环境)

android fde开机过程 android开机启动流程_java_03

2、在main函数的最后,通过调用上面创建的AndroidRuntime对象的**start(“com,android.internal.os.ZygoteInit”, args, zygote)**方法,启动我们Android运行时环境

android fde开机过程 android开机启动流程_apache_04

2、执行runtime.start()方法启动zygoteInit,它做了如下几个关键事情。我们进入start方法内部看看里面写什么东西:

1、创建虚拟机、注册jni方法

android fde开机过程 android开机启动流程_Android_05

上面这段代码里,相关地方注释也就写得很明白了,在这里面也看出,一个进程,内部包含一个虚拟机。

2、当我们注册完jni,在下面的代码开始使用jni方法调用com.android.inter.os.ZygoteInit.main()方法,由此进入java世界:

android fde开机过程 android开机启动流程_java_06

为什么要用jni方法来调用ZygoteInit的main()方法呢?因为zygote是java进程的鼻祖,而我们平时开发的app都是属于java层的代码,想要从native层进入java层,就需要用到jni,我们可以将jni理解为native层和java层之间的桥梁。

3、执行ZygoteInit.main()方法,它做了如下几个关键事情。我们进入ZygoteInit.main()方法内部看看里面写什么东西:

1、执行preload()方法预加载信息,这些预加载信息包括了一部分framework的资源,以及一部分常用的java类。这部分预加载的信息,在后面创建的进程都是可以直接用的。所以这里预加载的作用就是加快了应用进程的启动速度

android fde开机过程 android开机启动流程_apache_07

2、创建zygote的socket服务

android fde开机过程 android开机启动流程_android_08

在这里使用的socket进行进程之间的通信,为什么不用Binder呢?事实上,代码执行到这,Binder还没开始初始化。

3、通过fork创建SystemServer进程

android fde开机过程 android开机启动流程_apache_09

在这里通过调用forkSystemServer()方法,以fork的形式创建了system_setver进程。在这段代码中也可以看到,执行r.run()方法,run方法内部会执行SystemServer的main方法,我们等会再说SystemServer的main方法里面做啥什么吧,,,

4、当我们继续往main方法下面走,就会执行zygoteServer.runSelectLoop()方法,使zygote进入无限循环,等待AMS给他发消息,从而创建进程。这里还有一个点要注意:为什么我们要用zygote去fork应用进程,而不是用init进程去fork呢?—首先我们要知道,init进程除了fork出zygote进程外,还会创建很多其他进程,而且这些进程我们应用进程都是不需要的。那为什么不放在SystemServer进程中fork应用进程呢,因为SystemServer里会启动很多的系统服务,像AMS/PMS/WMS等等,大大小加起来也有100个左右了,而且这些服务是所有哟应用进程公用的,通过进程通信就可以访问。

android fde开机过程 android开机启动流程_Android_10