Android 系统启动流程

概述

站在巨人的肩膀上学习,本片博客参考 gityuan,用于笔记和巩固知识node

Android 架构

在这里插入图片描述
这个是Google官方提供的经典的分层架构图,从下向上依次是, Linux内核HAL系统Native库和Android RuntimeJava框架层应用层,其中每一层都有若干的子模块和子系统

Google提供的5层很经典,可是为了更进一步的透视Android 系统架构,以进程的视角,以分层的架构,来诠释Android的全貌,诠释Android 全貌的内在联系linux

Android 启动架构图

在这里插入图片描述

Android 系统启动过程由上图从下向上的一个过程,由Boot Loader引导开机,而后依次进入Kernel -> Native-> Framework-> App,下面简要介绍这几个过程android

开机(关于Loader层)git

  • Boot ROM:当手机处于关机的状态,长按Power键开机,引导芯片从固化在ROM里预设的代码开始执行,而后加载程序到RAM
  • Boot Loader:这是启动Android系统以前的引导程序,主要是检查RAM,初始化硬件参数等工能

关于Kernel (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进程是全部内核进程的鼻祖

关于硬件抽闲层(HAL)架构

硬件抽象层(HAL)提供标准接口,HAL包括多个库模块,每一个模块都为特定的硬件组件实现一组接口,好比Wifi/蓝牙模块,当框架API请求访问硬件时,Android系统将为该硬件加载相应的库模块app

Android Runtime 和 系统库框架

每一个应用都在本身的进程中运行,都有本身的虚拟机实例,ART经过执行dex文件可在设备能运行多个虚拟机,DEX文件是专门为Android设计的字节码格式,通过优化使用的内存很小,ART主要包括的工能是,预先(AOT)和即时(JIT)编译 ,优化垃圾回收(GC),以及调试相关支持oop

这里的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进程孵化出来的

Framework层

  • Zygote进程,是由init进程经过解析init.rc文件后fork生成的,Zygote进程主要包括
    • 加载Zygoteinit类,注册Zygote Socket服务端套接字
    • 加载虚拟机
    • 提早加载类PreloadClasses
    • 提早加载资源PreLoadResouces
  • System Server 进程,是由Zygote fork而来,System Server是Zygote孵化出的第一个进程,System Server 负责启动和管理整个Java FrameWork,包含ActivityManagerService, WorkManagerService,PagerManagerService,PowerManagerService等服务
  • Media Server 进程,是由init fork而来,负责启动和管理整个C++FrameWork,包含AudioFlinger,Camera Service等

App层

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

Syscall && JNI

  • Native 和 KerNel之间有一层系统调用(Syscall)
  • Java 层和Native层之间的纽带JNI

重要的进程

在这里插入图片描述
Android 系统中极其重要的进程, initZygote, ServiceMager, system_server

init 进程

  • Linux系统中用户空间的第一个进程init.main

  • init进程还启动了ServiceManager进程(Binder的管家),bootanim(开机动画)等重要服务

  • init 进程还孵化除了Zygote进程Zygote进程是Android中的第一个Java进程(即虚拟机进程)Zygote是全部Java进程的父进程,Zygote进程自己就是init进程孵化出来的

Zygote进程

  • 全部App的父进程,ZygoteInit.main

  • Zygote进程,是由init进程经过解析init.rc文件后fork生成的,Zygote进程主要包括

    • 加载Zygoteinit类,注册Zygote Socket服务端套接字
    • 加载虚拟机
    • 提早加载类PreloadClasses
    • 提早加载资源PreLoadResouces
  • system_server进程,是由Zygote fork而来,System Server是Zygote孵化出的第一个进程,System Server 负责启动和管理整个Java FrameWork,包含ActivityManagerService, WorkManagerService,PagerManagerService,PowerManagerService等服务

system_server进程

系统各大服务的载体, SystemServer.main system_server进程从源码角度来看能够分为,引导服务,核心服务和其余服务

  • 引导服务(7个):ActivityManagerService、PowerManagerService、LightsService、DisplayManagerService、PackageManagerService、UserManagerService、SensorService;
  • 核心服务(3个):BatteryService、UsageStatsService、WebViewUpdateService;
  • 其余服务(70个+):AlarmManagerService、VibratorService等。

ServiceManger进程

bInder服务的大管家

ServiceManager 是Binder IPC通讯过程当中的守护进程,自己也是一个Binder,可是并无采用多线程模型来跟Binder通讯,而是自行编写了binder.c直接和Binder驱动来通讯,而且只有一个binder_loop来读取和处理事务,这样作的好处是简单和高效 ServiceManager自己工做相对简单,其工能查询和注册服务

流程图

在这里插入图片描述
ServiceManager 集中管理系统内的全部服务,通能过权限控制进程是否有权注册服务,经过字符串来查找是否有对应的Service,因为ServiceManager进程注册了Service的死亡通知,那么服务所在的进程死亡后,只需告诉ServiceManager,每一个Client经过查询ServiceManager能够获取Service的状况

启动主要包括如下几个阶段

  • 打开Binder驱动,并调用mmap()方法分配128k的内存映射空间,binder_open
  • 注册成为Binder服务的大管家binder_become_context_manager
  • 验证selinux权限,判断进程是否有权注册查看指定服务
  • 进入无限循环,处理Client发来的请求 binder_loop
  • 根据服务的名称注册服务,重复注册会移除以前的注册信息
  • 死亡通知,当所在进程死亡后,调用binder_release方法,而后调用binder_node_release,这个过程发出死亡通知回调

App进程

  • 经过Process.start启动的App进程ActivityThread.main
  • Zygote 孵化出的第一个App进程是Launcher,这是用户看到的桌面App
  • Zygote 还会建立出BrowserPhoneEmail等App进程,每一个App至少运行在一个进程上
  • 全部的App进程都是由Zygote fork而成

进程与线程的区别

进程:每一个App启动前必须先建立一个进程,该进程是由Zygote fork出来,进程具备独立的资源空间,用于承载App运行的各类Activity/Service组件,进程对于上层的应用层来讲是彻底透明的,这也是Google刻意为之,让App程序都运行在Android Runtime,大多数状况一个App运行在一个进程中,除非在AndroidManifest.xml文件中配置了Android:process,或者经过Native代码fork进程

线程:线程对于咱们来讲比较熟悉,好比每次new Thread().start,都会建立一个新的线程,该线程没有本身的独立空间,而是与所在的进程资源共享,从Linux来讲,进程与线程都是task_struct结构体,除了是否资源共享外,没有任何区别

看一下进程建立的过程

在这里插入图片描述

  • App发起进程:若是从桌面启动应用,则发起进程即是Launcher所在的进程,当从某App启动远程进程,则发起进程是App所在的进程,发起进程首先须要经过Binder发送信息给system_server进程
  • system_server进程:调用Process.start方法,经过Socket向Zygote进程发送新建进程的请求
  • zygote进程:在执行ZygoteInit.main()后进入runSelectLoop()循环体,当有客户端链接时,便会执行ZygoteConnection.runOnce()方法,再通过层层调用后fork出新的应用进程
  • 新进程:执行handleChildProc方法,设置进程名,打开binder驱动,启动新的binder线程,设置art虚拟机参数,反射目标类的main方法,即调用ActivityThread.main()方法

Process.start()方法是阻塞方法,等待直到进程建立完成返回响应的pid,才完成该方法

在这里插入图片描述
相关文章
相关标签/搜索