Android系统启动概述

1 Android 系统启动流程

Android 系统框架分为应用层、Framework 层、系统运行库层(Native)、Linux 内核层,启动按照:Loader -> Kernel -> Framework -> Application 来进行的。

boot loader [计] 引导装载程序 boot [buːt] 启动 zygote [ˈzaɪɡoʊt] 受精卵 launch [lɔːntʃ] 发起,发动,开始
在这里插入图片描述

第一步,启动电源

电源键开机,首先会从 ROM 中预定义的地方加载引导程序 Boot Loader 到 RAM 中。

  • ROM(Read-Ony-Memory):只读存储器,只能读出无法写入,即便是切断电源数据也不会丢失;
  • RAM(Random Access Memory):随机存取存储器,与 CPU 直接交换数据,随时读写,一旦断电,存储的数据也将丢失;
第二步,加载引导程序(Boot Loader)

Boot Loader 是 Android 操作系统内核开始运行之前的一小段程序,它的主要作用是把系统 OS 拉起来并运行。

通过这一小段程序,可以初始化硬件设备、建立内存空间的映射,从而为操作系统内核准备出比较合适的软硬件运行环境。之后,启动 Linux Kernel。

设备制造商要么使用比较流行的引导程序,比如 redboot、uboot、qi bootloader,要么自己开发,它不是 Android 操作系统的一部分。引导程序是 OEM 厂商或者运营商加锁和限制的地方。

引导程序分为两个阶段执行:

  • 第一个阶段:检测外部的 RAM 以及加载对第二个阶段有用的程序;
  • 第二个阶段:引导程序设置网络、内存等功能;

这些对于运行内核是必要的,为了达到特殊的目标,引导程序可以根据配置参数或者输入数据设置内核。Android 引导程序可以在 \bootable\bootloader\legacy\usbloader 找到。传统的加载器包含两个文件,需要在这里说明:

  • init.s 初始化堆栈,清零 BBS 段,调用 main.c 的 _main() 函数;
  • main.c 初始化硬件(闹钟、主板、键盘、控制台),创建 linux 标签;
第三步,启动 Linux Kernel

内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。在内核完成各种设置后,首先会在系统文件中寻找 init.rc 文件,进而启动 init 进程。

第四步:启动 init 进程

Kernel 启动后,就会启动 init 进程,并调用 init 进程的 main 方法执行其职责。init 进程是第一个用户级别的进程,进程号固定为 1。init 进程的主要工作有:

  • 创建(mkdir)和挂载(mount)启动所需要的文件目录;
  • 初始化和启动属性服务(property service);
  • 解析 init.rc 配置文件并启动 zygote 、Service Manager 等进程;(Service Manager 主要用于管理系统服务)

property /ˈprɑːpərti/ 属性

第五步:启动 Zygote 进程

Zygote 的意思为孵化器,主要用于孵化子进程。 Zygote 进程最初的名字为 app_process。这个名字在 /frameworks/base/cmds/app_process/android.mk 中有定义。

zygote [ˈzaɪɡoʊt] n. 受精卵

在 Android 系统中有两种程序,一种是 Java 应用程序,主要是基于 ART (Android Runtime),所有的应用程序都属于这一类;另一种是 Native 程序,也就是用 C/C++ 开发的程序,如 Boot Animation(开机动画)。

fork [fɔːrk](道路、河流等)分岔,岔开;

所有的 Java 应用程序以及 system_server 进程都是由 Zygote 进程 fork 出来的。(Native 进程则是由 init 进程创建的)

Zygote 进程是通过 Socket 的方式和其他进程通信的,这里的“其他进程”其实主要指的是 system_server 进程。

Zygote 是一个 C/S 模型,Zygote 进程作为服务端,主要负责启动 system_server 进程,创建 Java 虚拟机,加载系统资源以及在后续的运行中启动 Java 应用程序。其他进程可以向其发出“孵化”进程的请求,而 Zygote 进程接收到这个请求后会“孵化”出一个新的进程。比如,点击 Launcher 中的某个应用程序图标启动一个新的进程时,这个请求会到达 Framework 层的 ActivityTaskManagerService(ATMS)中,ATMS 接收到这个请求后,会调用 Process 类发出“孵化”子进程的 Socket 请求,Zygote 监听到这个请求后会 fork 出一个新的进程。

