美文网首页
Android 系统启动过程-Zygote启动

Android 系统启动过程-Zygote启动

作者: Bfmall | 来源:发表于2023-02-27 16:02 被阅读0次
image.png

从上图我们可以清楚的看到Android系统的启动分为以下几个步骤

启动电源以及启动系统

当我们按下电源键时, 引导芯片代码开始从预定义的地方(固化在ROM)开始执行, 加载引导程序到RAM, 然后执行

引导程序

引导程序是在Android操作系统开始运行前的一个小程序. 引导程序是运行的第一个程序, 因此它是针对特性的主板和芯片的. 设备制造商要么使用很受欢迎的引导程序比如redboot, uboot, qi bootloader或者开发自己的引导程序, 在此注意一下, 引导程序并不是Android操作系统的一部分. 引导程序是OEM厂商或运营商加锁和限制的地方.

引导程序分为两个阶段执行.
第一: 检查外部的RAM以及加载对第二阶段有用的程序
第二: 引导程序设置网络, 内存等等. 这些对于运行内核是有必要的. 为了达到特殊的目标, 引导程序可以根据配置参数或者输入数据设置内核.

传统得加载器主要是2个文件:
/external/arm-trusted-firmware/lib/romlib/init.s

这个主要是初始化堆栈, 清零BSS段, 调用main.c的_main()函数
/external/rootdev/main.c
初始化硬件(闹钟,主板,键盘, 控制台等), 创建Linux标签

内核

Android内核与桌面Linux内核的启动方式差不多, 内核启动时, 设置缓存 被保护的存储器 计划列表 加载驱动. 当内核完成系统设置时, 它首先在系统文件中寻找"init"文件, 然后启动root进程或者系统的第一个进程(据我之前的了解这个进程叫idle进程, pid=0, 如有记错的话请大家指出)

init进程

init进程是Linux系统中用户空间的第一个进程, 进程号固定为1. Kernel启动后, 在用户空间启动init进程, 并调用init中的main()方法执行init进程的职责

启动Launcher App

init进程分析
init进程是Android系统中及其重要的用户空间的第一个进程. 接下来我们看看init进程做了些什么事情.
1.创建和挂载启动所需要的目录文件
2.初始化和启动属性服务
3.解析init.rc配置文件并启动Zygote进程


image.png

比较重要的两个文件
/system/core/init/init.cpp
/system/core/rootdir/init.rc
在这里init.cpp里面干了啥我们就不去详细解析了, 有兴趣得同学自己去研究

init.rc解析
init.rc是什么? 它是一个非常重要的配置文件, 由android初始化语言(Android Init Language)编写的脚本, 它里面包含了Action, Service, Command, Options. 这里就不过多讲解, 有兴趣了解的同学自己google

Zygote

1.启动图解


0d8b2f4795e0002c34e1e991d977da3.png 1e7101e2e612fa284766d5fefe330c3.png
  1. Zygote概述
    Zygote的翻译为"受精卵", 如其名, 它的主要作用是用来孵化进程的, 在Android系统中主要有以下两种程序
    Java应用程序---主要基于ART虚拟机, 所有的应用程序APK都是属于这一类程序
    Native程序---也就是利用c/cpp开发的程序, 例如bootanimation.
    所有的Java程序都以及系统服务进程SystemServer 都是由Zygote孵化而来的, 而native程序是由init程序创建启动的.

Binder 机制中存在 Binder 线程池, 是多线程的, 如果 Zygote 采用 Binder 的话就存在上面说的 fork() 与 多线程的问题了。 其实严格来说, Binder 机制不一定要多线程, 所谓的 Binder 线程只不过是在循环读 取 Binder 驱动的消息而已, 只注册一个 Binder 线程也是可以工作的, 比如 service manager 就是这样的。 实际 上 Zygote 尽管没有采取 Binder 机制, 它也不是单线程的, 但它在 fork() 前主动停止了其他线程, fork() 后重 新启动了。

