前言

Android 系统启动流程的一次整体梳理。

按下电源键

Step 1 启动电源及系统启动

系统从 ROM 中开始启动,加载引导程序到 RAM ,然后执行

Step 2 引导程序

引导程序是 Android 操作系统开始运行前的一个小程序,因此它需要针对特定主板与芯片,并不是 Android 操作系统的一部分。引导程序是 OEM 厂商或运行商进行加锁、限制的地方。

两个阶段:

  1. 检测外部 RAM 以及为第二阶段加载程序
  2. 设置网络、内存等,搭建内核运行环境(为了达到特殊目的时,引导程序可以根据配置参数或者输入数据来设置内核

Android引导程序可以在\bootable\bootloader\legacy\usbloader找到,传统的加载器包含的两个文件:

  1. init.s 初始化堆栈,清零BSS段(bss segment:通常是指用来存放程序中未初始化的全局变量的一块内存区域;BSS - Block Started by Symbol。BSS段属于静态内存分配),会调用 main.c 中的 _main()函数
  2. main.c 初始化硬件,创建 linux 标签

Step 3 内核

Android 内核启动方式类似桌面 linux,主要步骤:设置缓存、被保护存储器、计划列表、加载驱动

当内核完成系统设置,接下来即将启动系统的第一个进程 -- init 进程

Step 4 init 进程

作为 Android 系统的第一个进程,其PID为0,通过解析 init.rc 脚本来构建出系统初始运行形态,这一阶段中,“Android” logo 会显示出来(系统中,大多数系统服务程序都是在该脚本中描述并被相继启动的)

init.rc 由4种类型声明组成:Actions、Commands、Services、Options

  • Actions:响应某事件的过程。当“trigger”所描述的触发事件产生时,则依次执行各种“command”
    源码角度:系统会对 init.rc 中各“trigger”进行匹配,当发现符合条件的 Action,就将它加入“命令执行队列”尾部(除非 Action 已存在队列中),然后系统再对这些命令按顺序进行。
on  ##触发条件   ##执行命令   ##可执行多个命令  ...
  • Commands:命令将在所属事件发生时被一个个执行
  • Services:可执行程序,它们在特定选项的约束下会被 init 程序运行或者重启(Service 可以在配置中指定是否需要退出重启,那么,当 Service 出现异常 crash 时,可有机会复原)
service  []*   
  • Options:对 service 的约束选项

Step 5、6 ServiceManager、Zygote、SystemServer

科普:Daemons - 守护进程

init进程通过解析 init.rc 来陆续启动其他关键的系统服务进程,其中最重要的是 ServiceManager、Zygote 和 SystemServer 三者,下面我们逐一解析:

ServiceManager -- Binder 机制支撑者

概述:ServiceManager 是 Binder 机制中的支撑者,负责某 Binder 服务注册信息到底层 Binder 驱动分配的值解析。

ServiceManager 由 init 进程解析 rc 脚本时启动,属于 core 类,其他同类进程包括:uenetd、console、adbd等。根据 core 组的特性,这些进程会同时启动或停止。另外,ServiceManager 配置含有 critical 属性,这意味着它是系统关键进程(如果进程不幸在4分钟内异常退出超过4次,设备将重启并进入还原模式)。当 ServiceManager 每次重启时,其他关键进程:zygote、media、surfaceflinger 等也会被 restart。

Zygote -- “孕育”新线程与进程

Android 中大多数应用进程与系统进程都是通过 Zygote 来生成的。Zygote 同样由 init 解析 rc 脚本时启动,属于 main 类,同属 main 类的系统进程有:netd、debuggerd、rild等。Zygote并不是处于独立的程序中的,它所在程序名为“app_process”,观察 app_process 主函数实现知道,如果 init.rc 中指定了 --zygote选项,app_process 接下来将启动“ZygoteInit”,并传入“start-system-server”,这样,ZygoteInit 就会运行在虚拟机上(Dalvik VM)上了。

ZygoteInit 函数有两项重要工作:

  1. 预装载各种系统类
  2. 搭建 SystemServer 环境,并启动 SystemServer(大部分的 Android 系统服务都在其中,由 Java 编写)

ZygoteInit 流程总结(摘自:Gityuan -- Android 系统启动-Zygote 篇)

  1. 解析init.zygote.rc中的参数,创建AppRuntime并调用AppRuntime.start()方法;
  2. 调用AndroidRuntime的startVM()方法创建虚拟机,再调用startReg()注册JNI函数;
  3. 通过JNI方式调用ZygoteInit.main(),第一次进入Java世界;
  4. registerZygoteSocket()建立socket通道,zygote作为通信的服务端,用于响应客户端请求;
  5. preload()预加载通用类、drawable和color资源、openGL以及共享库以及WebView,用于提高ap启动效率;
  6. zygote完毕大部分工作,接下来再通过startSystemServer(),fork得力帮手system_server进程,也是上层framework的运行载体。
  7. zygote功成身退,调用runSelectLoop(),随时待命,当接收到请求创建新进程请求时立即唤醒并执行相应工作。

ZygoteInit 结束后,开机动画就出来了(注意:前面说道的并不是开机动画,而是开机前 “Android” Logo 出现的那个画面)

SystemServer -- 大部分 Android 系统服务所在地

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

如果 init.rc 中为 zygote 指定启动参数 --start-system-server,那么 ZygotyeInit 就会调用 startSystemServer 来进入 SystemServer。

startSystemServer函数解析:

  1. 首先 ZygoteInit 通过 Zygote.forkSystemServer 来生成一个新的线程(fork),用于承载各种系统服务。(源码角度:Zygote 内部由 Native 函数 Dalvik_dalvik_system_Zygote_forkSystemServer 来进一步实现,最终调用底层接口的** fork 接口**来实际产生进程)
  2. 根据fork特性,子进程与父进程将获得相同的代码环境pid为0为子进程,否则为父进程;如果是前者,则进一步调用** handleSystemServerProcess(parseArgs) 函数来完成最核心的工作 -- “启动各系统服务”(源码角度:handleSystemServerProcess 方法将 startSystemServer 中的 parsedArgs.remainingArgs 参数传给 RuntimeInit.zygoteInit,后者又调用 nativeZygoteInit 函数**)
  3. nativeZygoteInit 调用后,接着,三个重要的 static 函数就要被执行了:init1 - 完成本地Service(SurfaceFlinger、AudioFlinger等)启动,完成后调用 init2init2 - 新建一个新的带 Looper 的线程 ServerThread来启动 Java层各 Service

后续的启动

上面对 Android 系统启动做了一个简述,意在给大家展现一个整体流程,其中每个环节涉及的知识点只是浅浅掠过,笔者也尚在学习与探索中,希望在后续再作详细分析。

资源推荐

  • Gityuan - Android 开篇
  • 老罗的Android之旅
  • 《深入理解 Android 内核设计思想》 由浅入深,落实到源码层面上进行探索,知识很有深度

更多相关文章

  1. Android(安卓)Activity process(进程设置)
  2. [闲话杂谈] Android(安卓)跟 Linux 是有差別的(轉)
  3. Android机器人的七十二变
  4. 监听android屏幕亮、暗、锁和关闭系统动作
  5. 分析方法论探讨之设计意图
  6. 安卓开发笔记——从0到1
  7. Android(安卓)开机如何跨过Luancher界面直接显示定制的app?
  8. 开发者如何选择系统平台?Android、IOS还是Windows Phone?
  9. Android(安卓)属性系统

随机推荐

  1. Android(安卓)项目如何获取MD5和SHA1
  2. Android中广播的基本原理
  3. android jni入门基础
  4. 一个简单的手电筒APP源码分享(支持Android
  5. Android(安卓)Bitmap详解
  6. Android(安卓)View的onClick回调机制
  7. Android(安卓)动态创建Drawable selector
  8. 环形进度条简单实现
  9. Android——RecyclerView根据不同的item
  10. 自定义控件其实很简单(笔记一)