第六步,启动 system_server 进程

Zygote 启动了 system_server 进程后,在 system_server 进程中会进一步启动 WindowManagerService(WMS)、ActivityManagerService(AMS)、ActivityTaskManagerService(ATMS)、PackageManagerService(PMS)等服务进程,等这些服务启动后,ATMS 就会打开 Launcher 应用的 Home Activity,也就是手机桌面。

第七步,Launcher APP 启动
总结

Android 设备启动必须经历三个阶段:Boot Loader、Linux Kernel 和 Android 系统服务(他们都是有各自的启动动画)。严格来说,Android 系统实际是运行在 Linux 内核上的一系列的“服务进程”(并不是严格意义上的操作系统),而这些服务进程的“老祖宗”是 init 进程,它是第一个用户级别的进程,PID 为 1,它通过一系列的初始工作以及解析 init.rc(一个脚本文件)文件构建出 Android 系统运行的初始形态:即其他的 Android 服务进程大多在这个 init.rc 脚本中有描述并按照一定的条件启动。
启动流程

2 Zygote 进程

在 Android 系统中,DVM(Dalvik 虚拟机)和 ART、应用程序进程以及运行系统的关键服务的 system_server 进程都是由 Zygote 进程来创建的(或者说大多数应用进程和系统进程都是通过 Zygote 创建出来的),我们也将它称为孵化器。它通过 fork(复制进程)的形式来创建应用程序进程和 system_server 进程。 由于 Zygote 进程在启动时会创建 DVM 或者 ART,因此通过 fork 而创建的应用程序进程和 system_server 进程可以在内部获取一个 DVM 或者 ART 的实例副本。

Zygote进程启动过程

为了实现资源共用和更快的启动速度,Android 系统开启新进程的新方式,是通过 fork 第一个 Zygote 进程实现的。 当系统里面的第一个 Zygote 进程运行之后,在这之后再开启 APP,就相当于开启了一个新的进程。所以说,除了第一个 Zygote 进程,其他应用所在的进程都是 Zygote 的子进程。

每个 APP 其实都是:一个单独的 dalvik 虚拟机;一个单独的进程。

Zygote 的 IPC 通信机制为什么使用 Sokcet 而不是采用 Binder?

Zygote 是通过 fork 生成进程的,多线程不允许使用 fork,可能造成死锁,而 Binder 是多线程的。另外 Binder 通信需要 Binder 线程池,Zygote 进程还没有启动 Binder 线程池(在 system_server 进程中启动的)。

3 system_server 进程

system_server也是是一个进程,是由Zygote进程fork出来的。这个进程是Android Framework里面非常重要的进程,因为系统里面重要的服务都是在这个进程里开启的。比如ActivityManagerServicePackageManagerServiceWindowManagerService等等。

ActivityManagerService 简称AMS,服务端对象,负责系统中所有Activity的生命周期(Activity的开启、暂停、销毁)。在SystemServer进程开启的时候,就会初始化ActivityManagerService

任何一个Activity的启动都是由AMS和应用程序进程(主要是ActivityThread)相互配合来完成的,AMS服务统一调度系统中所有进程的Activity启动,而每个Activity的启动过程则由其所属的进程具体来完成。

system_server进程总结:

  • 启动Binder线程池,这样就可以和其他进程进行通信
  • 创建SystemServiceManager,其对于系统的服务进行创建,启动和生命周期管理
  • 启动各种系统服务

对于APPSystemServerZygote分别属于三个独立的进程,它们之间是如何通信的呢?

APPSystemServer是用Binder IPC通信的,SystemServerZygote是用Sockte IPC进行通信的。

system_serverServiceManagerSystemServiceManager的关系

ServiceManager是系统服务管理者,维护一个svclist列表来存储services信息。客户端通过ServiceManager查询服务。

system_server是一个由Zygote进程孵化出来的第1个进程,叫做系统服务进程。

