遥想当年,刚接触android那会,心里一直很想弄明白,Android的开机流程到底是怎样的?但当时一来刚入这行,什么也不懂,有点无从下手,二来忙着完成手头工做,也没时间。如今恰好有点时间,也来简单捋捋Android系统开机的过程当中,都发生了什么。本篇文章尽可能不涉及代码,只讲流程。java
看过我上一篇文章《Android系统框架》的人应该还有印象(没看过的待会能够在文末点开连接前往看看),Android系统由上至下大体可分为五层,分别是Applications层,Framework层,Native层,Hardware层,Kernel层。显然,在这五层中,Android设备最早进入的就是Kernel层。那么咱们就先从这一层入手,Android是如何进入这一层的。android
所谓Kernel层,其实就是系统跑到了Linux内核,而在系统进入Linux内核以前,其实还经历了一个阶段,那就是bootloader。而在Android系统中,uboot就是一种常见的bootloader程序。这里会以MTK平台做为例子,来简单介绍从机器上电到进入kernel层发生的事。须要事先说明的是,MTK平台会比其它平台多出一个preloader阶段,这个下面会说到。服务器
preloader按照mtk的说法是MTK in-house developed loader,也就说是mtk内部开发的一个loader。微信
首先须要明确的是preloader、lk、kernel、android这些系统镜像文件是存储在flash中的,而不是在CPU芯片或者DDR中。app
而后每一个mtk芯片都有个boot rom(能够当作是一段指令),在上电时刻,boot rom开始启动,boot rom加载preloader到内部的SRAM中,为何是加载到内部的SRAM中,而不是外部RAM中呢,是由于这个时候外部RAM尚未被初始化好,preloader被加载完成以后,程序就从boot rom跳转到preloader处开始执行,preloader初始化好外部RAM以后,preloader将lk(或uboot)加载外部RAM中,而后跳转到lk(或uboot)中去执行,lk(或uboot)紧接着就加载bootimage(包括kernel和ramdisk)到外部RAM中,而后去执行kernel部分。启动过程如图所示:框架
简单总结以下:socket
系统上电->Rom boot->Pre-loader->lk(u-boot)->kernel
复制代码
从上电到系统进入到内核阶段,这就是系统大概作的事情。接下来要说的是Linux内核的“天字一号”进程,init。函数
init进程其实也是Android系统的第一个进程,由于Android就是基于Linux内核的。init的进程号是1,这是一个极其重要的进程,身负重任。java世界的开创者Zygote就是它建立的。源码分析
那zygote进程是怎么被建立出来,从而建立出整个java世界呢?post
先大概列出init进程的工做流程:
1.解析init.rc文件;
2.执行init.rc文件中各个阶段的动做,而建立zygote的工做就是其中的某个阶段完成的;
3.调用property_init初始化属性相关的资源,而且经过property_start_service启动属性服务;
4.init进入一个无限循环,而且等待一些事情的发生。
复制代码
在这里,咱们只关心第二个阶段,即zygote的建立。既然zygote是经过解析init.rc文件建立,那咱们先看看这个init.rc文件:
//init.rc
import /init.${ro.zygote}.rc
复制代码
从上面的语句能够看到,init.rc并非直接引入某个固定的文件,而是根据属性ro.zygote的内容来引入不一样的文件。
属性ro.zygote的值有四种状况:
zygote32:纯32位模式
zygote32_64:混32位模式(即32位为主,64位为辅)模式
zygote64:纯64位模式
zygote64_32:混64位模式(即 64位为主,32位为辅)模式
复制代码
这里以zygote32为例,咱们看看zygote32.rc文件:
//zygote32.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
writepid /dev/cpuset/foreground/tasks
复制代码
这里经过start service的方式启动zygote,会fork出一个进程,这个进程就是zygote。 zygote建立后,会执行以下bin文件:
/system/bin/app_process
复制代码
app_process对应的源文件是App_main.cpp,这里不贴源码,只是作大概介绍。App_main.cpp路径以下:
/frameworks/base/cmds/app_process/app_main.cpp
复制代码
而在app_process中主要作的一件事就是调用AppRuntime的start方法。AppRuntime由AndroidRuntime类派生出来,而在AndroidRuntime的start方法中主要作了三件事:
/frameworks/base/core/jni/AndroidRuntime.cpp
1.建立虚拟机---startVm;
2.注册JNI函数---startReg;
3.经过JNI调用Java函数,调用的函数是ZygoteInit的main函数。
复制代码
这是开创android系统的Java世界的三大步,在这以后,zygote就正式进入了Java世界,繁殖framework的核心system_server进程。接着等待请求,孵化app,建立一个又一个的子子孙孙。launcher就是zygote的后代。
Android系统从上电,前后通过了以下流程:
系统上电->Rom boot->Pre-loader->lk(u-boot)->kernel->init->zygote->system_server&app
复制代码
若是从开机界面上来作区分的话,上电开机的时候,显示的开机logo,第一个阶段是uboot,第二阶段是kernel阶段,若是你看到开机logo一直没变,那是由于这两个阶段用的logo是同一张。第三阶段则是开机动画,这时已经进入Java的世界,等待launcher加载完成,就能够结束开机动画,从而进入咱们熟悉的launcher界面。
这里简单梳理了下Android上电后发生的一些事情,彻底没涉及到源码分析,也只是简单粗略大概讲了下流程。不少没有涉及,如uboot阶段的一些硬件参数初始化,如init在起来的时候不止启动了zygote,还建立了不少守护进程,也建立了Android系统的属性服务器,如zygote孵化出来的system_server所作的事,它会启动Android系统的核心服务。。。
Android系统很庞大,咱们的全部的了解都只是冰山一角。希望这篇文件可以给你带来一丝丝的对android系统开机流程的了解。
若是文章存在错误描述,可直接留言,一块儿探讨!
我在微信公众号也有写文章,更新比较及时,有兴趣者能够关注以下公众号!