6.1 framework 开机流程
init 流程:
每一个进程的启动都是从main函数开始的,比如下面的 init 的 main 函数
// init 的main 函数,没有中途return的话,会进入 firststagemain
// argv 0 是函数名,argv 1 是第一个参数
int main(int argc, char** argv) {
...
if (!strcmp(basename(argv[0]), "ueventd")) {
return ueventd_main(argc, argv);
}
if (argc > 1) {
if (!strcmp(argv[1], "subcontext")) {
android::base::InitLogging(argv, &android::base::KernelLogger);
const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
return SubcontextMain(argc, argv, &function_map);
}
if (!strcmp(argv[1], "selinux_setup")) {
android::mboot::mdb("SELinux Setup ...");
return SetupSelinux(argv);
}
if (!strcmp(argv[1], "second_stage")) {
return SecondStageMain(argc, argv);
}
}
...
return FirstStageMain(argc, argv);
}
// firstStageMain 中进行一些 mout 文件挂载,因为 linux 一切皆文件嘛,肯定要先把文件准备好
int FirstStageMain(int argc, char** argv) {
...
CHECKCALL(mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"));
CHECKCALL(mkdir("/dev/pts", 0755));
CHECKCALL(mkdir("/dev/socket", 0755));
CHECKCALL(mkdir("/dev/dm-user", 0755));
CHECKCALL(mount("devpts", "/dev/pts", "devpts", 0, NULL));
...
// 开始进入 init 的第二阶段,这里定义了 init 进程所在路径和参数
const char* path = "/system/bin/init";
const char* args[] = {path, "selinux_setup", nullptr};
...
// 这里执行定义好的 path 和 args,
// 从上面的 main 函数来看,init 进程被进入 setlinux_setup 阶段
**execv(path, const_cast(args));**
// execv() only returns if an error happened, in which case we
// panic and never fall through this conditional.
PLOG(FATAL) /system/core/rootdir/init.rc
// init.rc 包含了 start zygote 的工作,
// 当然此阶段也会构建许多许多文件,这是 linux 系统的典型,linux 系统就是解析路径的
on zygote-start && property:ro.crypto.state=unencrypted
wait_for_prop odsign.verification.done 1
# A/B update verifier that marks a successful boot.
exec_start update_verifier_nonencrypted
start statsd
start netd
**start zygote // start zyogte**
start zygote_secondary
on zygote-start && property:ro.crypto.state=unsupported
wait_for_prop odsign.verification.done 1
# A/B update verifier that marks a successful boot.
exec_start update_verifier_nonencrypted
start statsd
start netd
start zygote
start zygote_secondary
on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
wait_for_prop odsign.verification.done 1
# A/B update verifier that marks a successful boot.
// 它要去启动 zygote 的时候,就会去解析 init.zygote.rc
// init.zygote32.rc
// init.zygote64_32.rc
// init.zygote64.rc
// 里面有一行命令,比较有意思,标红的就是下面 zygote main 函数 argv 索要的参数
service **zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server**
class main // 解析的时候会找到这个 main 函数,找到 main 函数的时候会执行一些参数
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
socket usap_pool_primary stream 660 root system
onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart media.tuner
onrestart restart netd
onrestart restart wificond
task_profiles ProcessCapacityHigh
critical window=${zygote.critical_window.minute:-off} target=zygote-fatal
// zygote 的 main 函数在这里 ---> /frameworks/base/cmds/app_process/app_main.cpp
// 这里的 main 函数就会去手机上述的参数来进行解析
int main(int argc, char* const argv[]){
...
// 如果匹配到了 --zygote,就悄悄换个名字,这里还是蛮有意思的哈
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
}
...
// 在这里将 start init 加入了 args 参数中,这个参数最后会传给 runtime
if (startSystemServer) {
args.add(String8("start-system-server"));
}
// 在这里 start 启动了 android runtime 这个东西,android 是一个 jni 层的东西
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (!className.isEmpty()) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
...
}
// 来看到 android runtime 这个东西 --> /frameworks/base/core/jni/AndroidRuntime.cpp
// 这里就开始 start 了,并且原生还插桩 boot_progress_start,说明framework层开始起来了
void AndroidRuntime::start(const char* className, const Vector& options, bool ...{
...
// system server 起来
static const String8 startSystemServer("start-system-server");
...
// 插桩 boot_progress_start
addBootEvent("boot_progress_start");
...
// 创建虚拟机
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
...
// 注册 android 常用 jni
if (startReg(env) FindClass(slashClassName); // 找到类 className
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
// 这是一个比较重要的 main 函数,通过反射来启动
// 基于类找到它的方法
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
} else {
// 调用 call 执行这个main函数
// 所以上面的 runtime.start("com.android.internal.os.**ZygoteInit**", args, zygote)
// 参数传下来,就是执行的 ZygoteInit 这个类的 main 函数
env->CallStaticVoidMethod(startClass, startMeth, strArray);
...
}
// startVm,虚拟机这个东西蛮重要的,有一个团队来搞呢,所以很重要的一个函数
// 因为虚拟机堆内存的管理比较重要,
// 比如jvm stop the world,所有的调优都是基于这个函数来的
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool primary_zygote)
{
JavaVMInitArgs initArgs;
char propBuf[PROPERTY_VALUE_MAX];
char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX];
char heapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1 + PROPERTY_VALUE_MAX];
char heapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1 + ...}// 接下来还要谈谈这个 startReg,即注册 jni 函数/* * Register android native functions with the VM. *//*static*/ int AndroidRuntime::startReg(JNIEnv* env){ ... // 这个 gRegJNI 变量可以关注一下, // 这里注册了java 调用 native的jni if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) FindClass(slashClassName); // 找到类 className
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
// 这是一个比较重要的 main 函数,通过反射来启动
// 基于类找到它的方法
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
} else {
// 调用 call 执行这个main函数
**// 所以上面的 runtime.start("com.android.internal.os.ZygoteInit", args, zygote)
// 参数传下来,就是执行的 ZygoteInit 这个类的 main 函数**
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
// 这个时候就来到了 java 层级
// ZygoteInit.java --> /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
android runtime 做了3件事情,start 虚拟机(虚拟机就是一个内存管理工具),注册 jni,反射了 zygoteInit 进入 zygote
// 这个时候就来到了 java 层级
// ZygoteInit.java --> /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String[] argv) {
ZygoteServer zygoteServer = null;
// Mark zygote start. This ensures that thread creation will throw
// an error.
ZygoteHooks.startZygoteNoThreadCreation();
// Zygote goes into its own process group.
try {
Os.setpgid(0, 0);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to setpgid(0,0)", ex);
}
Runnable caller;
try {
// Store now for StatsLogging later.
final long startTime = SystemClock.elapsedRealtime();
final boolean isRuntimeRestarted = "1".equals(
SystemProperties.get("sys.boot_completed"));
...
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
// step1: 这里有个比较重要的 preload 函数过程,这个函数是比较耗时的,是可以优化的
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
}
...
ZygoteHooks.stopZygoteNoThreadCreation();
// step2 重要函数 创建 socket 服务器,等待别人通知fork进程
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
// Zygote fork 出的第一个进程 system server
// 所谓的 fork 就是复制出来一个进程
// 谁来通知我来 fork 一个进程,ams 来通知,ams 通过一个 socket 通信!
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
Log.i(TAG, "Accepting command socket connections");
// The select loop returns early in the child process after a fork and
// loops forever in the zygote.
// 循环等待 fork 出其它的应用进程,比如 launcher,比如 app
// runSelectLoop 这个函数保证 zygote while 死循环,没东西就 poll 休眠
caller = zygoteServer.runSelectLoop(abiList);
...
// fork完进程,会返回进程pid
pid = Zygote.forkSystemServer(
// return 到 handle 这里去处理
return handleSystemServerProcess(parsedArgs);
...
}
// handleSystemServerProcess 方法会返回到 zygoteInit 去处理
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
...
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, cl);
}
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit(); // 初始化运行环境
ZygoteInit.nativeZygoteInit(); // 启动binder,方法在 androidRuntime.cpp 中注册
// 通过反射创建**程序入口函数**的 method 对象,并返回 runable 对象
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
// preload 这个函数也在 ZygoteInit.java 里面
static void preload(TimingsTraceLog bootTimingsTraceLog) {
Log.d(TAG, "begin preload");
bootTimingsTraceLog.traceBegin("BeginPreload");
beginPreload();
bootTimingsTraceLog.traceEnd(); // BeginPreload
bootTimingsTraceLog.traceBegin("PreloadClasses");
preloadClasses(); // 加载系统类,系统常用类,比如上层需要用的 TextView、ImageView等
// 在这里加载了,app就可以直接拿来用了,这也是为什么 app 可以直接用的原因
bootTimingsTraceLog.traceEnd(); // PreloadClasses
bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders");
cacheNonBootClasspathClassLoaders();
bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders
bootTimingsTraceLog.traceBegin("PreloadResources");
preloadResources(); // 加载系统资源,R 文件等,以前经常在系统改的
bootTimingsTraceLog.traceEnd(); // PreloadResources
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
nativePreloadAppProcessHALs();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadGraphicsDriver");
maybePreloadGraphicsDriver();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
preloadSharedLibraries(); // 加载一些共享 so库,其实就三个:android、compiler_rt、jnigraphic
preloadTextResources(); // 加载字体资源,app运行时,字体库拿来的,就是这里来的,
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
WebViewFactory.prepareWebViewInZygote(); // 加载 webview 相关资源
endPreload();
warmUpJcaProviders(); // 初始化 jca 安全相关的参数
Log.d(TAG, "end preload");
sPreloadComplete = true;
}
// preloadClasses() 函数也在 ZygoteInit.java
private static void preloadClasses() {
...
} finally {
IoUtils.closeQuietly(is);
// Fill in dex caches with classes, fields, and methods brought in by preloading.
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
runtime.preloadDexCaches(); // 最后在这个地方加载的 preload classes
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
...
// fork 进程了解一下
fork 的时候倒是几个设置线程优先级的,可以研究一下