基于Android12的Android启动流程介绍

本文详细介绍了Android系统从上电到系统服务启动的完整流程,包括Bootloader、Kernel、init、Zygote和SystemServer的启动过程。重点阐述了init进程如何解析init.rc文件,启动Zygote和SystemServer,以及Zygote如何通过fork创建SystemServer进程。同时,提到了servicemanager在系统启动中的角色,它是Binder通信的核心组件。整个启动过程涉及硬件初始化、内核加载、用户空间服务启动等多个环节,展现了Android系统复杂而有序的启动机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android系统启动流程介绍

概述

本文将介绍Android系统的启动,从上电开始到系统服务启动完成。整个流程的可以简述为如下流程BootLoader->Kernel -> Native-> Framework-> App,简单讲述一下每个阶段,详细的自下而上的流程介绍如下图

在这里插入图片描述

接下来介绍一下这些阶段的具体细节

上电->Bootloader

本阶段主要任务:引导芯片从固化在ROM里预设的代码开始执行。它将引导加载程序加载到RAM中并开始执行。

Bootloader->Kernel

Bootloader的主要作用是准备硬件环境,引导Linux Kernel(Linux内核)的启动。
启动过程中,会区分本次要启动的系统是Android系统或Recovery模式还是Fastboot模式,完成引导加载程序后,它将执行跳转到Linux内核

Kernel->init

Android系统底层基于Linux Kernel, Linux内核在Android上启动的方式与在其他系统上类似。它将设置系统运行所需的一切。初始化中断控制器,设置内存保护,缓存和调度。

  • 启动swapper进程(pid=0),这是系统初始化过程kernel创建的第一个进程,用于初始化进程管理、内存管理、加载Display、Camera、Binder等驱动
  • 启动kthreadd进程,这是Linux系统的内核进程。kthreadd是所有内核进程的鼻祖。
    一旦内存管理单元和缓存被初始化,系统将能够使用虚拟内存并启动用户空间进程。 内核将在根文件系统中查找init进程入口(在Android目录的system/core/hw/init下找到),并将其作为初始用户空间进程启动

init

Kerner启动找到init进程后,进程入口为源码init目录下的main.cpp的main(),然后在Selinux.cpp中使用execv启动init进程(旧版本直接调用/system/core/init/Init.cpp的main())。这个init进程是Linux系统中用户空间的第一个进程(pid=1)
init进程入口
selinux.cpp的Setuplinux方法中加载了selinux的策略并启动selinux的强制模式然后启动了init进程。init的二进制文件存放在机器的/system/bin/init,然后通过execs启动init进程。
代码内容如下:
selinux.cpp关键代码

这里简单介绍一下FirstStageMain方法所做的工作

  1. 处理init进程挂掉的情况
  2. 设置用户组,挂载相关系统文件
  3. 根据/force_debuggable文件来判断是否允许adb root指令
  4. 找到init的二进制文件目录,通过execv来启动init进程

至此init进程就被启动起来了,接下来看一下SecondStageMain方法

SecondStageMain

SecondStageMain函数实现是在init.cpp中,由此可知该函数是其实是init.cpp的入口函数,(在Android10之前的版本中,该类的入口函数为main)其中的主要工作是:

  1. 使用epoll对init子进程的信号进行监听
  2. 初始化系统属性,使用mmap共享内存
  3. 开启属性服务,并注册到epoll中
  4. 加载系统启动脚本"/init.rc"
  5. 解析启动脚本,启动相关服务

init进程负责的事情主要便是对init.rc这个系统启动脚本文件进行解析下面从这个rc文件分析相关内容与关键系统服务的启动

initrc

init.rc文件内容为
init.rc部分

可以看到这个rc文件还引入了其余的rc文件,这里介绍其中部分
当需要定制系统时,读取ro.hardware属性对应的rc文件,启动相关定制系统服务,每个项目定制的rc文件一般存放在${AndroidSourcePath}/device目录下。
关键的rc还有导入的zygote的rc文件,然后启动了servicemanager。