SystemServiceManagersystem_server中初始化,启动各种系统服务,包括ActivityManagerServiceAMS)/WindowManagerService(WMS)/PackagerManagerService(PMS)。system_server通过ServiceManager.addService()的调用,使用Binder IPC的方式将这些核心的服务注册得到ServiceManager的列表(svclist)。

孵化应用进程这种事为什么不交给system_server来做,而是专门设计一个Zygote进程

Zygote进程是所有Android进程的母体,包括system_server进程和各个APP进程。新进程A复用Zygote进程本身的资源,再加上新进程A相关的资源,构成新的应用进程A。应用在启动的时候需要做很多准备工作,包括启动虚拟机,加载各类系统资源等等,这些都是非常耗时的,如果能在Zygote里就给这些必要的初始化工作做好,在fork子进程的时候就能直接共享,那么这样做的话效果就非常高。

system_server里跑了一堆系统服务,这些不能继承到应用进程。

僵尸进程与危害

在UNIX/Linux中,父进程使用fork创建子进程,在子进程终止之后,如果父进程并不知道子进程已经终止了,这时子进程虽然已经退出了,但是在系统进程中还未它保留了一定的信息(比如进程号、退出状态、运行时间等),这个子进程就被称作为僵尸进程。 系统进程表是一项有限资源,如果系统进程表被僵尸进程耗尽的话,系统就可能无法创建新的进程了。

Android系统中的服务端和客户端

服务端、客户端不仅仅存在于Web开发中,在Android的框架设计中,使用的也是这样一种模式。服务端指的是所有APP共用的系统服务,比如ActivityManagerServicePackageManagerServiceWindowManagerService等等, 这些基础的系统服务是被所有的APP共用的,当某个APP想要实现某个操作的时候,就要告诉这些系统服务,比如你想要打开一个APP,那么知道这个APP的包名和MainActivity类名之后即可以打开:

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
ComponentName cn = new ComponentName(packageName, className);
intent.setComponet(cn);
startActivity(intent);

我们的APP通过调用startActivity()并不能直接打开另外的一个APP最终是通过AMS来通知Zygote进程来fork一个新进程,来启动目标APP 这就像浏览器要打开一个超链接一样,浏览器把网页地址发送给服务器,然后服务器把需要的资源文件发送给客户端。

system_serverAndroid进入Launcher前的最后准备,它提供了众多由Java语言编写的“系统服务”

4 Launcher启动流程

系统启动的最后一步是启动一个应用程序用来显示系统中已经安装的应用程序,这个应用程序叫做LauncherLauncher在启动过程中会请求PackageManagerService返回系统中已经安装的应用程序的信息,并将这些信息封装程一个快捷图标列表显示在系统屏幕上,这样用户可以通过点击这些快捷图标来启动相应的应用程序。

通俗来讲Launcher就是Android系统的桌面,它的作用主要有以下两点:

  • 作为Android系统的启动器,用于启动应用程序
  • 作为Android系统的桌面,用于显示和管理应用程序的快捷图标或者其他桌面组件

SystemServer进程在启动的过程中会启动PackageManagerServicePackageManagerService启动后会将系统中的应用程序安装完成。在此之前已经启动的AMS会将Launcher启动起来。

点击APP的图标的时候,这个APP就由Launcher启动了。Launcher本质上也是一个应用程序,和普通的APP一样。我们在点击APP图标的时候,捕捉到图标点击事件,然后startActivity()发送对应的intent请求。

Android系统启动流程

参考

https://cloud.tencent.com/developer/article/1356506
https://www.pianshen.com/article/10041941900/
https://www.jianshu.com/p/e3a630e85ee0
https://www.it610.com/article/1306034628473163776.htm
https://www.pianshen.com/article/58891502756/
https://www.it610.com/article/1304489264385396736.htm
https://blog.csdn.net/qq_39037047/article/details/88066589
https://blog.csdn.net/anhenzhufeng/article/details/106444099?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link
https://blog.csdn.net/qq_39037047/article/details/88066589?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2aggregatepagefirst_rank_ecpm_v1~rank_v31_ecpm-1-88066589.pc_agg_new_rank&utm_term=Zygote没有采用binder&spm=1000.2123.3001.4430
https://www.pianshen.com/article/55371343995/
https://blog.csdn.net/shaoenxiao/article/details/87088982

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值