系统启动流程大致分以下五步:

  • Loader(加载引导程序Boot Loader)
  • Kernel(Linux内核层)
  • Native(init进程)
  • Framework(Zygote进程/SystemServer进程)
  • Application(应用层/Launcher进程)

源码阅读地址参考(Android10):
www.androidos.net.cn/android/10.…


Loader

从ROM中加载BootLoader到RAM(这一步由芯片公司执行)
BootLoader:启动Android系统之前的引导程序,检测RAM,初始化硬件参数

Kernel

内核层,启动第一个进程:Swapper进程(pid=0),又称idle进程,用于初始化进程管理、内存管理、加载显示、相机、Binder等驱动

启动kthreadd进程(pid=2),是linux系统的内核进程,是所有内核进程的鼻祖,会创建内核工作线程,内核守护进程等

Kernel设置完成后,开始启动init进程

Native

启动init进程(pid=1),是Linux系统的用户进程,是所有用户进程的鼻祖,fork出一些用户守护进程,启动servicemanager,开机动画等(后续会详细介绍次阶段)

init进程fork出Zygote进程(解析init.rc文件来启动Zygote进程),Zygote是第一个虚拟机进程,创建虚拟机,注册JNI函数等

init进程fork出MediaServer进程,负责启动和管理整个C++ framework,包含AudioFlinger,CameraService等服务

Framework

Zygote进程启动后,加载ZygoteInit.java类,注册ZygoteScoket,加载虚拟机,加载类,加载系统资源,fork SystemServer进程,SystemServer是Zygote进程孵化的第一个进程,负责启动和管理整个Java framework

Application

SystemServer进程会启动Launcher进程,即桌面App


Native层

我们从Native层启动init进程开始 /system/core/init/main.cpp
init进程启动 从system/core/init/main.cpp的main函数开始

int main(int argc, char** argv) {……if (argc > 1) {……if (!strcmp(argv[1], "selinux_setup")) {return SetupSelinux(argv);}if (!strcmp(argv[1], "second_stage")) {return SecondStageMain(argc, argv);}}return FirstStageMain(argc, argv);
}

/system/core/init/first_stage_init.cpp
先执行FirstStageMain
/system/core/init/selinux.cpp
再执行SetupSelinux
/system/core/init/init.cpp
最后执行SecondStageMain
在SecondStageMain中执行了LoadBootScripts,在LoadBootScripts中可以看到,解析了init.rc文件

int SecondStageMain(int argc, char** argv) {……LoadBootScripts(am, sm);……
}static void LoadBootScripts(……) {……if (bootscript.empty()) {parser.ParseConfig("/init.rc");……}……
}

/system/core/rootdir/init.rc

……
import /init.${ro.zygote}.rc
……
//解析时启动了ServiceManager
start servicemanager
……
start zygote
start zygote_secondary
……

/frameworks/native/cmds/servicemanager/servicemanager.rc

service servicemanager /system/bin/servicemanager
......

以服务的形式启动一个名为“servicemanager”的进程,执行路为/system/bin/servicemanager
对应的源文件为service_manager.c 找到这个类中的入口函数 main 函数.(这里暂时不做介绍,后续会有专门的失眠系列来介绍servicemanager如何启动)


终于到了比较熟悉的环节,我们以init.zygote64_32.rc为例 /system/core/rootdir/init.zygote64_32.rc

service zygote  /system/bin/app_process64 ……  —socket-name=zygote
......
service zygote_secondary  /system/bin/app_process32 ……
......
  • init进程以服务的形式启动一个名为“zygote”的进程,执行路为/system/bin/app_process64
  • 创建名为zygote的socket,用于后续IPC
  • 创建了名为“zygote_secondary”的进程,用于适配不用的abi架构

/frameworks/base/cmds/app_process64/app_main.cpp app_main.cpp中的main作为Zygote启动的入口

int main(int argc, char* const argv[]){......AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));......while (i < argc) {const char* arg = argv[i++];if (strcmp(arg, "--zygote") == 0) {zygote = true;niceName = ZYGOTE_NICE_NAME;} else if (strcmp(arg, "--start-system-server") == 0) {startSystemServer = true;} else if (strcmp(arg, "--application") == 0) {application = true;} else if (strncmp(arg, "--nice-name=", 12) == 0) {niceName.setTo(arg + 12);} else if (strncmp(arg, "--", 2) != 0) {className.setTo(arg);break;} else {--i;break;}}......if (zygote) {runtime.start("com.android.internal.os.ZygoteInit", args, zygote);} else if (className) {runtime.start("com.android.internal.os.RuntimeInit", args, zygote);} else {……}
}
  • 创建AppRuntime(即AndroidRuntime),调用start方法
  • 由于zygote=true,调用runtime.start,执行ZygoteInit文件

