【开机流程】Android系统的启动流程

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

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

在这里插入图片描述

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进程创建的过程,先看图:

在这里插入图片描述

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

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

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

在这里插入图片描述

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

在这里插入图片描述

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

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

在这里插入图片描述

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

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

在这里插入图片描述

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

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

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

在这里插入图片描述

2、创建zygote的socket服务

在这里插入图片描述

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

3、通过fork创建SystemServer进程

在这里插入图片描述

在这里通过调用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个左右了,而且这些服务是所有哟应用进程公用的,通过进程通信就可以访问。

在这里插入图片描述

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一场雪ycx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值