init->Zygote

Zygote是一个VM进程,是Java进程的鼻祖, Zygote进程会创建 system_server进程以及各种app进程,它在系统启动时由init进程解析init.rc文件通过app_process启动。import的对应的rc文件是init.zygote64_32.rc

zygote
可以看到zygote是通过app_process64来启动的,app_process 调用的命令格式如下
app_process [java-options] cmd-dir start-class-name [options]
可执行文件本身路径 [Java虚拟机参数] 可执行程序所在父目录路径 内部参数
参数三往后:为,有如下四种使用方法

--zygote : 以Zygote模式启动 
--start-system-server: 启动SystemServer 
--application : 以独立应用程序模式启动(非Zygote模式)
--nice-name:设置新启动的进程名称,

该_app_process64的代码路径与重要调用如下图
app_main

根据runtime.start可知最后启动的是com.android.internal.os.ZygoteInit的main方法,该包名对应的是ZygoteInit.java细节如下
ZygoteInit

流程:解析rc->调用appprocess->设置进程名称zygote->调用ZygoteInit.java初始化进程->jni调用zygoteInit.cpp完成进程创建->调用runSelectionLoop(),接收其他进程发送的消息创建子进程

Zygote->SytemService

Zygote进程启动后,通过fork的方式启动了SystemServer,简单介绍一下是如何fork SystemServer的

ZygoteInitforkSystemServernativeForkSystemServer

以上就是通过Zygote fork SystemServer的过程,整个流程简述如下

  1. 解析zygote.rc的相关脚本,获取startSystemserver的属性字段
  2. 调用startSystemServer()
  3. 调用forkSystemServer(),为当前进程赋予权限,并设置UID,GID
  4. 创建ZygoteArgument,调用zygote.forkSystemServer
  5. JNI调用native的函数,nativeForkSystemServer完成进程的fork工作

在讲解SystemServer前,需要介绍Zygote的另外一个重要功能:启动servicemanager,等介绍完这个Binder大管家后,再回来介绍SystemServer

Init->service_manager

回顾一下上面的init.rc文件
init.rc

在Zygote启动后,开始启动servicemanager,这里的servicemanager的定义是在Android.bp下

表示servicemanager关联的rc文件是servicemanager.rc,入口是main.cpp

Android.bp
这个servicemanager的rc文件内容如下:
servicemanager.rc
init进程解析rc后会调用serviceManager进程的入口,执行对应的可执行文件:main.cpp的main()方法
main.cpp
上述main代码实现的功能是:

  1. 打开binder驱动
  2. 成为context manager
  3. 开启binder的loop循环,等待客户端发送过来的请求

binder驱动打开后继续向下追踪代码可以得知:
通过mmap(),binder驱动与serviceManager进程建立了映射关系。
本质上就是完成serviceManager进程的虚拟内存空间与内核中binder驱动的物理内存的映射。
具体细节不在本文介绍,至此servicemanager启动完成。继续回到SystemServer继续分析

SystemServer

在上上节已经介绍了Zygote是如何孵化SystemServer的进程,是调用了native层的forkSystemServer()来fork子进程,这也是Zygote fork出的第一个进程。回顾一下ZygoteInit.java的forkSystemServer。
ZygoteInit.java

参数args中添加了SystemServer类的全限定名,接下来主要看一下handleSystemServerProcess()看看是如何完成新fork的SystemServer进程剩余工作的并确定如何进入SystemServer的main方法的
RuntimeInit.java
经过了上述的过程终于进入了SystemServer的main方法

SystemServer maini各阶段启动服务
自此SystemService启动系统服务流程介绍完成。这些服务基本通过
ServiceManager.addService将自身注册进servicemanager统一管理,获取时使用getService获取对应的manager。
这里给出Init启动Zygote到startService的时序图,供参考
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值