相信我们对 Android 系统都不陌生, 而 Android 系统博大精深, 被各种各样的智能设备承载的同时, 我们会否好奇过, 如此复杂的 Android 究竟是怎么运作起来的呢? 借本文给大家分享, 笔者对 Android 系统启动流程的整体理解~
hi, I'm Android
现在, 按下电源键
下面是 Android 启动的核心步骤流程图, 看文字的时候, 记得回来对照图来理解喔, 希望阅读全文后, 回观流程图, 会有恍然大悟的感觉, 那么文章的目的就达到啦~
整体流程
一, 启动电源及系统启动
系统从 ROM 中开始启动, 加载引导程序到 RAM , 然后执行.
二, 引导程序
引导程序是 Android 操作系统开始运行前的一个小程序, 因此它需要针对特定主板与芯片, 并不是 Android 操作系统的一部分. 引导程序是 OEM 厂商或运行商进行加锁, 限制的地方.
1 两个阶段
检测外部 RAM 以及为第二阶段加载程序
设置网络, 内存等, 搭建内核运行环境(为了达到特殊目的时, 引导程序可以根据配置参数或者输入数据来设置内核)
2 引导程序的加载器
Android 引导程序可以在 \ bootable\bootloader\legacy\usbloader 找到, 传统的加载器包含的两个文件:
init.s 初始化堆栈, 清零 BSS 段, 会调用 main.c 中的 _main()函数
(bss segment: 通常是指用来存放程序中未初始化的全局变量的一块内存区域; BSS - Block Started by Symbol.BSS 段属于静态内存分配)
main.c 初始化硬件, 创建 Linux 标签
三, 内核启动
Android 内核启动方式类似桌面 Linux, 主要步骤:
1. 设置缓存
2. 被保护存储器
3. 计划列表
4. 加载驱动
当内核完成系统设置, 接下来即将启动系统的第一个进程 -- init 进程
四, init 进程
作为 Android 系统的第一个进程, 其 PID 为 0, 通过解析 init.rc 脚本来构建出系统初始运行形态, 这一阶段中,"Android" logo 会显示出来
(系统中, 大多数系统服务程序都是在该脚本中描述并被相继启动的)
init.rc 由 4 种类型声明组成: Actions,Commands,Services,Options
Actions: 响应某事件的过程. 当 "trigger" 所描述的触发事件产生时, 则依次执行各种 "command"
源码角度: 系统会对 init.rc 中各 "trigger" 进行匹配, 当发现符合条件的 Action, 就将它加入 "命令执行队列" 尾部(除非 Action 已存在队列中), 然后系统再对这些命令按顺序进行. on <trigger> ## 触发条件
- <command1> ## 执行命令
- <command2> ## 可执行多个命令
- ...
Commands: 命令将在所属事件发生时被一个个执行
Services: 可执行程序, 它们在特定选项的约束下会被 init 程序运行或者重启(Service 可以在配置中指定是否需要退出重启, 那么, 当 Service 出现异常 crash 时, 可有机会复原)service <name><pathname> [<argument>]*
- <option>
- <option>
Options: 对 service 的约束选项
五和六, ServiceManager,Zygote,SystemServer
科普: Daemons - 守护进程
init 进程通过解析 init.rc 来陆续启动其他关键的系统服务进程, 其中最重要的是 ServiceManager,Zygote 和 SystemServer 三者, 下面我们逐一解析:
1 ServiceManager -- Binder 机制支撑者
概述: ServiceManager 是 Binder 机制中的支撑者, 负责某 Binder 服务注册信息到底层 Binder 驱动分配的值解析.
ServiceManager 由 init 进程解析 rc 脚本时启动, 属于 core 类, 其他同类进程包括: uenetd,console,adbd 等. 根据 core 组的特性, 这些进程会同时启动或停止. 另外, ServiceManager 配置含有 critical 属性, 这意味着它是系统关键进程(如果进程不幸在 4 分钟内异常退出超过 4 次, 设备将重启并进入还原模式). 当 ServiceManager 每次重启时, 其他关键进程: zygote,media,surfaceflinger 等也会被 restart.
2. 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 函数有两项重要工作
预装载各种系统类
搭建 SystemServer 环境, 并启动 SystemServer(大部分的 Android 系统服务都在其中, 由 Java 编写)
ZygoteInit 流程总结(摘自: Gityuan -- Android 系统启动 - Zygote 篇 http://gityuan.com/2016/02/13/android-zygote/ )
解析 init.zygote.rc 中的参数, 创建 AppRuntime 并调用 AppRuntime.start()方法;
调用 AndroidRuntime 的 startVM()方法创建虚拟机, 再调用 startReg()注册 JNI 函数;
通过 JNI 方式调用 ZygoteInit.main(), 第一次进入 Java 世界;
registerZygoteSocket()建立 socket 通道, zygote 作为通信的服务端, 用于响应客户端请求;
preload()预加载通用类, drawable 和 color 资源, openGL 以及共享库以及 webView, 用于提高 ap 启动效率;
zygote 完毕大部分工作, 接下来再通过 startSystemServer(),fork 得力帮手 system_server 进程, 也是上层 framework 的运行载体.
zygote 功成身退, 调用 runSelectLoop(), 随时待命, 当接收到请求创建新进程请求时立即唤醒并执行相应工作.
ZygoteInit 结束后, 开机 Logo 就出来了.
(注意: 这里并不包括开机动画, 而是开机前 "Android" Logo 出现的那个画面, 开机动画出现之前还需要进行各种加载, 开机动画是在 "Android" Logo 出现之后才播放的)
3. SystemServer -- 大部分 Android 系统服务所在地
SystemServer 是 Android 进入 Launcher 前的最后准备, 它提供了众多的由 "Java" 语言编写的系统服务.
如果 init.rc 中为 zygote 指定启动参数 --start-system-server, 那么 ZygotyeInit 就会调用 startSystemServer 来进入 SystemServer.
startSystemServer 函数解析:
首先 ZygoteInit 通过 Zygote.forkSystemServer 来生成一个新的线程(fork), 用于承载各种系统服务.(源码角度: Zygote 内部由 Native 函数 Dalvik_dalvik_system_Zygote_forkSystemServer 来进一步实现, 最终调用底层接口的 fork 接口来实际产生进程)
根据 fork 特性, 子进程与父进程将获得相同的代码环境. pid 为 0 为子进程, 否则为父进程; 如果是前者, 则进一步调用 handleSystemServerProcess(parseArgs) 函数来完成最核心的工作 -- "启动各系统服务"(源码角度: handleSystemServerProcess 方法将 startSystemServer 中的 parsedArgs.remainingArgs 参数传给 RuntimeInit.zygoteInit, 后者又调用 nativeZygoteInit 函数)
nativeZygoteInit 调用后, 接着, 三个重要的 static 函数就要被执行了: init1 - 完成本地 Service(SurfaceFlinger,AudioFlinger 等)启动, 完成后调用 init2,init2 - 新建一个新的带 Looper 的线程 ServerThread 来启动 Java 层各 Service
后语
上面对 Android 系统启动做了一个简述, 意在给大家展现一个整体流程, 其中每个环节涉及的知识点只是浅浅掠过, 笔者也尚在学习与探索中, 希望在后续再作详细分析.
资源推荐
来源: https://www.qcloud.com/developer/article/1360945