Android R 启动流程

Linux在BootLoader后,加载完内核后,启动第一个进程init进程,源码路径位于/system/core/init:
关注入口函数main.cpp可以看见,main.cpp主要是根据参数选择某种启动模式,正常我们是走SecondStageMain

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

接着我们查看/system/core/init/init.cpp

int SecondStageMain(int argc, char** argv) {
    InitKernelLogging(argv);
    PropertyInit();
    // Mount extra filesystems required during second stage init
    MountExtraFilesystems();
    // Now set up SELinux for second stage.
    SelinuxSetupKernelLogging();
    SelabelInitialize();
    SelinuxRestoreContext();
    Epoll epoll;
    if (auto result = epoll.Open(); !result.ok()) {
        PLOG(FATAL) << result.error();
    }
    InstallSignalFdHandler(&epoll);
    InstallInitNotifier(&epoll);
    //解析init配置文件
    LoadBootScripts(am, sm);
    while (true) {
        //省略
    }
    return 0;
}

可以看到init主要做了部分初始化操作,比如内核日志,文件创建挂载,se权限,epoll的创建与注册监听,配置文件解析,最后还有个while的死循环用以处理事件
我们重点关注配置解析即可:

static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser = CreateParser(action_manager, service_list);
    std::string bootscript = GetProperty("ro.boot.init_rc", "");
    if (bootscript.empty()) {
        parser.ParseConfig("/system/etc/init/hw/init.rc");
        if (!parser.ParseConfig("/system/etc/init")) {
            late_import_paths.emplace_back("/system/etc/init");
        }
        // late_import is available only in Q and earlier release. As we don't
        // have system_ext in those versions, skip late_import for system_ext.
        parser.ParseConfig("/system_ext/etc/init");
        if (!parser.ParseConfig("/vendor/etc/init")) {
            late_import_paths.emplace_back("/vendor/etc/init");
        }
        if (!parser.ParseConfig("/odm/etc/init")) {
            late_import_paths.emplace_back("/odm/etc/init");
        }
        if (!parser.ParseConfig("/product/etc/init")) {
            late_import_paths.emplace_back("/product/etc/init");
        }
    } else {
        parser.ParseConfig(bootscript);
    }
}

可以看到主要是从system(系统),vendor(硬件商:高通/mtk),odm(设备厂商,小米/联想/华为等)三个目录去获取配置文件,以及/system.etc/init/hw/init.rc
根据 /system/core/rootdir下的make文件,我们可以看出:
/system/core/rootdir 对应着编译后的/system/etc/init目录
主要关注:
system/core/rootdir/init.rc以及 system/core/rootdir/init.zygote64.rc


image.png

image.png

可以看到这两个配置文件分别描述了servicemanager进程以及zygote进程使得其由init进程进行解析并启动。
servicemanager源码位于:frameworks/native/cmds/servicemanager/
该进程作为servicemanager管家,主要在于向binder驱动注册自己,接着陷入循环等待(具体见路径下源码)
zygote源码位于:frameworks/base/cmds/app_process/
从路径名app_process即可看出,zygote才是我们真正意义上与应用相关的进程。
进入对应入口函数查看(app_main.cpp):

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 {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }
}

可以看到main函数中判断传入参数,走了不同的业务逻辑,要启动的是一个system-server,还是一个app,还是说就是一个zygote
最后走AppRuntime的start进行启动。因为之前在init.zygote64.rc内,指定了参数 --zygote --start-system-server,所以此处走第一个if,并且继续将-start-system-server传递进去

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

void AndroidRuntime::start(const char* className, const Vector& options, bool zygote)
{
    static const String8 startSystemServer("start-system-server");
    bool primary_zygote = false;
    for (size_t i = 0; i < options.size(); ++i) {
        if (options[i] == startSystemServer) {
            primary_zygote = true;
        }
    }
    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    //启动jvm虚拟机,传入配置参数,此时还未真正调用新进程的main
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    //虚拟机启动后的回调
    onVmCreated(env);

    //有了jvm环境后,注册JNI方法
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
    
    //className:com.android.internal.os.ZygoteInit
    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);
        }
    }
    
}

