美文网首页
android, zygote, systemservice启动

android, zygote, systemservice启动

作者: MickCaptain | 来源:发表于2019-08-04 19:37 被阅读0次
    • 1. 开机上电
    • 2. cpu bootloader 读取启动项(u盘启动,sd卡启动),然后启动uboot
    • 3. uboot 初始化外设,引导内核启动,通过串口设置启动参数
    • 4. kernal 读取硬件设置, 驱动加载, 根据uboot 配置参数启动系统
    • ** 5. 启动android系统**
      (1). 挂载分区
      (2). 动态加载驱动
      (3). 启动相关系统服务
      (4). 配置环境变量
      (5). 守护系统

    android 启动脚本

    uboot -> recovery检查 -> 1. recovery 模式进行安装包的安装
    2. 正常启动模式


    系统启动后的第一个进程init
    1.创建目录,挂载分区

    int main(int argc, char** argv) {
        if (!strcmp(basename(argv[0]), "ueventd")) {
            return ueventd_main(argc, argv);
        }
    
        if (!strcmp(basename(argv[0]), "watchdogd")) {
            return watchdogd_main(argc, argv);
        }
    
        if (REBOOT_BOOTLOADER_ON_PANIC) {
            InstallRebootSignalHandlers();
        }
    
        add_environment("PATH", _PATH_DEFPATH);
    
        bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);
    
        if (is_first_stage) {
            boot_clock::time_point start_time = boot_clock::now();
    
            // Clear the umask.
            umask(0);
        // 创建目录挂载分区
            // Get the basic filesystem setup we need put together in the initramdisk
            // on / and then we'll let the rc file figure out the rest.
            mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
            mkdir("/dev/pts", 0755);
            mkdir("/dev/socket", 0755);
            mount("devpts", "/dev/pts", "devpts", 0, NULL);
            #define MAKE_STR(x) __STRING(x)
            mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
            // Don't expose the raw commandline to unprivileged processes.
            chmod("/proc/cmdline", 0440);
            gid_t groups[] = { AID_READPROC };
            setgroups(arraysize(groups), groups);
            mount("sysfs", "/sys", "sysfs", 0, NULL);
            mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
            mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
            mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
            mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
    
            // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
            // talk to the outside world...
            // 初始化并重定向klog
            InitKernelLogging(argv);
    
            LOG(INFO) << "init first stage started!";
    
            if (!DoFirstStageMount()) {
                LOG(ERROR) << "Failed to mount required partitions early ...";
                panic();
            }
    
            SetInitAvbVersionInRecovery();
    
            // Set up SELinux, loading the SELinux policy.
            selinux_initialize(true);
    
            // We're in the kernel domain, so re-exec init to transition to the init domain now
            // that the SELinux policy has been loaded.
            if (selinux_android_restorecon("/init", 0) == -1) {
                PLOG(ERROR) << "restorecon failed";
                security_failure();
            }
    
            setenv("INIT_SECOND_STAGE", "true", 1);
    
            static constexpr uint32_t kNanosecondsPerMillisecond = 1e6;
            uint64_t start_ms = start_time.time_since_epoch().count() / kNanosecondsPerMillisecond;
            setenv("INIT_STARTED_AT", std::to_string(start_ms).c_str(), 1);
    
            char* path = argv[0];
            char* args[] = { path, nullptr };
            execv(path, args);
    
            // execv() only returns if an error happened, in which case we
            // panic and never fall through this conditional.
            PLOG(ERROR) << "execv(\"" << path << "\") failed";
            security_failure();
        }
    
        // At this point we're in the second stage of init.
        InitKernelLogging(argv);
        LOG(INFO) << "init second stage started!";
    
        // Set up a session keyring that all processes will have access to. It
        // will hold things like FBE encryption keys. No process should override
        // its session keyring.
        keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1);
    
        // Indicate that booting is in progress to background fw loaders, etc.
        close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
        
    // 初始化环境变量  
        property_init();
    
        // If arguments are passed both on the command line and in DT,
        // properties set in DT always have priority over the command-line ones.
        process_kernel_dt();
        // 解析内核启动参数
        process_kernel_cmdline();
    
        // Propagate the kernel variables to internal variables
        // used by init as well as the current required properties.
        export_kernel_boot_props();
    
        // Make the time that init started available for bootstat to log.
        property_set("ro.boottime.init", getenv("INIT_STARTED_AT"));
        property_set("ro.boottime.init.selinux", getenv("INIT_SELINUX_TOOK"));
    
        // Set libavb version for Framework-only OTA match in Treble build.
        const char* avb_version = getenv("INIT_AVB_VERSION");
        if (avb_version) property_set("ro.boot.avb_version", avb_version);
    
        // Clean up our environment.
        unsetenv("INIT_SECOND_STAGE");
        unsetenv("INIT_STARTED_AT");
        unsetenv("INIT_SELINUX_TOOK");
        unsetenv("INIT_AVB_VERSION");
    
        // Now set up SELinux for second stage.
        selinux_initialize(false);
        selinux_restore_context();
    
        epoll_fd = epoll_create1(EPOLL_CLOEXEC);
        if (epoll_fd == -1) {
            PLOG(ERROR) << "epoll_create1 failed";
            exit(1);
        }
    
        signal_handler_init();
    // 加载默认环境变量
        property_load_boot_defaults();
        export_oem_lock_status();
        start_property_service();
        set_usb_controller();
    
        const BuiltinFunctionMap function_map;
        Action::set_function_map(&function_map);
    
        ActionManager& am = ActionManager::GetInstance();
        ServiceManager& sm = ServiceManager::GetInstance();
        Parser& parser = Parser::GetInstance();
    
        parser.AddSectionParser("service", std::make_unique<ServiceParser>(&sm));
        parser.AddSectionParser("on", std::make_unique<ActionParser>(&am));
        parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
        std::string bootscript = GetProperty("ro.boot.init_rc", "");
        if (bootscript.empty()) {
            parser.ParseConfig("/init.rc");
            parser.set_is_system_etc_init_loaded(
                    parser.ParseConfig("/system/etc/init"));
            parser.set_is_vendor_etc_init_loaded(
                    parser.ParseConfig("/vendor/etc/init"));
            parser.set_is_odm_etc_init_loaded(parser.ParseConfig("/odm/etc/init"));
        } else {
            parser.ParseConfig(bootscript);
            parser.set_is_system_etc_init_loaded(true);
            parser.set_is_vendor_etc_init_loaded(true);
            parser.set_is_odm_etc_init_loaded(true);
        }
    
        // Turning this on and letting the INFO logging be discarded adds 0.2s to
        // Nexus 9 boot time, so it's disabled by default.
        if (false) DumpState();
    
        am.QueueEventTrigger("early-init");
    
        // Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...
        am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
        // ... so that we can start queuing up actions that require stuff from /dev.
        am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
        am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits");
        am.QueueBuiltinAction(set_kptr_restrict_action, "set_kptr_restrict");
        am.QueueBuiltinAction(keychord_init_action, "keychord_init");
        am.QueueBuiltinAction(console_init_action, "console_init");
    
        // Trigger all the boot actions to get us started.
        am.QueueEventTrigger("init");
    
        // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
        // wasn't ready immediately after wait_for_coldboot_done
        am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
    
        // Don't mount filesystems or start core system services in charger mode.
        std::string bootmode = GetProperty("ro.bootmode", "");
        if (bootmode == "charger") {
            am.QueueEventTrigger("charger");
        } else {
            am.QueueEventTrigger("late-init");
        }
    
        // Run all property triggers based on current state of the properties.
        am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");
    
        while (true) {
            // By default, sleep until something happens.
            int epoll_timeout_ms = -1;
    
            if (do_shutdown && !shutting_down) {
                do_shutdown = false;
                if (HandlePowerctlMessage(shutdown_command)) {
                    shutting_down = true;
                }
            }
    
            if (!(waiting_for_prop || sm.IsWaitingForExec())) {
                am.ExecuteOneCommand();
            }
            if (!(waiting_for_prop || sm.IsWaitingForExec())) {
                if (!shutting_down) restart_processes();
    
                // If there's a process that needs restarting, wake up in time for that.
                if (process_needs_restart_at != 0) {
                    epoll_timeout_ms = (process_needs_restart_at - time(nullptr)) * 1000;
                    if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
                }
    
                // If there's more work to do, wake up again immediately.
                if (am.HasMoreCommands()) epoll_timeout_ms = 0;
            }
    
            epoll_event ev;
            int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, epoll_timeout_ms));
            if (nr == -1) {
                PLOG(ERROR) << "epoll_wait failed";
            } else if (nr == 1) {
                ((void (*)()) ev.data.ptr)();
            }
        }
    
        return 0;
    }
    

    start_property_service作用创建所有的服务

    • NETD 网络管理服务
    • servicemanager client和service通信管理服务
    • surfaceflingge 显示管理服务
    • zygote 创建app应用进程服务
    • media (audio, camera)多媒体服务
    • installed 应用安装服务
    • bootanim 开机动画

    3.守护进程

    zygote启动分析

    (1). 在app_main的main方法中启动zygote进程
    // framework/base/cmds/app_process/app_main.cpp
    runtime.start("com.android.internal.os.ZygoteInit", args, zygote);

    int main(int argc, char* const argv[])
    {
        if (!LOG_NDEBUG) {
          String8 argv_String;
          for (int i = 0; i < argc; ++i) {
            argv_String.append("\"");
            argv_String.append(argv[i]);
            argv_String.append("\" ");
          }
          ALOGV("app_process main with argv: %s", argv_String.string());
        }
    
        AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
        // Process command line arguments
        // ignore argv[0]
        argc--;
        argv++;
    
        // Everything up to '--' or first non '-' arg goes to the vm.
        //
        // The first argument after the VM args is the "parent dir", which
        // is currently unused.
        //
        // After the parent dir, we expect one or more the following internal
        // arguments :
        //
        // --zygote : Start in zygote mode
        // --start-system-server : Start the system server.
        // --application : Start in application (stand alone, non zygote) mode.
        // --nice-name : The nice name for this process.
        //
        // For non zygote starts, these arguments will be followed by
        // the main class name. All remaining arguments are passed to
        // the main method of this class.
        //
        // For zygote starts, all remaining arguments are passed to the zygote.
        // main function.
        //
        // Note that we must copy argument string values since we will rewrite the
        // entire argument block when we apply the nice name to argv0.
        //
        // As an exception to the above rule, anything in "spaced commands"
        // goes to the vm even though it has a space in it.
        const char* spaced_commands[] = { "-cp", "-classpath" };
        // Allow "spaced commands" to be succeeded by exactly 1 argument (regardless of -s).
        bool known_command = false;
    
        int i;
        for (i = 0; i < argc; i++) {
            if (known_command == true) {
              runtime.addOption(strdup(argv[i]));
              // The static analyzer gets upset that we don't ever free the above
              // string. Since the allocation is from main, leaking it doesn't seem
              // problematic. NOLINTNEXTLINE
              ALOGV("app_process main add known option '%s'", argv[i]);
              known_command = false;
              continue;
            }
    
            for (int j = 0;
                 j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));
                 ++j) {
              if (strcmp(argv[i], spaced_commands[j]) == 0) {
                known_command = true;
                ALOGV("app_process main found known command '%s'", argv[i]);
              }
            }
    
            if (argv[i][0] != '-') {
                break;
            }
            if (argv[i][1] == '-' && argv[i][2] == 0) {
                ++i; // Skip --.
                break;
            }
    
            runtime.addOption(strdup(argv[i]));
            // The static analyzer gets upset that we don't ever free the above
            // string. Since the allocation is from main, leaking it doesn't seem
            // problematic. NOLINTNEXTLINE
            ALOGV("app_process main add option '%s'", argv[i]);
        }
    
        // Parse runtime arguments.  Stop at first unrecognized option.
        bool zygote = false;
        bool startSystemServer = false;
        bool application = false;
        String8 niceName;
        String8 className;
    
        ++i;  // Skip unused "parent dir" argument.
        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;
            }
        }
    
        Vector<String8> args;
        if (!className.isEmpty()) {
            // We're not in zygote mode, the only argument we need to pass
            // to RuntimeInit is the application argument.
            //
            // The Remainder of args get passed to startup class main(). Make
            // copies of them before we overwrite them with the process name.
            args.add(application ? String8("application") : String8("tool"));
            runtime.setClassNameAndArgs(className, argc - i, argv + i);
    
            if (!LOG_NDEBUG) {
              String8 restOfArgs;
              char* const* argv_new = argv + i;
              int argc_new = argc - i;
              for (int k = 0; k < argc_new; ++k) {
                restOfArgs.append("\"");
                restOfArgs.append(argv_new[k]);
                restOfArgs.append("\" ");
              }
              ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
            }
        } else {
            // We're in zygote mode.
            maybeCreateDalvikCache();
    
            if (startSystemServer) {
                args.add(String8("start-system-server"));
            }
    
            char prop[PROP_VALUE_MAX];
            if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
                LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
                    ABI_LIST_PROPERTY);
                return 11;
            }
    
            String8 abiFlag("--abi-list=");
            abiFlag.append(prop);
            args.add(abiFlag);
    
            // In zygote mode, pass all remaining arguments to the zygote
            // main() method.
            for (; i < argc; ++i) {
                args.add(String8(argv[i]));
            }
        }
    
        if (!niceName.isEmpty()) {
            runtime.setArgv0(niceName.string(), true /* setProcName */);
        }
    
    // 启动dalvik虚拟机,和jni环境变量
        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.");
        }
    
    

    (2). dalvik虚拟机实例和jni环境变量,jni调用zggote main方法
    // framework/base/core/jni/AndroidRuntime.cpp

    *
     * Start the Android runtime.  This involves starting the virtual machine
     * and calling the "static void main(String[] args)" method in the class
     * named by "className".
     *
     * Passes the main function two arguments, the class name and the specified
     * options string.
     */
    void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
    {
        ALOGD(">>>>>> START %s uid %d <<<<<<\n",
                className != NULL ? className : "(unknown)", getuid());
    
        static const String8 startSystemServer("start-system-server");
    
        /*
         * 'startSystemServer == true' means runtime is obsolete and not run from
         * init.rc anymore, so we print out the boot start event here.
         */
        for (size_t i = 0; i < options.size(); ++i) {
            if (options[i] == startSystemServer) {
               /* track our progress through the boot sequence */
               const int LOG_BOOT_PROGRESS_START = 3000;
               LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
            }
        }
    
        const char* rootDir = getenv("ANDROID_ROOT");
        if (rootDir == NULL) {
            rootDir = "/system";
            if (!hasDir("/system")) {
                LOG_FATAL("No root directory specified, and /android does not exist.");
                return;
            }
            setenv("ANDROID_ROOT", rootDir, 1);
        }
    
        //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
        //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
    
        /* start the virtual machine */
        JniInvocation jni_invocation;
        jni_invocation.Init(NULL);
        JNIEnv* env;
        // 启动dalvik虚拟机
        if (startVm(&mJavaVM, &env, zygote) != 0) {
            return;
        }
        onVmCreated(env);
    
        /*
         * Register android functions.
         */
         // 注册android  jni函数
        if (startReg(env) < 0) {
            ALOGE("Unable to register all android natives\n");
            return;
        }
    
        /*
         * We want to call main() with a String array with arguments in it.
         * At present we have two arguments, the class name and an option string.
         * Create an array to hold them.
         */
        jclass stringClass;
        jobjectArray strArray;
        jstring classNameStr;
    
        stringClass = env->FindClass("java/lang/String");
        assert(stringClass != NULL);
        strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
        assert(strArray != NULL);
        classNameStr = env->NewStringUTF(className);
        assert(classNameStr != NULL);
        env->SetObjectArrayElement(strArray, 0, classNameStr);
    
        for (size_t i = 0; i < options.size(); ++i) {
            jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
            assert(optionsStr != NULL);
            env->SetObjectArrayElement(strArray, i + 1, optionsStr);
        }
    
        /*
         * 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 {
        // 调用zygote 的main方法
            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
            }
        }
        free(slashClassName);
    
        ALOGD("Shutting down VM\n");
        if (mJavaVM->DetachCurrentThread() != JNI_OK)
            ALOGW("Warning: unable to detach main thread\n");
        if (mJavaVM->DestroyJavaVM() != 0)
            ALOGW("Warning: VM did not shut down cleanly\n");
    }
    
    

    zygote 创建socket ,预加载,接收进程消息创建进程,启动服务

    位置// framework/base/core/com/android/internal/zygoteInit.java
    在app_main的main方法中最终调用了zygoteInit.java中的main方法
    // 创建socket
    zygoteServer.registerServerSocket(socketName);
    // 预加载
    preload(bootTimingsTraceLog);
    // 接受进程发来的消息创建相关应用
    caller = zygoteServer.runSelectLoop(abiList);
    // 启动系统服务

    
    public static void main(String argv[]) {
            ZygoteServer zygoteServer = new ZygoteServer();
    
            // 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);
            }
    
            final Runnable caller;
            try {
                // Report Zygote start time to tron unless it is a runtime restart
                if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
                    MetricsLogger.histogram(null, "boot_zygote_init",
                            (int) SystemClock.elapsedRealtime());
                }
    
                String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
                TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
                        Trace.TRACE_TAG_DALVIK);
                bootTimingsTraceLog.traceBegin("ZygoteInit");
                RuntimeInit.enableDdms();
    
                boolean startSystemServer = false;
                String socketName = "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)) {
                        socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                    } else {
                        throw new RuntimeException("Unknown command line argument: " + argv[i]);
                    }
                }
    
                if (abiList == null) {
                    throw new RuntimeException("No ABI list supplied.");
                }
        // 注册一个socket,用于消息传递
                zygoteServer.registerServerSocket(socketName);
                // 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());
                       // 预加载 
                    preload(bootTimingsTraceLog);
                    EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                        SystemClock.uptimeMillis());
                    bootTimingsTraceLog.traceEnd(); // ZygotePreload
                } else {
                    Zygote.resetNicePriority();
                }
    
                // Do an initial gc to clean up after startup
                bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
                gcAndFinalize();
                bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
    
                bootTimingsTraceLog.traceEnd(); // ZygoteInit
                // Disable tracing so that forked processes do not inherit stale tracing tags from
                // Zygote.
                Trace.setTracingEnabled(false, 0);
    
                // Zygote process unmounts root storage spaces.
                Zygote.nativeUnmountStorageOnInit();
    
                // Set seccomp policy
                Seccomp.setPolicy();
    
                ZygoteHooks.stopZygoteNoThreadCreation();
    
                if (startSystemServer) {
                    Runnable r = forkSystemServer(abiList, socketName, 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.
                // 接受进程发来的消息创建相关应用
                caller = zygoteServer.runSelectLoop(abiList);
            } catch (Throwable ex) {
                Log.e(TAG, "System zygote died with exception", ex);
                throw ex;
            } finally {
                zygoteServer.closeServerSocket();
            }
    
            // We're in the child process and have exited the select loop. Proceed to execute the
            // command.
            if (caller != null) {
                caller.run();
            }
        }
    
    
    

    systemservice的启动过程

    位置// framework/base/core/com/android/internal/zygoteInit.java

    public static void main(String argv[]) {
         // 此处省略若干行
         // 获得systemservier,创建子进程
                if (startSystemServer) {
                    Runnable r = forkSystemServer(abiList, socketName, 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.
                caller = zygoteServer.runSelectLoop(abiList);
            } catch (Throwable ex) {
                Log.e(TAG, "System zygote died with exception", ex);
                throw ex;
            } finally {
                zygoteServer.closeServerSocket();
            }
    
            // We're in the child process and have exited the select loop. Proceed to execute the
            // command.
            // 启动system service
            if (caller != null) {
                caller.run();
            }
        }
        // forkSystemServer 中最终会调用一系列初始化操作
         /**
         * The main function called when started through the zygote process. This
         * could be unified with main(), if the native code in nativeFinishInit()
         * were rationalized with Zygote startup.<p>
         *
         * Current recognized args:
         * <ul>
         *   <li> <code> [--] &lt;start class name&gt;  &lt;args&gt;
         * </ul>
         *
         * @param targetSdkVersion target SDK version
         * @param argv arg strings
         */
        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();
            return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
        }
    
        
    

    相关文章

      网友评论

          本文标题:android, zygote, systemservice启动

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