相关文章 Android系统启动流程(1)  ——  解析init进程启动过程        在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由zygote进程孕育(fork)出来的,这也许就是为什么要把它称为Zygote(受精卵)的原因吧。由于zygote进程在Android系统中有着如此重要的地位,本文将详细分析它的启动过程。        在Android系统中,DVM(Dalvik虚拟机)、应用程序进程以及运行系统的关键服务的SystemServer进程都是由zygote进程来创建的,我们也将它称为孵化器。它通过fock(复制进程)的形式来创建应用程序进程和SystemServer进程,由于zygote进程在启动时会创建DVM,因此通过fock而创建的应用程序进程和SystemServer进程可以在内部获取一个DVM的实例拷贝。         在init.rc文件中采用了Import类型语句来引入Zygote启动脚本,这些启动脚本都是由Android初始化语言(Android Init Language)来编写的,引入Zygote脚本代码如下: system/core/init/init.cpp        在init.rc中通过属性ro.zygote的值来引入不同的zygote启动脚本的。从Android5.0开始,Android开始支持64位程序,Zygote也就有了32位和64位的区别了,所以在这里用 ro.zygote 属性来控制使用不同的 Zygote 启动脚本,从而也就启动了不同版本zygote进程, ro.zygote 属性的取值有以下4种:       表示支持纯 32 位程序, init.zygote32.rc 文件内容如下所示:        根据 Service类型语句的格式,可以得知 Zygote 进程名称为zygote ,执行程序为 app _process, class name为main ,如果 audioserver cameraserver、 media、netd、wificond 进程终止了,就需要进行 restart (重启 )。        表示既支持 32 位程序也支持64位程序, init.zygote32_64.rc 文件内容如下所示:       表示支持纯 64 位程序, init.zygote64.rc 文件内容如下所示:        根据 Service类型语句的格式,可以得知 Zygote 进程名称为zygote ,执行程序为 app _process64, class name为main ,如果 audioserver cameraserver、 media、netd、wificond 进程终止了,就需要进行 restart (重启 )。        表示既支持 32 位程序也支持64位程序, init.zygote64_32.rc 文件内容如下所示:        脚本中有两个Service类型语句,说明会启动两个zygote 进程, 第一个名称为 zygote,执行程序为 app_process64 ,作为主模式 ;第二个名称为 zygote_secondary,执行程序为 app _process ,作为辅模式。        在init启动zygote进程是主要是调用App_mian.cpp的main函数中的AppRuntime的start方法来启动zygote进程的,那我们就从App_main.cpp的main函数开始分析,代码如下: frameworks/base/cmds/app_process/App_main.cpp        由于zygote进程都是通过fock自身来创建子进程的,所以zygote进程以及它的子进程都可以进入App_main.cpp的main函数,因此main函数中为了区分当前运行在哪个进程中,会在注释1处判断参数 arg中是否包含了“–zygote”,如果包含了则说明main函数是运行在 zygote 进程中的并在注释2处将 zygote设置为ture,同理在注释3处判断参数arg中是否包含了“–start-system-server”,如果包含了则说明 main 函数是运行在SystemServer进程中的并在注释4处将 startSystemServer设置为true。       在注释5处,如果zygote为true,就说明当前运行在zygote进程中,就会调用注释6处的runtime的start函数,runtime指的就是AppRuntime,AppRuntime声明也在App_main.cpp中,它继承AndroidRuntime,但是AppRuntime并没有重写start函数,也就是说我们调用start函数其实调用的就是AndroidRuntime的start函数,如下所示: frameworks/base/cmds/app_process/App_main.cpp        在注释1处通过registerServerSocket 方法来创建 Server 端的 Socket ,这个name 为“zygote”的 Socket 用于等待 ActivityManagerService 请求 Zygote 来创建新的应用程序进程,后续会出AMS相关的文章解析AMS,这里就先不做介绍了。在注释2处预加载类和资源。在注释3处启动 SystemServer进程,这样系统的服务也会由 SystemServer进程启动起来。在注释4处调用 zygoteServer.runSelectLoop 方法来等待 AMS 请求创建新的应用程序进程。由此得知, Zygotelnit的main方法主要做了4件事:        首先我们来查看 ZygoteServer的registerZygoteSocket 方法做了什么,代码如下所示: frameworks/base/core/java/com/android/internal/os/ZygoteServe.java        接下来查看 forkSystemServer方法, 代码如下所示: frameworks/base/core/java/com/android/internal/os/Zygotelnit.java         注释1处的代码用来创建 args 数组,这个数组用来保存启动SystemServer 进程的启动参数,其中可以看出SystemServer 进程的用户id 和用户组 id 被设置为1000 ,并且拥有用户组 1001~1010、1018、1021、1032 、3001~3010 的权限;进程名为 system_server ;启动的类名 com.android server.SystemServer 。在注释2处将 args 数组封装成 Arguments 对象并供注释3处的 forkSystemServer 函数调用 。在注释3处调用 Zygote.forkSystemServer 方法, 其内部会调用 nativeForkSystemServer 这个 Native 方怯, nativeForkSystemServer方法最终会通过fork函数在当前进程创建一个子进程,也就是SystemServer 进程,如果forkSystemServer 方法返回的 pid 的值为0 ,就表示当前的代码运行在新创建的子进程中, 则执行注释4处的 handleSystemServerProcess 来处理 SystemServer 进程。        启动Systemserver 进程后,会执行ZygoteServer的runSelectLoop 方法来等待AMS的请求,代码如下所示: frameworks/base/core/java/com/android/internal/os/ZygoteServe.javaZygote 进程启动过程
    1. Zygote简介
        关于init启动zygote我们在上一篇文章已经提到了,这里就不赘述了,这篇文章主要分析Android8.1系统的zygote进程的启动流程。     2. Zygote启动脚本
 