可以看到最终启动了一个jvm虚拟机,zygote为true,primary_zygote 也为true。即意味着最终我们要启动一个主zygote,并且将fork出system-server),可以看到,最终我们通过JNI调用了frameworks/base/core/java/com/android/internal/os/ZygoteInit.java的main函数

    public static void main(String argv[]) {
        //可以看到ZygoteInit首先创建了一个ZygoteServer:里面主要是初始化了socket
        zygoteServer = new ZygoteServer(isPrimaryZygote);
        if (startSystemServer) {
            //关键1:fork出system server进程
            Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
            if (r != null) {
                r.run();
                return;
            }
        }
        //关键2: zygote陷入循环,监听处理各种需求
        caller = zygoteServer.runSelectLoop(abiList);
        if (caller != null) {
            caller.run();
        }
    }
    //frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
    ZygoteServer(boolean isPrimaryZygote) {
        mUsapPoolEventFD = Zygote.getUsapPoolEventFD();
        if (isPrimaryZygote) {
            //创建了socket
            mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
            mUsapPoolSocket =
                    Zygote.createManagedSocketFromInitSocket(
                            Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
        }
    }

    //frameworks/base/core/java/com/android/internal/os/Zygote.java
    static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {
            int fileDesc;
            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;//"ANDROID_SOCKET_zygote"
            String env = System.getenv(fullSocketName);
            fileDesc = Integer.parseInt(env);
            FileDescriptor fd = new FileDescriptor();
            fd.setInt$(fileDesc);
            return new LocalServerSocket(fd);
    }

我们先看下system server启动相关,即被fork出的system server这个进程后续逻辑frameworks/base/core/java/com/android/internal/os/ZygoteInit.java:

    private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {
        //通过fork创建system server子进程
        pid = Zygote.forkSystemServer(
                parsedArgs.mUid, parsedArgs.mGid,
                parsedArgs.mGids,
                parsedArgs.mRuntimeFlags,
                null,
                parsedArgs.mPermittedCapabilities,
                parsedArgs.mEffectiveCapabilities);
        if (pid == 0) {
            //system server子进程启动各种system server
            return handleSystemServerProcess(parsedArgs);
        }
    }

    private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
        return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                                     parsedArgs.mDisabledCompatChanges,
                                     parsedArgs.mRemainingArgs, cl);
    }

    public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        //通过JNI调用native层初始化com_android_internal_os_ZygoteInit_nativeZygoteInit:
        ZygoteInit.nativeZygoteInit();
        //进行Java层的初始化
        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                                           classLoader);
    }
   //frameworks/base/core/jni/AndroidRuntime.cpp:
    static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
    {
        //gCurRuntime真正实现为一开始创建的AppRuntime : AndroidRuntime
        gCurRuntime->onZygoteInit();
    }
    //frameworks/base/cmds/app_process/app_main.cpp ->AppRuntime:
    virtual void onZygoteInit()
    {
        //可以看到为system server进程初始化了Binder线程池,以用于处理其它程序访问系统服务
        //ProcessState是每个进程唯一的,主要用于管理Binder操作,而IPCThreadState则是每个线程的Binder操作:具体可以查看Binder机制分析
        sp proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }

    //frameworks/base/core/java/com/android/internal/os/RuntimeInit.java:
    protected static Runnable findStaticMain(String className, String[] argv,ClassLoader classLoader) {
        //其实这里就是执行SystemServer.java的main函数
        Class cl;
        cl = Class.forName(className, true, classLoader);
        Method m;
        m = cl.getMethod("main", new Class[] { String[].class });
        int modifiers = m.getModifiers();
        return new MethodAndArgsCaller(m, argv);
    }
    //frameworks/base/services/java/com/android/server/SystemServer.java
    public static void main(String[] args) {
        new SystemServer().run();
    }
    private void run() {
        Looper.prepareMainLooper();
        Looper.getMainLooper().setSlowLogThresholdMs(
                SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
        //启动三大类的系统服务,然后陷入loop循环,利用之前初始化的binder环境,提供通信
        startBootstrapServices(t);
        startCoreServices(t);
        startOtherServices(t);
        // Loop forever.
        Looper.loop();
    }

可以看出整个system server由zygote fork出来之后,最终是作为独立进程启动了各类核心服务,通过Binder提供给其余应用访问

接着我们看下zygote自身的后续逻辑,即陷入循环部分,这一块涉及到普通应用是如何被zygote孵化运行并启动的
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java:

//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
    Runnable runSelectLoop(String abiList) {
        //所有监听描述符集合
        ArrayList socketFDs = new ArrayList<>();
        //所有创建的链接集合
        ArrayList peers = new ArrayList<>();
        //这里添加的就是在创建ZygoteServer时初始化的socket
        socketFDs.add(mZygoteSocket.getFileDescriptor());
        peers.add(null);
        //陷入死循环
        while (true) {
            StructPollfd[] pollFDs;
            pollFDs = new StructPollfd[socketFDs.size()];
            int pollIndex = 0;
            //转换一下数据格式
            for (FileDescriptor socketFD : socketFDs) {
                pollFDs[pollIndex] = new StructPollfd();
                pollFDs[pollIndex].fd = socketFD;
                pollFDs[pollIndex].events = (short) POLLIN;
                ++pollIndex;
            }
            //poll轮询时间
            int pollTimeoutMs;
            //poll监听结果
            int pollReturnValue;
            try {
                //发起一次poll轮询
                pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }

            if (pollReturnValue == 0) {
                //轮询超时前没有事件发生
            } else {
                //有事件发生,需要遍历描述符集合查进行处理
                while (--pollIndex >= 0) {
                    if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
                        continue;
                    }
                    //最开始只有zygote的socket,所以会优先执行这里:与system server建立连接
                    if (pollIndex == 0) {
                        // Zygote server socket
                        ZygoteConnection newPeer = acceptCommandPeer(abiList);
                        peers.add(newPeer);
                        socketFDs.add(newPeer.getFileDescriptor());
                    }else {
                        //这部分是处理已建立联系的通信,system server的AMS启动新进程即在此处:
                        ZygoteConnection connection = peers.get(pollIndex);
                        final Runnable command = connection.processOneCommand(this);
                    }
                }
            }
        }
    }

    //frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
    Runnable processOneCommand(ZygoteServer zygoteServer) {
        String[] args;
        args = Zygote.readArgumentList(mSocketReader);
        int pid;
        FileDescriptor childPipeFd = null;
        FileDescriptor serverPipeFd = null;
        ZygoteArguments parsedArgs = new ZygoteArguments(args);
        //进行fork创建应用进程
        pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
                                       parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                                       parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                                       parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
                                       parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
                                       parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
        if (pid == 0) {
            //此时已是应用进程逻辑
            zygoteServer.setForkChild();
            zygoteServer.closeServerSocket();
            IoUtils.closeQuietly(serverPipeFd);
            serverPipeFd = null;
            //从这里继续启动应用进程的后续逻辑
            return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
        }
    }
    //我们先看fork进程的逻辑:
    //frameworks/base/core/java/com/android/internal/os/Zygote.java
    static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
                                 int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
                                 int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
                                 boolean isTopApp, String[] pkgDataInfoList, String[] whitelistedDataInfoList,
                                 boolean bindMountAppDataDirs, boolean bindMountAppStorageDirs) {
        //创建运行环境
        ZygoteHooks.preFork();
        //调用native层
        int pid = nativeForkAndSpecialize(
                uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,
                pkgDataInfoList, whitelistedDataInfoList, bindMountAppDataDirs,
                bindMountAppStorageDirs);
        ZygoteHooks.postForkCommon();
        return pid;
    }
    //frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
    static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
            JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
            jint runtime_flags, jobjectArray rlimits,
            jint mount_external, jstring se_info, jstring nice_name,
            jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
            jstring instruction_set, jstring app_data_dir, jboolean is_top_app,
            jobjectArray pkg_data_info_list, jobjectArray whitelisted_data_info_list,
            jboolean mount_data_dirs, jboolean mount_storage_dirs) {
        pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true);
        return pid;
    }

    static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
                            const std::vector& fds_to_close,
                            const std::vector& fds_to_ignore,
                            bool is_priority_fork) {
        //可以看到实际,最终在native层通过fork孵化了应用进程
        pid_t pid = fork();
        return pid;
    }
    //接着回到fork出的进程的后续执行逻辑中:frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
    private Runnable handleChildProc(ZygoteArguments parsedArgs,
        closeSocket();
        Zygote.setAppProcessName(parsedArgs, TAG);
        //可以看到最终我们再次走到了zygoteInit
        // 和之前的system server进程启动一样,接下来会在native层准备binder环境,然后反射调用java层的启动类(ActivityThread)的main函数
        return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                                 parsedArgs.mDisabledCompatChanges,
                                 parsedArgs.mRemainingArgs, null /* classLoader */);
    }

简单总结一下,整个启动流程就是:
先从固定位置的固化存储中启动bootloader,然后加载linux内核,由linux内核启动第一个用户进程init。init进程启动后通过解析rc文件,依次启动了servicemanager进程,以及zygote进程。前者作为binder管家,负责所有service的通信寻址工作,后者则负责Android系统的应用孵化工作。
zygote首先是根据init解析rc传入的参数,fork出了system server进程,这里面就运行了所有的系统级服务,比如常见的AMS,PMS等等,注册进了之前的servicemanager中,接着zygote创建socket,与system server建立通信,并且陷入循环阻塞,当AMS启动应用时,就会通过socket通知zygote,zygote就会去fork出新的子进程。

你可能感兴趣的:(Android R 启动流程)