3.Zygote触发过程.
之前介绍了Zygote,那么Zygote是怎么被唤起来的?
在init.rc中, 上面有这一行代码:
import /system/etc/init/hw/init.{ro.zygote}.rc{ro.zygote}这个会被替换成ro.zygote对应的属性值, 这个是由不同厂商自己定制的, 有4个值:
zygote32: zygote进程对应的执行程序是app_process(纯32bit模式)
zygote64:zygote进程对应的执行程序是app_process64(纯64bit模式)
zygote32_64: 启动两个zygote进程(名为zygote和zygote_secondary), 对应的执行程序是app_process32(主模式), app_process64
zygote64_32: 启动两个zygote进程(名为zygote和zygote_secondary), 对应的执行程序是app_process64(主模式), app_process32

Start zygote
拿32位为例,文件位置/system/core/rootdir/init.zygote32.rc

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class 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 write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    onrestart restart wificond
    writepid /dev/cpuset/foreground/tasks

app_processXXX对应的位置为:out/target/product/xxx/system/bin
源位置app_process 中有一个比较重要的文件:::::/frameworks/base/cmds/app_process/app_main.cpp

app_main.cpp的main()方法:

int main(int argc, char* const argv[])
{
   
     .......

    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));

    .......

    //这里, 就是由native的世界进入java世界的地方, 在此之前都是native和kernel的世界
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }
}

先看下runtime.start方法调用,文件位置/frameworks/base/core/jni/AndroidRuntime.cpp:

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
   
    .......

    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    //启动虚拟机
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.
     */
    //注册JNI函数
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
    //以上我们可以看到, 这里ART先给我们干了两件事 启动java虚拟机, 然后注册JNI
    .......

    //下面是通过反射去调用某个类的main方法, 哪个类? 之前在app_main里面那一行 runtime.start 传进来的参数是ZygoteInit, 就是调的它.. 从这里.我们真正的进入了Java的世界
    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    char* slashClassName = toSlashClassName(className != NULL ? className : "");
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);

#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif
        }
    }
}

看下/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
的main()方法:

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 {

        ......

        boolean startSystemServer = false;
        String zygoteSocketName = "zygote";
        String abiList = null;
        boolean enableLazyPreload = false;
        //遍历参数
        for (int i = 1; i < argv.length; i++) {
            if ("start-system-server".equals(argv[i])) {
                startSystemServer = true;
            } else if ("--enable-lazy-preload".equals(argv[i])) {
                enableLazyPreload = true;
            } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                abiList = argv[i].substring(ABI_LIST_ARG.length());
            } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
            } else {
                throw new RuntimeException("Unknown command line argument: " + argv[i]);
            }
        }

        ......

        // In some configurations, we avoid preloading resources and classes eagerly.
            // In such cases, we will preload things prior to our first fork.
            if (!enableLazyPreload) {
                bootTimingsTraceLog.traceBegin("ZygotePreload");
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                        SystemClock.uptimeMillis());
                //预加载classes和resources等
                preload(bootTimingsTraceLog);
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                        SystemClock.uptimeMillis());
                bootTimingsTraceLog.traceEnd(); // ZygotePreload
            } else {
                Zygote.resetNicePriority();
            }

        ......

        Zygote.initNativeState(isPrimaryZygote);

        ZygoteHooks.stopZygoteNoThreadCreation();

        //创建ZygoteServer,就是zygote socket的server端,用于接收AMS的请求,调用zygote来fork进程的,后面有说明
        zygoteServer = new ZygoteServer(isPrimaryZygote);

        if (startSystemServer) {
            //调用forkSystemServer方法
            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");

        //zygote socket server进入轮训等待请求
        // The select loop returns early in the child process after a fork and
        // loops forever in the zygote.
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        throw ex;
    } finally {
        if (zygoteServer != null) {
            zygoteServer.closeServerSocket();
        }
    }

    // We're in the child process and have exited the select loop. Proceed to execute the
    // command.
    if (caller != null) {
        caller.run();
    }
}

