前提知识
PC主板上有一小段程序叫做BIOS,主板加电时它是第一个跑起来的程序。
功能:
- 硬件检测
- 初始化中断向量、设置寄存器等
- 从硬盘的开始扇区读取记录,引导操作系统
这个在android中叫Bootloader
系统加载
首先Android启动三种方式:
1.Bootloader交互式启动,此时可刷全部存储空间(和向硬盘中装系统一样、放入正确的路径/分区)
2.recover模式,从recovery.img镜像启动系统,可以修改部分存储,更新系统
3.Main System,从boot.img镜像启动系统
引导默认从Main System启动
系统启动
此时linux系统启动,设置缓存、被保护存储器、计划列表,加载驱动等系统任务。创建基本的程序运行环境,启动init进程。
android在init进程中启动/init.rc脚本来启动android系统
里面有一句import /init.${ro.zygote}.rc
在default.prop中定义ro.zygote=zygote64_32
/init.zygote64_32.rc中:
创建名为zygote的进程,这个zygote进程要执行的程序是/system/bin/app_process64后面都是参数。
可见我的nexus_6p 8.1.0是启动/system/bin/app_process64来启动Zygote进程的。
android启动zygote
时序图:
app_main.cpp
/system/bin/app_process64的源码位于frameworks\base\cmds\app_process\app_main.cpp
|
|
主要干了:
- 处理分发各参数
- 创建AppRuntime对象
- runtime.start(“com.android.internal.os.ZygoteInit”, args, zygote);参:类名,设置,true
AppRuntime
定义于frameworks\base\cmds\app_process\app_main.cpp
|
|
为AndroidRuntime类的子类,构造中调用父,本身无start方法
AndroidRuntime类定义于frameworks\base\core\jni\AndroidRuntime.cpp
首先看下构造方法:
|
|
为全局静态变量gCurRuntime赋值,该AndroidRuntime一个进程只会有一个。
注意构建函数的俩个参数:第一个为程序名的地址,但是在进程初始堆栈中argv[0]指向的正是初始栈的参数字串统一存储区域一开始的位置(由运行库传给main)
第二个参数为参数块大小。因此可以命名为 mArgBlockStart作为所有参数存于全局。
runtime.start(“com.android.internal.os.ZygoteInit”, args, zygote);执行的是AndroidRuntime类的start方法
|
|
Dalvik虚拟机和ART虚拟机都实现了三个用来抽象Java虚拟机的接口:
- JNI_GetDefaultJavaVMInitArgs – 获取虚拟机的默认初始化参数
- JNI_CreateJavaVM – 在进程中创建虚拟机实例 这里创建javavm与javaenv给予该进程虚拟机
- JNI_GetCreatedJavaVMs – 获取进程中创建的虚拟机实例
art通过替换libdvm.so为libart.so,开放公共接口,从而替换虚拟机,安装时dex->oat
libnativehelper/JniInvocation.cpp中:
|
|
AndroidRuntime::start的过程:参:执行的java类com.android.internal.os.ZygoteInit,设置,true 。返回void
- jni_invocation.Init(NULL);加载libart.so,导出虚拟机接口
- startVm(&mJavaVM, &env, zygote)启动虚拟机,参:全局静态量JavaVM类型的地址,该函数内变量JNIEnv类型的地址,true。返回0成功
- startReg(env)注册jni方法,参:函数内变量JNIEnv*类型的地址。返回>=0表成功
- env->CallStaticVoidMethod(startClass, startMeth, strArray);通过jni调用com.android.internal.os.ZygoteInit的main。参:jclass类型的类对象,main方法id,参数数组
之后进入java层。
ZygoteInit
位于frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
参数为设置选选项
ZygoteInit.main的主要任务:
- 构造ZygoteServer对象
- zygoteServer.registerServerSocket(socketName);//ZygoteServer注册socket名字为zygote
- startSystemServer(abiList, socketName, zygoteServer);开启系统服务,第一个子进程。参:abilist,zy注册的socketName,zy开启的socketName对象。
- zygoteServer.runSelectLoop(abiList);进入选择循环,参为abilist
zygoteServer
位于frameworks\base\core\java\com\android\internal\os\ZygoteServer.java
该函数进入循环模式监听处理消息
总结
init启动zygote进程,期间进行了native库加载、初始化jni环境、初始化bootclassloader、加载framework等操作,最后jni调用启动zygote。
zygote在java层主要做了俩件事:
- startSystemServer进程,该进程运行SystemServer服务,其启动WMS、PMS、AMS等众多系统服务
- 进入loop监听socket,听从SystemServer发送的消息进行分裂。