/frameworks/base/core/jni/AndroidRuntime.cpp

void AndroidRuntime::start(){……if (startVm(&mJavaVM, &env, zygote) != 0) {return;}onVmCreated(env);if (startReg(env) < 0) {ALOGE("Unable to register all android natives\n");return;}……
}int AndroidRuntime::startReg(JNIEnv* env){……   if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {env->PopLocalFrame(NULL);return -1;}……return 0;
}void AndroidRuntime::onVmCreated(){}static const RegJNIRec gRegJNI[] = {REG_JNI(register_com_android_internal_os_RuntimeInit), REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),……
}
  • startVm启动虚拟机
  • 执行onVmCreated方法,空方法
  • 执行startReg方法
  • 执行register_jni_procs方法,注册JNI函数
  • 后续代码自行查看,反射调用Zygoteinit的main方法

Framework层

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {ZygoteServer zygoteServer = null;……//预加载资源preload(bootTimingsTraceLog);……final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);zygoteServer = new ZygoteServer(isPrimaryZygote);……//fork systemserver进程if (startSystemServer) {Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);if (r != null) {r.run();return;}}……caller = zygoteServer.runSelectLoop(abiList);……
}

frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

ZygoteServer(boolean isPrimaryZygote) {……if (isPrimaryZygote) {mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);……}……
}

frameworks/base/core/java/com/android/internal/os/Zygote.java

static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {……FileDescriptor fd = new FileDescriptor();fd.setInt$(fileDesc);return new LocalServerSocket(fd);……
}
  • 预加载资源(反射加载类,加载资源drawable / color资源, 即com.android.internal.R.xxx开头的资源)
  • 创建ZygoteServer对象,注册socket,zygote作为服务端, 不断接受其他进程发来的消息
  • fork System Server(验证了System Server是Zygote进程孵化的第一个进程)
  • 执行zygoteServer.runSelectLoop(abiList);无限循环等待AMS请求,代码如下: frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
Runnable runSelectLoop(String abiList) {while(true){……final Runnable command = connection.processOneCommand(this);……}
}

frameworks/base/core/java/com/android/internal/os/Zygote.java

Runnable processOneCommand(ZygoteServer zygoteServer) {……args = Zygote.readArgumentList(mSocketReader);……pid = Zygote.forkAndSpecialize(……);……
}

通过socket,客户端connect,服务端accept,客户端write,服务端read,根据args中的各种参数,执行Zygote.forkAndSpecialize,即Zygote孵化子进程


启动 System Server

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {……/* Request to fork the system server process */pid = Zygote.forkSystemServer(……)……//创建成果,会返回父进程pid=0if (pid == 0) {……zygoteServer.closeServerSocket();return handleSystemServerProcess(parsedArgs);}
}

frameworks/base/core/java/com/android/internal/os/Zygote.java

public static int forkSystemServer() {……int pid = nativeForkSystemServer();……
}

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

private static Runnable handleSystemServerProcess() {//先是创建了classloader cl,一路传下去……return ZygoteInit.zygoteInit(……,cl);
}public static final Runnable zygoteInit(cl) {……return RuntimeInit.applicationInit(cl);
}

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