看下预加载类和资源的preload()方法:

static void preload(TimingsTraceLog bootTimingsTraceLog) {
        Log.d(TAG, "begin preload");
        bootTimingsTraceLog.traceBegin("BeginPreload");
        beginPreload();
        bootTimingsTraceLog.traceEnd(); // BeginPreload
        bootTimingsTraceLog.traceBegin("PreloadClasses");
        //预加载类
        preloadClasses();
        bootTimingsTraceLog.traceEnd(); // PreloadClasses
        bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders");
        cacheNonBootClasspathClassLoaders();
        bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders
        bootTimingsTraceLog.traceBegin("PreloadResources");
        //预加载系统资源
        preloadResources();
        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();
        preloadTextResources();
        // Ask the WebViewFactory to do any initialization that must run in the zygote process,
        // for memory sharing purposes.
        WebViewFactory.prepareWebViewInZygote();
        endPreload();
        warmUpJcaProviders();
        Log.d(TAG, "end preload");

        sPreloadComplete = true;
    }

看下/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java的runSelectLoop方法:

Runnable runSelectLoop(String abiList) {
        ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

        //mZygoteSocket是socket通信中的服务端,即zygote进程
        socketFDs.add(mZygoteSocket.getFileDescriptor());
        peers.add(null);

        while (true) {
            
            ......

            while (--pollIndex >= 0) {
                //采用I/O多路复用机制,当客户端发出 连接请求或者数据处理请求时,则执行continue
                if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
                    continue;
                }

                if (pollIndex == 0) {
                    // Zygote server socket
                    //创建客户端连接
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    socketFDs.add(newPeer.getFileDescriptor());

                } else if (pollIndex < usapPoolEventFDIndex) {
                    // Session socket accepted from the Zygote server socket

                    try {
                        //处理客户端数据事务
                        ZygoteConnection connection = peers.get(pollIndex);
                        final Runnable command = connection.processOneCommand(this);

                        // TODO (chriswailes): Is this extra check necessary?
                        if (mIsForkChild) {
                            // We're in the child. We should always have a command to run at this
                            // stage if processOneCommand hasn't called "exec".
                            if (command == null) {
                                throw new IllegalStateException("command == null");
                            }

                            return command;
                        } else {
                            // We're in the server - we should never have any commands to run.
                            if (command != null) {
                                throw new IllegalStateException("command != null");
                            }

                            // We don't know whether the remote side of the socket was closed or
                            // not until we attempt to read from it from processOneCommand. This
                            // shows up as a regular POLLIN event in our regular processing loop.
                            if (connection.isClosedByPeer()) {
                                connection.closeSocket();
                                peers.remove(pollIndex);
                                socketFDs.remove(pollIndex);
                            }
                        }
                    } catch (Exception e) {
                        if (!mIsForkChild) {
                            // We're in the server so any exception here is one that has taken place
                            // pre-fork while processing commands or reading / writing from the
                            // control socket. Make a loud noise about any such exceptions so that
                            // we know exactly what failed and why.

                            Slog.e(TAG, "Exception executing zygote command: ", e);

                            // Make sure the socket is closed so that the other end knows
                            // immediately that something has gone wrong and doesn't time out
                            // waiting for a response.
                            ZygoteConnection conn = peers.remove(pollIndex);
                            conn.closeSocket();

                            socketFDs.remove(pollIndex);
                        } else {
                            // We're in the child so any exception caught here has happened post
                            // fork and before we execute ActivityThread.main (or any other main()
                            // method). Log the details of the exception and bring down the process.
                            Log.e(TAG, "Caught post-fork exception in child process.", e);
                            throw e;
                        }
                    } finally {
                        // Reset the child flag, in the event that the child process is a child-
                        // zygote. The flag will not be consulted this loop pass after the Runnable
                        // is returned.
                        mIsForkChild = false;
                    }
                }

                ......
            }

            ......
        }
    }

