安卓系统启动流程

幻昼 2022年12月21日 321次浏览

先来一个整体的图,过一下整体流程,Android系统启动过程从下往上的一个过程是由 BootLoader 引导开机,然后依次进入 -> Kernel -> Native -> Framework -> App

process_status

硬件部分

按开机键电路引导过程

BIOS的启动,是由硬件完成的,Intel x86系列的cpu的硬件都设计为加电(即开机瞬间)就进入16位实模式状态运行,此时将cpu的硬件逻辑设计为强行将CS的值设置为0xFFFF,IP的值设置为0x0000,这样CS:IP就指向了0xFFFF0这个位置,而这个位置就是BIOS程序的入口地址。

Android手机会将固态存储设备ROM预先映射到类似地址上,当开机加电的时候,cpu就会从该地址执行/boot分区下的Bootloader程序,载入linux内核到RAM中。接下来就是 检查RAM,初始化各种软硬件环境,加载驱动程序,挂载根文件系统,并开始执行根文件系统的init程序

手机开机基本流程图

软件部分

BootLoader

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

Linux Kernel 层

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系统将为该硬件加载相应的库模块。

Android Runtime & 系统库

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

这里的Native系统库主要包括init孵化来的用户空间的守护进程、HAL层以及开机动画等。启动init进程(pid=1),是Linux系统的用户进程,init进程是所有用户进程的鼻祖

在这里插入图片描述

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

rc文件语法

rc文件语法是以行尾单位,以空格间隔的语法,以#开始代表注释行。rc文件主要包含Action、Service、Command、Options,其中对于Action和Service的名称都是唯一的,对于重复的命名视为无效。

Action

Action: 通过触发器trigger,即以on开头的语句来决定执行相应的service的时机,具体有如下时机:

  • on early-init; 在初始化早期阶段触发;
  • on init; 在初始化阶段触发;
  • on late-init; 在初始化晚期阶段触发;
  • on boot/charger: 当系统启动/充电时触发,还包含其他情况,此处不一一列举;
  • on property:=: 当属性值满足条件时触发;

Service

服务Service,以 service开头,由init进程启动,一般运行在init的一个子进程,所以启动service前需要判断对应的可执行文件是否存在。init生成的子进程,定义在rc文件,其中每一个service在启动时会通过fork方式生成子进程。

例如: service servicemanager /system/bin/servicemanager代表的是服务名为servicemanager,服务执行的路径为/system/bin/servicemanager。

Command

下面列举常用的命令

  • class_start <service_class_name>: 启动属于同一个class的所有服务;
  • start <service_name>: 启动指定的服务,若已启动则跳过;
  • stop <service_name>: 停止正在运行的服务
  • setprop :设置属性值
  • mkdir :创建指定目录
  • symlink <sym_link>: 创建连接到的<sym_link>符号链接;
  • write : 向文件path中写入字符串;
  • exec: fork并执行,会阻塞init进程直到程序完毕;
  • exprot :设定环境变量;
  • loglevel :设置log级别

Options

Options是Service的可选项,与service配合使用

  • disabled: 不随class自动启动,只有根据service名才启动;
  • oneshot: service退出后不再重启;
  • user/group: 设置执行服务的用户/用户组,默认都是root;
  • class:设置所属的类名,当所属类启动/退出时,服务也启动/停止,默认为default;
  • onrestart:当服务重启时执行相应命令;
  • socket: 创建名为/dev/socket/<name>的socket
  • critical: 在规定时间内该service不断重启,则系统会重启并进入恢复模式

default: 意味着disabled=false,oneshot=false,critical=false。

Framework层

  • Zygote进程,是由init进程通过解析init.rc文件后fork生成的,Zygote进程主要包含:
    • 加载ZygoteInit类,注册Zygote Socket服务端套接字
    • 加载虚拟机
    • 提前加载类preloadClasses
    • 提前加载资源preloadResouces
  • System Server进程,是由Zygote进程fork而来,System Server是Zygote孵化的第一个进程,System Server负责启动和管理整个Java framework,包含ActivityManager,WindowManager,PackageManager,PowerManager等服务。
  • Media Server进程,是由init进程fork而来,负责启动和管理整个C++ framework,包含AudioFlinger,Camera Service等服务。

App 层

  • Zygote进程孵化出的第一个App进程是Launcher,这是用户看到的桌面App;

  • Zygote进程还会创建Browser,Phone,短信等App进程,每个App至少运行在一个进程上。

  • 所有的App进程都是由Zygote进程fork生成的

    start_app_process

