转载:https://i-blog.csdnimg.cn/blog_migrate/875a884c5a4d7545f564107f5283b1f1.png
zygote的启动是通过init.rc,我们看下init.rc中有如下几行:
- service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
- socket zygote stream 666
- #onrestart write /sys/android_power/request_state wake
- #onrestart write /sys/power/state on
- onrestart restart media
- onrestart restart netd
所以 zygote是init进程的子进程。
在Android系统中,所 有的应用程序以及系统服务SystemServer都是由Zygote fork出来的,这或许就是为什么它叫zygote(受精卵)的原因把。
在解析init.rc 的时候会把zygote加到service列表中,并最终调用do_service启动,从上面可以看到zygote启动的实际是app_process程序,我们看下zygote的启动流程:
1、main函数
- if (0 == strcmp("--zygote", arg)) {
- bool startSystemServer = (i < argc) ?
- strcmp(argv[i], "--start-system-server") == 0 : false;
- setArgv0(argv0, "zygote");
- set_process_name("zygote");
- runtime.start("com.android.internal.os.ZygoteInit",
- startSystemServer);
代码路径在: Frameworks/base/cmds/app_process的app_main.cpp中,我们看下main函数中有如下几行:
- if (0 == strcmp("--zygote", arg)) {
- bool startSystemServer = (i < argc) ?
- strcmp(argv[i], "--start-system-server") == 0 : false;
- setArgv0(argv0, "zygote");
- set_process_name("zygote");
- runtime.start("com.android.internal.os.ZygoteInit",
- startSystemServer);
2、runtime.start()
- void AndroidRuntime::start(const char* className, const bool startSystemServer)
- {
- LOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",
- className != NULL ? className : "(unknown)");
- .
- .
- /* start the virtual machine */
- if (startVm(&mJavaVM, &env) != 0)
- goto bail;
- /*
- * Register android functions.
- */
- if (startReg(env) < 0) {
- LOGE("Unable to register all android natives\n");
- goto bail;
- }
- .
- .
- startClass = env->FindClass(slashClassName);
- if (startClass == NULL) {
- LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
- /* keep going */
- } else {
- startMeth = env->GetStaticMethodID(startClass, "main",
- "([Ljava/lang/String;)V");
- if (startMeth == NULL) {
- LOGE("JavaVM unable to find main() in '%s'\n", className);
- /* keep going */
- } else {
- env->CallStaticVoidMethod(startClass, startMeth, strArray);
- }
- }
3、zygoteInit.main
- public static void main(String argv[]) {
- try {
- VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);
- // Start profiling the zygote initialization.
- SamplingProfilerIntegration.start();
- registerZygoteSocket();
- EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
- SystemClock.uptimeMillis());
- preloadClasses();
- //cacheRegisterMaps();
- preloadResources();
- EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
- SystemClock.uptimeMillis());
- // Finish profiling the zygote initialization.
- SamplingProfilerIntegration.writeZygoteSnapshot();
- // Do an initial gc to clean up after startup
- gc();
- // If requested, start system server directly from Zygote
- if (argv.length != 2) {
- throw new RuntimeException(argv[0] + USAGE_STRING);
- }
- if (argv[1].equals("true")) {
- startSystemServer();
- } else if (!argv[1].equals("false")) {
- throw new RuntimeException(argv[0] + USAGE_STRING);
- }
- Log.i(TAG, "Accepting command socket connections");
- if (ZYGOTE_FORK_MODE) {
- runForkMode();
- } else {
- runSelectLoopMode();
- }
- closeServerSocket();
- } catch (MethodAndArgsCaller caller) {
- caller.run();
- } catch (RuntimeException ex) {
- Log.e(TAG, "Zygote died with exception", ex);
- closeServerSocket();
- throw ex;
- }
- }
在这里调用registerZygoteSocket建立了一个socket监听,用来和
ActivityManagerService进行通迅。注意这里利用System.getenv()获取"ANDROID_SOCKET_zygote这个环境变量对应的描述符,和我们前面 android usb挂载分析----vold启动文章中讲的获取"vold‘套接字是一样的,不过是这里传入的是整个环境变量的名称,而前面vold启动中传的是“vold"字符串,再在后面调用了android_get_control_socket在里面加上前缀组合成环境变量名再去获取的。
- private static void registerZygoteSocket() {
- if (sServerSocket == null) {
- int fileDesc;
- try {
- String env = System.getenv(ANDROID_SOCKET_ENV);
- fileDesc = Integer.parseInt(env);
- } catch (RuntimeException ex) {
- throw new RuntimeException(
- ANDROID_SOCKET_ENV + " unset or invalid", ex);
- }
- try {
- sServerSocket = new LocalServerSocket(
- createFileDescriptor(fileDesc));
- } catch (IOException ex) {
- throw new RuntimeException(
- "Error binding to local socket '" + fileDesc + "'", ex);
- }
- }
- }
LocalServerSocket即进行了监听操作:
- public LocalServerSocket(FileDescriptor fd) throws IOException
- {
- impl = new LocalSocketImpl(fd);
- impl.listen(LISTEN_BACKLOG);
- localAddress = impl.getSockAddress();
- }
- preloadClasses();
- //cacheRegisterMaps();
- preloadResources();
启动系统服务
- if (argv[1].equals("true")) {
- startSystemServer();
- }
- /**
- * Prepare the arguments and fork for the system server process.
- */
- private static boolean startSystemServer()
- throws MethodAndArgsCaller, RuntimeException {
- /* 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,3001,3002,3003",
- "--capabilities=130104352,130104352",
- "--runtime-init",
- "--nice-name=system_server",
- "com.android.server.SystemServer",
- };
- ZygoteConnection.Arguments parsedArgs = null;
- int pid;
- try {
- parsedArgs = new ZygoteConnection.Arguments(args);
- /*
- * Enable debugging of the system process if *either* the command line flags
- * indicate it should be debuggable or the ro.debuggable system property
- * is set to "1"
- */
- int debugFlags = parsedArgs.debugFlags;
- if ("1".equals(SystemProperties.get("ro.debuggable")))
- debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
- /* Request to fork the system server process */
- pid = Zygote.forkSystemServer(
- parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, debugFlags, null,
- parsedArgs.permittedCapabilities,
- parsedArgs.effectiveCapabilities);
- } catch (IllegalArgumentException ex) {
- throw new RuntimeException(ex);
- }
- /* For child process */
- if (pid == 0) {
- handleSystemServerProcess(parsedArgs);
- }
- return true;
- }
这里调用forkSystemServer fork一个子进程,父进程直接返回,子进程执行handleSystemServerProcess
Zygote.forkSystemServer最终调用Dalvik_dalvik_system_Zygote_forkSystemServer
- static void Dalvik_dalvik_system_Zygote_forkSystemServer(
- const u4* args, JValue* pResult)
- {
- pid_t pid;
- pid = forkAndSpecializeCommon(args, true);
- /* The zygote process checks whether the child process has died or not. */
- if (pid > 0) {
- int status;
- LOGI("System server process %d has been created", pid);
- gDvm.systemServerPid = pid;
- /* There is a slight window that the system server process has crashed
- * but it went unnoticed because we haven't published its pid yet. So
- * we recheck here just to make sure that all is well.
- */
- if (waitpid(pid, &status, WNOHANG) == pid) {
- LOGE("System server process %d has died. Restarting Zygote!", pid);
- kill(getpid(), SIGKILL);
- }
- }
- RETURN_INT(pid);
- }
- static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)
- {
- ...
- setSignalHandler();
- }
- static void setSignalHandler()
- {
- int err;
- struct sigaction sa;
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = sigchldHandler;
- err = sigaction (SIGCHLD, &sa, NULL);
- if (err < 0) {
- LOGW("Error setting SIGCHLD handler: %s", strerror(errno));
- }
- }
这里在注册了一个子进程退出的信号,处理函数:
- <span style="color:#333333;">static void sigchldHandler(int s)
- {
- pid_t pid;
- int status;
- while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
- if (WIFEXITED(status)) {
- if (WEXITSTATUS(status)) {
- LOG(LOG_DEBUG, ZYGOTE_LOG_TAG, "Process %d exited cleanly (%d)\n",
- (int) pid, WEXITSTATUS(status));
- } else {
- IF_LOGV(/*should use ZYGOTE_LOG_TAG*/) {
- LOG(LOG_VERBOSE, ZYGOTE_LOG_TAG,
- "Process %d exited cleanly (%d)\n",
- (int) pid, WEXITSTATUS(status));
- }
- }
- } else if (WIFSIGNALED(status)) {
- if (WTERMSIG(status) != SIGKILL) {
- LOG(LOG_DEBUG, ZYGOTE_LOG_TAG,
- "Process %d terminated by signal (%d)\n",
- (int) pid, WTERMSIG(status));
- } else {
- IF_LOGV(/*should use ZYGOTE_LOG_TAG*/) {
- LOG(LOG_VERBOSE, ZYGOTE_LOG_TAG,
- "Process %d terminated by signal (%d)\n",
- (int) pid, WTERMSIG(status));
- }
- }
- #ifdef WCOREDUMP
- if (WCOREDUMP(status)) {
- LOG(LOG_INFO, ZYGOTE_LOG_TAG, "Process %d dumped core\n",
- (int) pid);
- }
- #endif /* ifdef WCOREDUMP */
- }
- /*
- * If the just-crashed process is the system_server, bring down zygote
- * so that it is restarted by init and system server will be restarted
- * from there.
- */
- if (pid == gDvm.systemServerPid) {
- LOG(LOG_INFO, ZYGOTE_LOG_TAG,
- “Exit zygote because system server (%d) has terminated\n”);
- kill(getpid(), SIGKILL);
- }
- }
- if (pid < 0) {
- LOG(LOG_WARN, ZYGOTE_LOG_TAG,
- "Zygote SIGCHLD error in waitpid: %s\n",strerror(errno));
- }
- }
- </span>
继续跟踪main函数,父进程返回后
- if (ZYGOTE_FORK_MODE) {
- runForkMode();
- } else {
- runSelectLoopMode();
- }
这进而ZYGOTE_FORK_MODE为false所以执行runSelectLoopMode
- /**
- * Runs the zygote process's select loop. Accepts new connections as
- * they happen, and reads commands from connections one spawn-request's
- * worth at a time.
- *
- * @throws MethodAndArgsCaller in a child process when a main() should
- * be executed.
- */
- private static void runSelectLoopMode() throws MethodAndArgsCaller {
- ArrayList<FileDescriptor> fds = new ArrayList();
- ArrayList<ZygoteConnection> peers = new ArrayList();
- FileDescriptor[] fdArray = new FileDescriptor[4];
- fds.add(sServerSocket.getFileDescriptor());
- peers.add(null);
- int loopCount = GC_LOOP_COUNT;
- while (true) {
- int index;
- /*
- * Call gc() before we block in select().
- * It's work that has to be done anyway, and it's better
- * to avoid making every child do it. It will also
- * madvise() any free memory as a side-effect.
- *
- * Don't call it every time, because walking the entire
- * heap is a lot of overhead to free a few hundred bytes.
- */
- if (loopCount <= 0) {
- gc();
- loopCount = GC_LOOP_COUNT;
- } else {
- loopCount--;
- }
- try {
- fdArray = fds.toArray(fdArray);
- index = selectReadable(fdArray);
- } catch (IOException ex) {
- throw new RuntimeException("Error in select()", ex);
- }
- if (index < 0) {
- throw new RuntimeException("Error in select()");
- } else if (index == 0) {
- ZygoteConnection newPeer = acceptCommandPeer();
- peers.add(newPeer);
- fds.add(newPeer.getFileDesciptor());
- } else {
- boolean done;
- done = peers.get(index).runOnce();
- if (done) {
- peers.remove(index);
- fds.remove(index);
- }
- }
- }
- }
runSelectLoopMode等待 ActivityManagerService发送请求过来,最后调用ZygoteConnection.runOncef fork一个进程来运行应用程序。
到这里zygote就启动完成了,在它fork出来的SystemServer会负责一些其它关键服务的初始化,而他自己则等待ActivityManagerService的请求,为一个新的应用程序fork出 一个子进程。