Zygote进程创建Java虚拟机,并注册JNI方法, 真正成为Java进程的母体,用于孵化Java进程. 在创建完system_server进程后,zygote功成身退,调用runSelectLoop(),随时待命,当接收到请求创建新进程请求时立即唤醒并执行相应工作。

回过头来,再接着看ZygoteInit.java的forkSystemServer方法:

private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
        long capabilities = posixCapabilitiesAsBits(
                OsConstants.CAP_IPC_LOCK,
                OsConstants.CAP_KILL,
                OsConstants.CAP_NET_ADMIN,
                OsConstants.CAP_NET_BIND_SERVICE,
                OsConstants.CAP_NET_BROADCAST,
                OsConstants.CAP_NET_RAW,
                OsConstants.CAP_SYS_MODULE,
                OsConstants.CAP_SYS_NICE,
                OsConstants.CAP_SYS_PTRACE,
                OsConstants.CAP_SYS_TIME,
                OsConstants.CAP_SYS_TTY_CONFIG,
                OsConstants.CAP_WAKE_ALARM,
                OsConstants.CAP_BLOCK_SUSPEND
        );
        /* Containers run without some capabilities, so drop any caps that are not available. */
        StructCapUserHeader header = new StructCapUserHeader(
                OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
        StructCapUserData[] data;
        try {
            data = Os.capget(header);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to capget()", ex);
        }
        capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);

        /* Hardcoded command line to start the system server */
        String args[] = {
                "--setuid=1000",
                "--setgid=1000",
                "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
                        + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
                "--capabilities=" + capabilities + "," + capabilities,
                "--nice-name=system_server",
                "--runtime-args",
                "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
                "com.android.server.SystemServer",
        };
        ZygoteArguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteArguments(args);
            Zygote.applyDebuggerSystemProperty(parsedArgs);
            Zygote.applyInvokeWithSystemProperty(parsedArgs);

            boolean profileSystemServer = SystemProperties.getBoolean(
                    "dalvik.vm.profilesystemserver", false);
            if (profileSystemServer) {
                parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
            }

            //fork出来SystemServer进程,返回进程pid
            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.mUid, parsedArgs.mGid,
                    parsedArgs.mGids,
                    parsedArgs.mRuntimeFlags,
                    null,
                    parsedArgs.mPermittedCapabilities,
                    parsedArgs.mEffectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            zygoteServer.closeServerSocket();
            //调用handleSystemServerProcess方法
            return handleSystemServerProcess(parsedArgs);
        }

        return null;
    }

看下handleSystemServerProcess方法:

private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
    // set umask to 0077 so new files and directories will default to owner-only permissions.
    Os.umask(S_IRWXG | S_IRWXO);

    if (parsedArgs.mNiceName != null) {
        //设置当前进程名为"system_server"
        Process.setArgV0(parsedArgs.mNiceName);
    }

    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    if (systemServerClasspath != null) {
        //执行dex优化操作,比如services.jar
        if (performSystemServerDexOpt(systemServerClasspath)) {
            // Throw away the cached classloader. If we compiled here, the classloader would
            // not have had AoT-ed artifacts.
            // Note: This only works in a very special environment where selinux enforcement is
            // disabled, e.g., Mac builds.
            sCachedSystemServerClassLoader = null;
        }
        // Capturing profiles is only supported for debug or eng builds since selinux normally
        // prevents it.
        boolean profileSystemServer = SystemProperties.getBoolean(
                "dalvik.vm.profilesystemserver", false);
        if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
            try {
                prepareSystemServerProfile(systemServerClasspath);
            } catch (Exception e) {
                Log.wtf(TAG, "Failed to set up system server profile", e);
            }
        }
    }

    if (parsedArgs.mInvokeWith != null) {
        String[] args = parsedArgs.mRemainingArgs;
        // If we have a non-null system server class path, we'll have to duplicate the
        // existing arguments and append the classpath to it. ART will handle the classpath
        // correctly when we exec a new process.
        if (systemServerClasspath != null) {
            String[] amendedArgs = new String[args.length + 2];
            amendedArgs[0] = "-cp";
            amendedArgs[1] = systemServerClasspath;
            System.arraycopy(args, 0, amendedArgs, 2, args.length);
            args = amendedArgs;
        }

        WrapperInit.execApplication(parsedArgs.mInvokeWith,
                parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                VMRuntime.getCurrentInstructionSet(), null, args);

        throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
    } else {
        //system_server进程创建PathClassLoader类加载器,见下面的方法
        createSystemServerClassLoader();
        ClassLoader cl = sCachedSystemServerClassLoader;
        if (cl != null) {
            Thread.currentThread().setContextClassLoader(cl);
        }

       //调用ZygoteInit.java的zygoteInit方法
        /*
         * Pass the remaining arguments to SystemServer.
         */
        return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                parsedArgs.mRemainingArgs, cl);
    }

    /* should never reach here */
}