import /init.${ro.zygote}.rc
     1. 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     socket zygote 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       2. init.zygote32_64.rc
 
service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote     class main     priority -20     user root     group root readproc     socket zygote 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  service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary     class main     priority -20     user root     group root readproc     socket zygote_secondary stream 660 root system     onrestart restart zygote     writepid /dev/cpuset/foreground/tasks      3. init.zygote64.rc
 
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server     class main     priority -20     user root     group root readproc     socket zygote 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       4. init.zygote64_32.rc
 
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote     class main     priority -20     user root     group root readproc     socket zygote 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  service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload     class main     priority -20     user root     group root readproc     socket zygote_secondary stream 660 root system     onrestart restart zygote     writepid /dev/cpuset/foreground/tasks     3. Zygote 进程启动过程介绍
 
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) { // ... 1             // 如果当前运行在zygote进程中,则将zygote设置为true             zygote = true; // ... 2             niceName = ZYGOTE_NICE_NAME;         } else if (strcmp(arg, "--start-system-server") == 0) { // ... 3             // 如果当前运行在SystemServer进程中,则将startSystemServer设置为true             startSystemServer = true; // ... 4         } 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 (!niceName.isEmpty()) {         runtime.setArgv0(niceName.string(), true /* setProcName */);     }      // 如果运行在zygote进程中     if (zygote) { // ... 5         runtime.start("com.android.internal.os.ZygoteInit", args, zygote); // ... 6     } 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.");     } }  
class AppRuntime : public AndroidRuntime 
/*  * 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) {     ...      /* start the virtual machine */     JniInvocation jni_invocation;     jni_invocation.Init(NULL);     JNIEnv* env;     // 启动java虚拟机     if (startVm(&mJavaVM, &env, zygote) != 0) { // ... 1         return;     }     onVmCreated(env);      /*      * Register android functions.      * 为java虚拟机注册JNI方法      */     if (startReg(env) < 0) { // ... 2         ALOGE("Unable to register all android nativesn");         return;     }           ...          stringClass = env->FindClass("java/lang/String");     assert(stringClass != NULL);     strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);     assert(strArray != NULL);      // 从App_main的main函数得知,className为com.android.internal.os.ZygoteInit     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.      */      // 将className的"."替换为"/"     char* slashClassName = toSlashClassName(className != NULL ? className : ""); // .. 4     // 找到ZygoteInit     jclass startClass = env->FindClass(slashClassName); // ... 5     if (startClass == NULL) {         ALOGE("JavaVM unable to locate class '%s'n", slashClassName);         /* keep going */     } else {         // 找到ZygoteInit的main方法         jmethodID startMeth = env->GetStaticMethodID(startClass, "main",             "([Ljava/lang/String;)V"); // ... 6         if (startMeth == NULL) {             ALOGE("JavaVM unable to find main() in '%s'n", className);             /* keep going */         } else {             // 通过JNI调用ZygoteInit的main方法             env->CallStaticVoidMethod(startClass, startMeth, strArray); // ... 7  #if 0             if (env->ExceptionCheck())                 threadExitUncaughtException(env); #endif         }     }     free(slashClassName);      ALOGD("Shutting down VMn");     if (mJavaVM->DetachCurrentThread() != JNI_OK)         ALOGW("Warning: unable to detach main threadn");     if (mJavaVM->DestroyJavaVM() != 0)         ALOGW("Warning: VM did not shut down cleanlyn"); }  
public static void main(String argv[]) {         ZygoteServer zygoteServer = new ZygoteServer()         ...          String socketName = "zygote";           ...                 try {                           ...              // 创建一个Server端的Socket,socketName的值为"zygote"             zygoteServer.registerServerSocket(socketName); // ... 1             // 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); // ... 2                  EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,                     SystemClock.uptimeMillis());                 bootTimingsTraceLog.traceEnd(); // ZygotePreload             } else {                 Zygote.resetNicePriority();             }              ...              if (startSystemServer) {                 // 启动SystemServer进程                 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.             // 等待AMS请求             caller = zygoteServer.runSelectLoop(abiList); // 4         } 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();         }     }       1 . registerZygoteSocket 
 
    /**      * Registers a server socket for zygote command connections      *      * @throws RuntimeException when open fails      */     void registerServerSocket(String socketName) {         if (mServerSocket == null) {             int fileDesc;             // 拼接Socket的名称             final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;              try {                 // 获取Socket的环境变量的值                 String env = System.getenv(fullSocketName);                  // 将Socket环境变量的值转化为文件描述符的参数                 fileDesc = Integer.parseInt(env);              } catch (RuntimeException ex) {                 throw new RuntimeException(fullSocketName + " unset or invalid", ex);             }              try {                 // 创建文件描述符                 FileDescriptor fd = new FileDescriptor();                  // 设置文件描述符的参数                 fd.setInt$(fileDesc);                 // 创建服务器端Socket                 mServerSocket = new LocalServerSocket(fd); // ... 1             } catch (IOException ex) {                 throw new RuntimeException(                         "Error binding to local socket '" + fileDesc + "'", ex);             }         }     }       2. 启动SystemServer进程
 
    /**      * Prepare the arguments and forks for the system server process.      *      * Returns an {@code Runnable} that provides an entrypoint into system_server code in the      * child process, and {@code null} in the parent.      */     private static Runnable forkSystemServer(String abiList, String socketName,             ZygoteServer zygoteServer) {                  ...            /* Hardcoded command line to start the system server */          // 创建 args 数组,这个数组用来保存启动SystemServer进程的启动参数         String args[] = {             "--setuid=1000",             "--setgid=1000",             "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",             "--capabilities=" + capabilities + "," + capabilities,             "--nice-name=system_server",             "--runtime-args",             "com.android.server.SystemServer",         };  // ... 1           ZygoteConnection.Arguments parsedArgs = null;          int pid;          try {             parsedArgs = new ZygoteConnection.Arguments(args); // ... 2             ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);             ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);              /* Request to fork the system server process */             // 创建system_server进程             pid = Zygote.forkSystemServer(                     parsedArgs.uid, parsedArgs.gid,                     parsedArgs.gids,                     parsedArgs.debugFlags,                     null,                     parsedArgs.permittedCapabilities,                     parsedArgs.effectiveCapabilities); // ... 3         } catch (IllegalArgumentException ex) {             throw new RuntimeException(ex);         }          /* For child process */         // 当前代码逻辑运行在子进程中         if (pid == 0) {             if (hasSecondZygote(abiList)) {                 waitForSecondaryZygote(socketName);             }              zygoteServer.closeServerSocket();             // 处理system_server进程             return handleSystemServerProcess(parsedArgs); // ... 4         }          return null;     }       3. runSelectloop
 
/**      * 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.      */     Runnable runSelectLoop(String abiList) {         ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();         ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();          fds.add(mServerSocket.getFileDescriptor()); // ... 1         peers.add(null);          // 无线循环等待AMS的请求         while (true) {             StructPollfd[] pollFds = new StructPollfd[fds.size()];             for (int i = 0; i < pollFds.length; ++i) { // ... 2                 pollFds[i] = new StructPollfd();                 pollFds[i].fd = fds.get(i);                 pollFds[i].events = (short) POLLIN;             }             try {                 Os.poll(pollFds, -1);             } catch (ErrnoException ex) {                 throw new RuntimeException("poll failed", ex);             }             for (int i = pollFds.length - 1; i >= 0; --i) { // ... 3                 if ((pollFds[i].revents & POLLIN) == 0) {                     continue;                 }                  if (i == 0) {                     ZygoteConnection newPeer = acceptCommandPeer(abiList); // ... 4                     peers.add(newPeer);                     fds.add(newPeer.getFileDesciptor());                 } else {                     try {                         ZygoteConnection connection = peers.get(i);                         final Runnable command = connection.processOneCommand(this); // ... 5                          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(i);                                 fds.remove(i);                             }                         }                     } 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(i);                             conn.closeSocket();                              fds.remove(i);                         } 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;                         }                     }                 }             }         }     } }     4. Zygote 进程启动总结
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算
 官方软件产品操作指南 (170)
官方软件产品操作指南 (170)