Android从上电到加载Launcher,发生了啥

1,769 阅读6分钟

前言

遥想当年,刚接触android那会,内心一直很想弄明白,Android的开机流程究竟是怎样的?但当时一来刚入这行,什么也不懂,有点无从下手,二来忙着完成手头工作,也没时间。现在刚好有点时间,也来简单捋捋Android系统开机的过程中,都发生了什么。本篇文章尽量不涉及代码,只讲流程。

正文

看过我上一篇文章《Android系统框架》的人应该还有印象(没看过的待会可以在文末点开链接前往看看),Android系统由上至下大致可分为五层,分别是Applications层,Framework层,Native层,Hardware层,Kernel层。显然,在这五层中,Android设备最先进入的就是Kernel层。那么我们就先从这一层入手,Android是如何进入这一层的。

Kernel层

所谓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中。

然后每个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部分。启动过程如图所示:

image

简单总结如下:

系统上电->Rom boot->Pre-loader->lk(u-boot)->kernel

从上电到系统进入到内核阶段,这就是系统大概做的事情。接下来要说的是Linux内核的“天字一号”进程,init。

init&zygote

init进程其实也是Android系统的第一个进程,因为Android就是基于Linux内核的。init的进程号是1,这是一个极其重要的进程,身负重任。java世界的开创者Zygote就是它创建的。

那zygote进程是怎么被创建出来,从而创建出整个java世界呢?

先大概列出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系统开机流程的了解。

互动

如果文章存在错误描述,可直接留言,一起探讨!

可能感兴趣的文章

Android系统框架

Android studio使用系统源码的AIDL接口

关于Android状态栏高度为0仍显示的问题

最后

我在微信公众号也有写文章,更新比较及时,有兴趣者可以关注如下公众号!