​ 图解:

  1. App发起进程:当从桌面启动应用,则发起进程便是Launcher所在进程;当从某App内启动远程进程,则发送进程便是该App所在进程。发起进程先通过binder发送消息给system_server进程;
  2. system_server进程:调用Process.start()方法,通过socket向zygote进程发送创建新进程的请求;
  3. zygote进程:在执行ZygoteInit.main()后便进入runSelectLoop()循环体内,当有客户端连接时便会执行ZygoteConnection.runOnce()方法,再经过层层调用后fork出新的应用进程;
  4. 新进程:执行handleChildProc方法,最后调用ActivityThread.main()方法

App-create-process

img

桌面如何拉起负一屏

绑定负一屏的 AssistantOverlayService,看桌面的 AssistantLauncherClient 调用 connect,看流程图:

home2pa

开机流程的图

TODO

安卓系统知识层面图

android-stack

详细流程参考文章:

序号 进程启动 概述
1 init进程 Linux系统中用户空间的第一个进程, Init.main
2 zygote进程 所有App进程的父进程, ZygoteInit.main
3 system_server进程(上篇) 系统各大服务的载体, forkSystemServer过程
4 system_server进程(下篇) 系统各大服务的载体, SystemServer.main
5 servicemanager进程 binder服务的大管家, 守护进程循环运行在binder_loop
6 app进程 通过Process.start启动App进程, ActivityThread.main

问题

BootLoader 跟 BIOS 区别

BIOS:Basic Input/Output System(基本输入输出系统),在IBM PC兼容系统上,是一种业界标准的固件接口(来自维基百科)。有点难以理解,其实BIOS是我们电脑启动时加载的第一个程序,这个程序不是由Java语言编写也不是由C语言编写,一般是汇编程序。BIOS程序固化在主板上的一块芯片上,是连接计算机硬件与操作系统的桥梁,它保存着计算机最重要的基本输入输出的程序、开机后自检程序和系统自启动程序。

由于Android属于嵌入式设备,并没有像pc那样的BIOS程序。取而代之的是Bootloader——系统启动加载器。它类似于BIOS,在系统加载前,用以初始化硬件设备,建立内存空间的映像图,为最终调用系统内核准备好环境。

在Android里没有硬盘,而是ROM,它类似于硬盘存放操作系统,用户程序等。ROM跟硬盘一样也会划分为不同的区域,用于放置不同的程序,在Android中主要划分为一下几个分区:
/boot:存放引导程序,包括内核和内存操作程序
/system:相当于电脑c盘,存放Android系统及系统应用
/recovery:恢复分区,可以进入该分区进行系统恢复
/data:用户数据区,包含了用户的数据:联系人、短信、设置、用户安装的程序
/cache:安卓系统缓存区,保存系统最常访问的数据和应用程序
/misc:包含一些杂项内容,如系统设置和系统功能启用禁用设置
/sdcard:用户自己的存储区,可以存放照片,音乐,视频等文件

Native与Kernel之间通信方式、Java层与Native(C/C++)层之间通信方式?

系统调用(SysCall)层、JNI(Java Native Interface)

进程的Binder线程池又是何时启动?

应用进程怎么由Zygote进程创建?

fastboot 和 recovery 模式的区别?

Android设备有3个重要分区: 启动加载程序(Boot loader)、恢复(Recovery)和 Android ROM。
Bootloader最先加载并决定要加载的下一个分区,此分区通常是Android ROM。 
Recovery模式是设备用于安装Android ROM分区更新的模式, 在对手机恢复出厂设置时也会使用Recovery模式。 
默认情况下进行的recovery通常具有较少的选项,这就是自定义恢复模块可用的原因。

另一方面,Fastboot是一种协议,可用于通过USB从计算机连接到设备,并向设备的分区发出更新。 例如,当我在fastboot中时,我可以通过recovery分区进行更新。

recovery 模式:
恢复模式是一个小型Linux操作系统,可以用来对手机恢复出厂设置,或者使用供应商image对设备进行更新。

所有的设备都存在Recovery, 但并非所有设备都提供Fastboot。

fastboot 模式:
手机进入fastboot 模式,就可以安装recovery image。Fastboot现在是android sdk附带的工具,你可以用它来 re-flash 设备的分区。 因为fastboot在android之前启动,即使没有安装android,你也可以在 recovery 模式分区被破坏的情况下将它用作 recovery 模式的替代方案。

参考文献:

Android 操作系统架构开篇

http://gityuan.com/android/

Android系统启动流程(基于Android 11)

https://juejin.cn/post/6969141197596000263

Android Q 开机启动流程

https://blog.csdn.net/zhang2256109/article/details/105691449

Android从按下开机键到启动发生了什么

https://blog.csdn.net/qq_29882585/article/details/109276939

fastboot 和 recovery 模式的区别

https://blog.csdn.net/ftell/article/details/81630799