Android 的启动流程
话不多说 上图
内核里面第一个进程 idle 进程 又叫做Swapper进程 PID = 0
Kthread 进程 相当于内核的鼻祖
init 进程 启动 用户空间的鼻祖
zygote java 进程鼻祖
SystemServer zygote 的大儿子
SystemServer 又会启动很多服务, 90多个, 我们很多服务都在SystemServer进程中
SystemServer通过AMS 在zygote 出app进程
进程启动方式 fork
线程启动 new Thread
在内核中没有进程和线程之分
init 进程的启动
kernel/common/init/main.c -> kernel_init
init的入口函数 -》 main.cpp
init.rc脚本文件 按照init.rc 的内容去执行
first_state_main
- 主要做一些 挂载/ 创建 一些文件
- 重定向 输入 输出 error
- 初始化 内核的日志打印
- 启动 selinux_setup
SelinuxSetup
- SetupSelunx linux这块的安全策略 --- Android ---- 权限 最小权限原则
second_stage_main
-
PropertyInit(); --- 初始化属性域
- 处理子进程终止信号 --- 僵尸进程
- InstallSignalFdHandler(&epoll);
- InstallInitNotifier(&epoll);
- StartPropertyService(&property_fd);
- GetBultinFunctionmap () 匹配命令和函数之间的关系
- 处理子进程终止信号 --- 僵尸进程
-
LoadBootScripts() 解析init.rc
- --> CreateParser : parser
- parser.AddSectionParser("server" , xxxx);
- parser.AddSectionParser("on" , xxxx);
- parser.AddSectionParser("import" , xxxx);
- parser.ParseConfig("/system/etc/init/hw/init.rc"); // 解析 init.rc
- parserConfigDir();
- parseConfigFile();
- ParseData() 解析init 文件
- parseConfigFile();
- parserConfigDir();
- --> CreateParser : parser
-
进入while 循环 ---- 等待
- auto pending_function = epoll.Wait(epoll_timeout);
小结:
init处理的重要事情:
- 挂载文件
- 设置 seLinux -- 安全策略
- 开始属性服务 注册到 epoll中
- 解析 init.rc
- 循环处理脚本文件 -- 启动 zygote
- 循环等待
输入输出
stdio --
Linux 一切皆文件
system.out.println(); 把这句话写到文件夹中(dev/nulll 管道文件夹)
zygote 进程启动
孵化器 最重要的作用 有一部分在nitive 一部分在java
zygote 第一个进入Java的。
init.rc
- zygotr_start
- start zygote
启动 zygote
init.zygote.32
init.zygote.64
frameworks/base/cmds/app_process/Android.bp -- app_main.cpp
zygote ---> 进入 native 层
class AppRuntime : public AndroidRuntime
通过 传入参数 启动 zygote 和 systemserver
frameworks/base/core/jni/AndroidRuntime.cpp.start
runtime.start("com.android..insternall.os.ZygoreInit", args, zygote);
-->startVm 启动 虚拟机
-->startReg 注册JNI 建立 Java 方法 和 native 方法 管理起来
-->env - CallStaticVoidMethod(startClass, startMeth, startArray)
jni java 和 nitive 相互调用
zygote 的 java启动
-
preload (bootTimingTraceLog); // 预加载 提高进程的启动速度
- 类 system/etc/preloaded-classes 里面的类
- 资源 com.android.internal.R.xxx base/res/res/
-
zygoteServer = new zygoteServer(isPrimaryZygote); // socket AMS 和其连接 为什么不用 binder ,binder多线程 fock 出现死锁
-
Runnable r = forkSystemServer // 启动 systemserver进程
-
caller = zygoteServer.runSelectLoop(abiList) // 死循环 接受 AMS 传过来的消息
zygote 小结
native java 需要环境
- 初始化运行时环境 创建 JVM
- 注册 jni
- 调用 zygoteinit.main 进入 java层
java
- 预加载 加快进程创建速度
- socket 让别人通知我
- 循环等待 AMS 等别的服务的消息