【Android】系统启动流程(简介)

前言

Google提供的5层架构图很经典,但为了更进一步透视Android系统架构,本文更多的是以进程的视角,以分层的架构来诠释Android系统的全貌,阐述Android内部的环环相扣的内在联系。

一、系统启动架构图

Android系统启动过程由上图从下往上的一个过程是由Boot Loader引导开机,然后依次进入 -> Kernel -> Native -> Framework -> App,接来下简要说说每个过程。

2.1 Loader层

(1)Boot ROM

当手机处于关机状态时,长按Power键开机,引导芯片开始从固化在ROM里的预设代码开始执行,然后加载引导程序到RAM

(2)Boot Loader

这是启动Android系统之前的引导程序,主要是检查RAM,初始化硬件参数等功能。

2.2 Linux内核层

Android平台的基础是Linux内核,比如ART虚拟机最终调用底层Linux内核来执行功能。Linux内核的安全机制为Android提供相应的保障,也允许设备制造商为内核开发硬件驱动程序。

  • 启动Kernel的swapper进程(pid=0):该进程又称为idle进程, 系统初始化过程Kernel由无到有开创的第一个进程, 用于初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作;
  • 启动kthreadd进程(pid=2):是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。kthreadd进程是所有内核进程的鼻祖

2.3 硬件抽象层 (HAL)

硬件抽象层 (HAL) 提供标准接口,HAL包含多个库模块,其中每个模块都为特定类型的硬件组件实现一组接口,比如WIFI/蓝牙模块,当框架API请求访问设备硬件时,Android系统将为该硬件加载相应的库模块。

2.4 Android Runtime & 系统库

每个应用都在其自己的进程中运行,都有自己的虚拟机实例。

ART通过执行DEX文件可在设备运行多个虚拟机,DEX文件是一种专为Android设计的字节码格式文件,经过优化,使用内存很少。

ART主要功能包括:预先(AOT)和即时(JIT)编译,优化的垃圾回收(GC),以及调试相关的支持。

这里的Native系统库主要包括init孵化来的用户空间的守护进程、HAL层以及开机动画等。

启动init进程(pid=1),是Linux系统的用户进程,init进程是所有用户进程的鼻祖。

  • init进程会孵化出ueventd、logd、healthd、installd、adbd、lmkd等用户守护进程;
  • init进程还启动servicemanager(binder服务管家)、bootanim(开机动画)等重要服务
  • init进程孵化出Zygote进程,Zygote进程是Android系统的第一个Java进程(即虚拟机进程),Zygote是所有Java进程的父进程,Zygote进程本身是由init进程孵化而来的。

2.5 Framework层

(1)Zygote进程

Zygote进程,是由init进程通过解析init.rc文件后fork生成的。

Zygote进程主要包含:

  • 加载ZygoteInit类,注册Zygote Socket服务端套接字
  • 加载虚拟机
  • 提前加载类preloadClasses
  • 提前加载资源preloadResouces

(2)System Server进程

System Server进程,是由Zygote进程fork而来,System Server是Zygote孵化的第一个进程,System Server负责启动和管理整个Java framework,包含ActivityManager,WindowManager,PackageManager,PowerManager等服务。

(3)Media Server进程

Media Server进程,是由init进程fork而来,负责启动和管理整个C++ framework,包含AudioFlinger,Camera Service等服务。

2.6 App层

  • Zygote进程孵化出的第一个App进程是Launcher,这是用户看到的桌面App;
  • Zygote进程还会创建Browser,Phone,Email等App进程,每个App至少运行在一个进程上。
  • 所有的App进程都是由Zygote进程fork生成的。

2.7 Syscall && JNI

SysCall

内核提供用户空间程序与内核空间进行交互的一套标准接口,这些接口让用户态程序能受限访问硬件设备,比如申请系统资源,操作设备读写,创建新进程等。用户空间发生请求,内核空间负责执行,这些接口便是用户空间和内核空间共同识别的桥梁。

这里提到两个字“受限”,是由于为了保证内核稳定性,而不能让用户空间程序随意更改系统,必须是内核对外开放的且满足权限的程序才能调用相应接口。

在用户空间Native和内核Native空间之间,有一个叫做Syscall(系统调用, system call)的中间层,是连接用户态和内核态的桥梁。

这样即提高了内核的安全型,也便于移植,只需实现同一套接口即可。Linux系统,用户空间通过向内核空间发出Syscall,产生软中断,从而让程序陷入内核态,执行相应的操作。对于每个系统调用都会有一个对应的系统调用号,比很多操作系统要少很多。

(1)安全性与稳定性

内核驻留在受保护的地址空间,用户空间程序无法直接执行内核代码,也无法访问内核数据,通过系统调用。

(2)性能

Linux上下文切换时间很短,以及系统调用处理过程非常精简,内核优化得好,所以性能上往往比很多其他操作系统执行要好。

JNI

Java层与Native(C/C++)层之间的纽带JNI。

JNI(Java Native Interface,Java本地接口),用于打通Java层与Native(C/C++)层。这不是Android系统所独有的,而是Java所有。

众所周知,Java语言是跨平台的语言,而这跨平台的背后都是依靠Java虚拟机,虚拟机采用C/C++编写,适配各个系统,通过JNI为上层Java提供各种服务,保证跨平台性。

(1)流程

Android系统在启动启动过程中,先启动Kernel创建init进程,紧接着由init进程fork第一个横穿Java和C/C++的进程,即Zygote进程。Zygote启动过程中会AndroidRuntime.cpp中的startVm创建虚拟机,VM创建完成后,紧接着调用startReg完成虚拟机中的JNI方法注册。

二、Android启动的大体流程

Android系统的启动流程与Linux接近,

1.引导加载程序(Bootloader)启动

当设备上电或者重启时,首先会由引导加载程序负责启动。引导加载程序通常存储在设备的固件中,它的主要任务是初始化硬件,并加载并启动操作系统内核。引导加载程序会首先运行自身的初始化代码,然后加载操作系统内核到内存中。

2.内核加载

引导加载程序会根据预定义的配置从设备存储中加载操作系统内核。在Android设备中,通常使用的是Linux内核。引导加载程序将内核加载到内存中的指定位置。

3.内核初始化

 一旦内核加载到内存中,引导加载程序会将控制权转交给内核。内核开始执行初始化过程,包括对硬件进行初始化、建立虚拟文件系统、创建进程和线程等。

4.启动 init 进程

内核初始化完成后,会启动名为init的用户空间进程。init进程是Android系统的第一个用户空间进程,它负责系统的进一步初始化和启动。init进程会读取系统配置文件(例如 init.rc),并根据其中的指令启动系统服务和应用程序。

5.启动 Zygote 进程

 在init进程启动后,会启动名为Zygote的进程。Zygote进程是Android应用程序的孵化器,它会预加载常用的Java类和资源,以加速应用程序的启动。

6.启动系统服务

在Zygote进程启动后,还会启动一系列系统服务,例如SurfaceFlinger、ActivityManager、PackageManager等。这些系统服务负责管理系统的各个方面,包括显示、应用程序生命周期、包管理等。

7.启动桌面程序

一旦系统服务启动完成,Android系统就处于可用状态。就会启动桌面程序,用户可以开始启动应用程序并使用设备进行各种操作了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

水w

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

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

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

打赏作者

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

抵扣说明:

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

余额充值