//调用createSystemServerClassLoader方法:
private static void createSystemServerClassLoader() {
        if (sCachedSystemServerClassLoader != null) {
            return;
        }
        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        // TODO: Should we run optimization here?
        if (systemServerClasspath != null) {
            //创建PathClassLoader
            sCachedSystemServerClassLoader = createPathClassLoader(systemServerClasspath,
                    VMRuntime.SDK_VERSION_CUR_DEVELOPMENT);
        }
    }

接着调用ZygoteInit.java的zygoteInit方法

public static final Runnable zygoteInit(int targetSdkVersion, 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();
        //调用RuntimeInit.applicationInit
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

调用/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java的applicationInit方法:

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
        // If the application calls System.exit(), terminate the process
        // immediately without running any shutdown hooks.  It is not possible to
        // shutdown an Android application gracefully.  Among other things, the
        // Android runtime shutdown hooks close the Binder driver, which can cause
        // leftover running threads to crash before the process actually exits.
        nativeSetExitWithoutCleanup(true);

        // We want to be fairly aggressive about heap utilization, to avoid
        // holding on to a lot of memory that isn't needed.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

        final Arguments args = new Arguments(argv);

        // The end of of the RuntimeInit event (see #zygoteInit).
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        //这里,调用findStaticMain方法
        // Remaining arguments are passed to the start class's static main
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }


protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
        Class<?> cl;

        try {
            //此处的className等于SystemServer
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }

        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
        //这里,调用MethodAndArgsCaller,是个Runnable
        return new MethodAndArgsCaller(m, argv);
    }

看下MethodAndArgsCaller:

static class MethodAndArgsCaller implements Runnable {
    /** method to call */
    private final Method mMethod;

    /** argument array */
    private final String[] mArgs;

    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }

    public void run() {
        try {
            //反射调用SystemServer.main()
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        } catch (InvocationTargetException ex) {
            Throwable cause = ex.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else if (cause instanceof Error) {
                throw (Error) cause;
            }
            throw new RuntimeException(ex);
        }
    }
}

最终调用到/frameworks/base/services/java/com/android/server/SystemServer.java的main()方法:

public static void main(String[] args) {
        new SystemServer().run();
    }