protected static Runnable applicationInit() {……return findStaticMain(args.startClass, args.startArgs, classLoader);
}protected static Runnable findStaticMain(……) {//这里通过传来的cl,加载类,通过类找到方法(自行查看)……return new MethodAndArgsCaller(m, argv);
}static class MethodAndArgsCaller implements Runnable {……public void run() {//这里反射执行该方法,即SystemServer的main方法mMethod.invoke(null, new Object[] { mArgs });}
}

fork SystemServer进程完成后,执行handleSystemServerProcess,一路跟踪下来,返回一个runnable,内部执行方法的调用,即通过反射机制执行SystemServer类的main函数

frameworks/base/services/java/com/android/server/SystemServer.java

public static void main(String[] args) {new SystemServer().run();
}private void run() {……startBootstrapServices();startCoreServices();startOtherServices();……
}

SystemServer.run中执行各种服务的初始化,其中startOtherServices中启动了launcher,即桌面app(这里暂时不做过多介绍,后续会有专门的失眠系列来介绍SystemServer如何启动,以及做了什么)


结尾:

失眠必读系列未完待续,有任何错误,虚心讨教,欢迎指正…

  • Android 系统启动流程
  • Service Manager 启动流程
  • System Server 启动流程
  • AMS 如何注册
  • Binder 源码阅读
  • Activity 启动流程

为了帮助到大家更好的从底层方面入手掌握性能优化相关知识点,这准备了Framework 知识点汇总、性能优化知识点汇总和Android 性能监控框架 的学习文档,中间记录了 启动优化、内存优化、UI优化……等知识点,可谓是很全面了 看↓↓↓方

有需要的可以复制下方链接,传送直达!!!
https://qr21.cn/CaZQLo?BIZ=ECOMMERCE

内功心法不是一天两天就可以修炼出来的,而是需要每天的坚持,技术提升也是如此。所以最好的速成修炼方法就是每天学习一点,日积月累后就会发现自己进步的效果。

详解 Android 系统启动流程相关推荐

  1. 源码详解Android 9.0(P) 系统启动流程之SystemServer

    源码详解Android 9.0(P) 系统启动流程目录: 源码详解Android 9.0(P)系统启动流程之init进程(第一阶段) 源码详解Android 9.0(P)系统启动流程之init进程(第 ...

  2. android系统加载主题的流程,详解Android布局加载流程源码

    一.首先看布局层次 看这么几张图 我们会发现DecorView里面包裹的内容可能会随着不同的情况而变化,但是在Decor之前的层次关系都是固定的.即Activity包裹PhoneWindow,Phon ...

  3. Android系统启动流程 -- bootloader

    Android系统启动流程 -- bootloader   BootLoader:在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行.可以初始化硬件设备.建立内存空间映射图,从而将系 ...

  4. 详解Android主流框架不可或缺的基石

    探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架 ...

  5. 现在详解Android App AllowBackup配置带来的风险

    现在位置:  首页 >  文章 >  移动安全 > 正文 详解Android App AllowBackup配置带来的风险 2015 /3/11 1:27 10,105 评论 3 条 ...

  6. Android 7.1.2(Android N) Android系统启动流程

    Android 7.1.2(Android N) Android系统启动流程 源码: system/core/rootdir/ init.rc init.zygote64.rc system/core ...

  7. 两分钟窃取身边女神微博帐号?详解Android App AllowBackup配置带来的风险

    两分钟窃取身边女神微博帐号?详解Android App AllowBackup配置带来的风险 笔者在使用自己编写的Drozer模块对国内流行的安卓手机应用进行自动化扫描后发现有大量涉及用户财产和隐私的 ...

  8. 深度详解 Android 之 Context

    文章目录 一. 简介 1.1 Context 概述 1.2 Context 体系结构 1.3 Context 作用域 1.4 总结 二. Context 详解 2.1 Application Cont ...

  9. android常用技术网站收藏过的网址 给 Android 开发者的 RxJava 详解 Android设备标识-没有完美的解决方案-只有取舍 - 小彼得的专栏 - 博客频道 - CSDN.NET

    收藏过的网址 http://www.jianshu.com/p/a7b36d682b6f?ref=myread  Android插件化快速入门与实例解析 http://www.cnblogs.com/ ...

最新文章

  1. react 禁止微信调整字体大小
  2. matlab 神经网络预测时间序列示例(水痘模型)
  3. 十、oracle 常用函数
  4. 前端学PHP之面向对象系列第四篇——关键字
  5. Vue项目实战03 : vue中 meta 路由元信息
  6. IOS之AutoLayout框架的使用
  7. handler原子锁_Linux的原子操作与同步机制
  8. python新奇检测_3种Python检测URL状态
  9. docker 安装kafka(快速)
  10. 中国成全球第二AI医疗交易国,上半年AI制药融资数等于去年全年 | 报告
  11. 基于Tight VNC的远程协助功能的实现
  12. 《Python机器学习——预测分析核心算法》——2.3 对“岩石vs.水雷”数据集属性的可视化展示...
  13. 01-SA8155P Flat Build QFIL刷机
  14. 如何给计算机安装驱动程序,电脑系统怎么安装驱动程序
  15. NOI题库练习1.5(38)
  16. 如何将XML转换为HL7
  17. 本地连接测试mysql失败,提示 flush hosts;
  18. 干货 | Trip.com APP QUIC应用和优化实践
  19. 已设置过微信号怎么改?这个官方提示你得知道!
  20. Matlab中的c2d函数离散化

热门文章

  1. 深入理解计算机系统第四章(4.55-4.58)
  2. 山东农业大学计算机类男女比例,男女比例_山东农业大学
  3. CVPR 2019 | 「识面知心」——基于自监督学习的微表情特征表达
  4. 黑马SpringBoot --基础篇
  5. 强监管焕新外卖行业,美团、饿了么如何应对?
  6. 第二十六篇 request模块使用
  7. mxgraph初体验
  8. 网易互娱2017实习生招聘在线笔试第一场-3划线
  9. 淘集集报活动需要隐身上架商品的链接吗?
  10. html5页面中添加腾讯地图api