private void run() {

    try {

    ......

        // 准备主线程looper
    Looper.prepareMainLooper();
        Looper.getMainLooper().setSlowLogThresholdMs(
                SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

        //加载android_servers.so库,该库包含的源码在frameworks/base/services/目录下
        // Initialize native services.
        System.loadLibrary("android_servers");

        // Debug builds - allow heap profiling.
        if (Build.IS_DEBUGGABLE) {
            initZygoteChildHeapProfiling();
        }

        //检测上次关机过程是否失败,该方法可能不会返回
        // Check whether we failed to shut down last time we tried.
        // This call may not return.
        performPendingShutdown();

        //初始化系统上下文
        // Initialize the system context.
        createSystemContext();

        // Create the system service manager.
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setStartInfo(mRuntimeRestart,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        // Prepare the thread pool for init tasks that can be parallelized
        SystemServerInitThreadPool.get();
    } finally {
        traceEnd();  // InitBeforeStartServices
    }
    
     // Start services.
    try {
        traceBeginAndSlog("StartServices");
        // 启动引导服务
        startBootstrapServices();
        // 启动核心服务
        startCoreServices();
        / 启动其他服务
        startOtherServices();
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        traceEnd();
    }

    ......

    //一直循环执行
    // Loop forever.
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

看下SystemServer中启动服务的方法:

public final class SystemServer {

    /**
     * 启动AMS,PMS等服务
     */
    private void startBootstrapServices() {
        ......

        ActivityTaskManagerService atm = mSystemServiceManager.startService(
                ActivityTaskManagerService.Lifecycle.class).getService();
        mActivityManagerService = ActivityManagerService.Lifecycle.startService(
                mSystemServiceManager, atm);
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);

        ......


        try {
            Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
            mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        } finally {
            Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
        }

        ......

    }

    private void startCoreServices() {
        // Tracks application usage stats.
        traceBeginAndSlog("StartUsageService");
        mSystemServiceManager.startService(UsageStatsService.class);
        mActivityManagerService.setUsageStatsManager(
                LocalServices.getService(UsageStatsManagerInternal.class));
        traceEnd();

        ......
    }

    private void startOtherServices() {
        
        ......

        // We now tell the activity manager it is okay to run third party
        // code.  It will call back into us once it has gotten to the state
        // where third party code can really run (but before it has actually
        // started launching the initial applications), for us to complete our
        // initialization.
        //调用ActivityManagerService的systemReady()方法
        mActivityManagerService.systemReady(() -> {
            Slog.i(TAG, "Making services ready");
            traceBeginAndSlog("StartActivityManagerReadyPhase");
            mSystemServiceManager.startBootPhase(
                    SystemService.PHASE_ACTIVITY_MANAGER_READY);
            traceEnd();
            traceBeginAndSlog("StartObservingNativeCrashes");
            try {
                mActivityManagerService.startObservingNativeCrashes();
            } catch (Throwable e) {
                reportWtf("observing native crashes", e);
            }
            traceEnd();

        ......
    }
   
} 

看下/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java的systemReady()方法:

/**
* AMS启动Home后续再展开说明
*/
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
        traceLog.traceBegin("PhaseActivityManagerReady");
        synchronized(this) {
            if (mSystemReady) {
                // If we're done calling all the receivers, run the next "boot phase" passed in
                // by the SystemServer
                if (goingCallback != null) {
                    goingCallback.run();
                }
                return;
            }

            mLocalDeviceIdleController
                    = LocalServices.getService(DeviceIdleController.LocalService.class);
            mActivityTaskManager.onSystemReady();
            // Make sure we have the current profile info, since it is needed for security checks.
            mUserController.onSystemReady();
            mAppOpsService.systemReady();
            mSystemReady = true;
        }
        
        ......
}

总结:Zygote进程在fork创建SystemServer进程后返回到SystemServer进程继续进行相关System进程启动工作,至此Zygote进程启动完毕,Zygote进程在初始化时就会创建Android虚拟机、注册JNI函数、预加载系统资源文件和Java 类。所有应用进程都共享和继承这些资源,Zygote进程启动工作完毕后,也会变成守护进程,负责处理启动App 应用程序的请求。

————————————————
参考:
https://www.jianshu.com/p/3e033aeb44f8
https://blog.csdn.net/izard999/article/details/128703776

相关文章

网友评论

      本文标题:Android 系统启动过程-Zygote启动

      本文链接:https://www.haomeiwen.com/subject/wlqtldtx.html