Android启动流程

时间:2024-06-13 10:50:20

目标:

1.zygote怎么创建进程?

fork进程:fork复制一份进程,对应的返回值有两个,pid=0,子进程;pid!=0父进程

写时拷贝: fork的子进程以后,子进程和父进程公用一份内存空间,只有子进程数据有修改时,才将内存复制一份新的写入。

2.init进程有什么作用?

3.systemserver为什么不在init中启动?

一、安卓启动流程

启动流程图

1.1 Boot Rom

安卓上电以后,引导芯片从ROM加载引导程序BootLoader到RAM,然后开始执行

1.2 BootLoader

BootLoader是什么?

相当于Windows BIOS

引导操作系统启动,启动安卓的第一个进程idle. 

1.3 idle进程

IDLE进程初始化进程管理、内存管理,加载Binder Driver、Display、Camera Driver灯相关工作。

Idle会创建两个进程,一个是kthreadd进程(内核进程)和init进程。

kthreadd进程:内核进程的鼻祖。

1.4 init进程

init进程是用户空间的鼻祖。init会fork创建zygote进程。

1.5 zygote进程

zygote进程是Java进程的鼻祖。所有的Java进程都是由zygote创建的(fork)。启动时zygote会

fork出大儿子 SystemServer进程。

1.6 SystemServer

SystemServer会启动一系列Android系统服务。

1.7 App进程

zygote利用AMS创建出app进程。

二、init进程的启动

2.1 启动入口

在/kernal/common/init/main.c

kernal_init方法

try_to_run_init_process("/bin/init")

启动init进程。

2.2 init进程main方法

关键方法:init会执行多次。

第一阶段:FirstStageMain:

  • 挂载磁盘文
  • 重定向输入输出
  • 初始化内核日志输出
  • 启动selinux_setup:Selinux初始化

安卓采用的Selinux安全策略

第二阶段:SecondStageMain

PropertyInit: 初始化属性域

初始化子进程终止信号:InstallSignalFDHandler(&epoll)

处理僵尸进程

什么是僵尸进程?

匹配命令和函数关系:GetBuiltinFunctionMap

解析Init.rc: LoadBootScripts()

创建解析器createParser,进行对应配置解析。

解析成功后,执行脚本命令。

进入while循环,循环等待启动进程。

am.ExecuteOneCommand

2.3 init主要功能

init主要功能

  1. 挂载文件
  2. 设置Selinux,开启安全策略
  3. 开启属性服务,注册到epoll
  4. 解析init启动脚本init.rc
  5. 循环处理脚本--》启动zygote
  6. 循环等待

三、zygote进程

zygote横跨C/C++和Java。

3.1 zygote启动入口

app_process(app_process32、app_process64)

 

入口方法:app_main.cpp的main方法

安卓运行时环境是zygote启动的。
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));

int main(int argc, char* const argv[])
174  {
175      if (!LOG_NDEBUG) {
176        String8 argv_String;
177        for (int i = 0; i < argc; ++i) {
178          argv_String.append("\"");
179          argv_String.append(argv[i]);
180          argv_String.append("\" ");
181        }
182        ALOGV("app_process main with argv: %s", argv_String.string());
183      }
184  
185      AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
186      // Process command line arguments
187      // ignore argv[0]
188      argc--;
189      argv++;
190  
191      // Everything up to '--' or first non '-' arg goes to the vm.
192      //
193      // The first argument after the VM args is the "parent dir", which
194      // is currently unused.
195      //
196      // After the parent dir, we expect one or more the following internal
197      // arguments :
198      //
199      // --zygote : Start in zygote mode
200      // --start-system-server : Start the system server.
201      // --application : Start in application (stand alone, non zygote) mode.
202      // --nice-name : The nice name for this process.
203      //
204      // For non zygote starts, these arguments will be followed by
205      // the main class name. All remaining arguments are passed to
206      // the main method of this class.
207      //
208      // For zygote starts, all remaining arguments are passed to the zygote.
209      // main function.
210      //
211      // Note that we must copy argument string values since we will rewrite the
212      // entire argument block when we apply the nice name to argv0.
213      //
214      // As an exception to the above rule, anything in "spaced commands"
215      // goes to the vm even though it has a space in it.
216      const char* spaced_commands[] = { "-cp", "-classpath" };
217      // Allow "spaced commands" to be succeeded by exactly 1 argument (regardless of -s).
218      bool known_command = false;
219  
220      int i;
221      for (i = 0; i < argc; i++) {
222          if (known_command == true) {
223            runtime.addOption(strdup(argv[i]));
224            // The static analyzer gets upset that we don't ever free the above
225            // string. Since the allocation is from main, leaking it doesn't seem
226            // problematic. NOLINTNEXTLINE
227            ALOGV("app_process main add known option '%s'", argv[i]);
228            known_command = false;
229            continue;
230          }
231  
232          for (int j = 0;
233               j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));
234               ++j) {
235            if (strcmp(argv[i], spaced_commands[j]) == 0) {
236              known_command = true;
237              ALOGV("app_process main found known command '%s'", argv[i]);
238            }
239          }
240  
241          if (argv[i][0] != '-') {
242              break;
243          }
244          if (argv[i][1] == '-' && argv[i][2] == 0) {
245              ++i; // Skip --.
246              break;
247          }
248  
249          runtime.addOption(strdup(argv[i]));
250          // The static analyzer gets upset that we don't ever free the above
251          // string. Since the allocation is from main, leaking it doesn't seem
252          // problematic. NOLINTNEXTLINE
253          ALOGV("app_process main add option '%s'", argv[i]);
254      }
255  
256      // Parse runtime arguments.  Stop at first unrecognized option.
257      bool zygote = false;
258      bool startSystemServer = false;
259      bool application = false;
260      String8 niceName;
261      String8 className;
262  
263      ++i;  // Skip unused "parent dir" argument.
264      while (i < argc) {
265          const char* arg = argv[i++];
266          if (strcmp(arg, "--zygote") == 0) {
267              zygote = true;
268              niceName = ZYGOTE_NICE_NAME;
269          } else if (strcmp(arg, "--start-system-server") == 0) {
270              startSystemServer = true;
271          } else if (strcmp(arg, "--application") == 0) {
272              application = true;
273          } else if (strncmp(arg, "--nice-name=", 12) == 0) {
274              niceName.setTo(arg + 12);
275          } else if (strncmp(arg, "--", 2) != 0) {
276              className.setTo(arg);
277              break;
278          } else {
279              --i;
280              break;
281          }
282      }
283  
284      Vector<String8> args;
285      if (!className.isEmpty()) {
286          // We're not in zygote mode, the only argument we need to pass
287          // to RuntimeInit is the application argument.
288          //
289          // The Remainder of args get passed to startup class main(). Make
290          // copies of them before we overwrite them with the process name.
291          args.add(application ? String8("application") : String8("tool"));
292          runtime.setClassNameAndArgs(className, argc - i, argv + i);
293  
294          if (!LOG_NDEBUG) {
295            String8 restOfArgs;
296            char* const* argv_new = argv + i;
297            int argc_new = argc - i;
298            for (int k = 0; k < argc_new; ++k) {
299              restOfArgs.append("\"");
300              restOfArgs.append(argv_new[k]);
301              restOfArgs.append("\" ");
302            }
303            ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
304          }
305      } else {
306          // We're in zygote mode.
307          maybeCreateDalvikCache();
308  
309          if (startSystemServer) {
310              args.add(String8("start-system-server"));
311          }
312  
313          char prop[PROP_VALUE_MAX];
314          if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
315              LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
316                  ABI_LIST_PROPERTY);
317              return 11;
318          }
319  
320          String8 abiFlag("--abi-list=");
321          abiFlag.append(prop);
322          args.add(abiFlag);
323  
324          // In zygote mode, pass all remaining arguments to the zygote
325          // main() method.
326          for (; i < argc; ++i) {
327              args.add(String8(argv[i]));
328          }
329      }
330  
331      if (!niceName.isEmpty()) {
332          runtime.setArgv0(niceName.string(), true /* setProcName */);
333      }
334  
335      if (zygote) {
336          runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
337      } else if (className) {
338          runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
339      } else {
340          fprintf(stderr, "Error: no class name or --zygote supplied.\n");
341          app_usage();
342          LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
343      }
344  }

启动参数解析:

启动zygote进程

3.2 AndroidRuntime.start

核心进程保护机制:

zygote或者init进程、systemserver进程杀死的话,会重启安卓系统。

zygote的native启动处理

3.2.1 zygote启动虚拟机

进程和虚拟机什么关系?哪个大?

zygote进程--》startVm启动虚拟机

虚拟机运行在进程中,虚拟机代码实现了这个功能:内存管理。

一个进程会创建一个虚拟机。

3.2.2 注册JNI

Java代码不能直接访问C++代码,需要通过JNI桥梁进行访问。

注册JNI就是建立桥梁,将java的本地方法和native的方法关联起来。

3.2.3 调用ZygoteInit.main方法

AndroidRuntime调用ZygoteInit.main方法。ZygoteInit.java是Java代码。

JNI实现了C++和Java相互调用的桥梁。 

3.3 ZygoteInit.main 

ZygoteInit处理zygote的java启动流程。进程不分native进程和Java进程。

ZygoteInit.main主要处理流程:

1)preload预处理(加快进程启动)

2)启动SystemServer进程

3)启动死循环,接收AMS的app启动请求

3.4 zygote启动总结

main方法中创建ZygoteServer。

3.3.1 ZygoteServer

Zygote的socket Server端。

创建一个Socket服务器。

此处为什么不使用Binder?

fork当前进程拷贝,如果创建进程添加了锁,拷贝的时候锁会丢失,导致进程出现死锁。

四、SystemServer进程

4.1 zygote如何启动SystemServer

systemserver是一个独立的进程,管理服务的,启动90多个系统服务。主要功能是为APP提供各种系统服务。AMS、PKMS都是systemserver中的关键服务。

zygoteInit-->zygote.forkSystemServer-->nativeForkSystemServer

根据3.2.2 注册JNI方法,

找到nativeForkSystemServer 对应的C++实现。

/frameworks/base/core/jni/

static const JNINativeMethod gMethods[] = {
2445          {"nativeForkAndSpecialize",
2446           "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/"
2447           "String;Z[Ljava/lang/String;[Ljava/lang/String;ZZ)I",
2448           (void*)com_android_internal_os_Zygote_nativeForkAndSpecialize},
2449          {"nativeForkSystemServer", "(II[II[[IJJ)I",
2450           (void*)com_android_internal_os_Zygote_nativeForkSystemServer},
2451          {"nativeAllowFileAcrossFork", "(Ljava/lang/String;)V",
2452           (void*)com_android_internal_os_Zygote_nativeAllowFileAcrossFork},
2453          {"nativePreApplicationInit", "()V",
2454           (void*)com_android_internal_os_Zygote_nativePreApplicationInit},
2455          {"nativeInstallSeccompUidGidFilter", "(II)V",
2456           (void*)com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter},
2457          {"nativeForkUsap", "(II[IZ)I", (void*)com_android_internal_os_Zygote_nativeForkUsap},
2458          {"nativeSpecializeAppProcess",
2459           "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/"
2460           "String;Z[Ljava/lang/String;[Ljava/lang/String;ZZ)V",
2461           (void*)com_android_internal_os_Zygote_nativeSpecializeAppProcess},
2462          {"nativeInitNativeState", "(Z)V",
2463           (void*)com_android_internal_os_Zygote_nativeInitNativeState},
2464          {"nativeGetUsapPipeFDs", "()[I",
2465           (void*)com_android_internal_os_Zygote_nativeGetUsapPipeFDs},
2466          {"nativeRemoveUsapTableEntry", "(I)Z",
2467           (void*)com_android_internal_os_Zygote_nativeRemoveUsapTableEntry},
2468          {"nativeGetUsapPoolEventFD", "()I",
2469           (void*)com_android_internal_os_Zygote_nativeGetUsapPoolEventFD},
2470          {"nativeGetUsapPoolCount", "()I",
2471           (void*)com_android_internal_os_Zygote_nativeGetUsapPoolCount},
2472          {"nativeEmptyUsapPool", "()V", (void*)com_android_internal_os_Zygote_nativeEmptyUsapPool},
2473          {"nativeBlockSigTerm", "()V", (void*)com_android_internal_os_Zygote_nativeBlockSigTerm},
2474          {"nativeUnblockSigTerm", "()V", (void*)com_android_internal_os_Zygote_nativeUnblockSigTerm},
2475          {"nativeBoostUsapPriority", "()V",
2476           (void*)com_android_internal_os_Zygote_nativeBoostUsapPriority},
2477          {"nativeParseSigChld", "([BI[I)I",
2478           (void*)com_android_internal_os_Zygote_nativeParseSigChld},
2479          {"nativeSupportsTaggedPointers", "()Z",
2480           (void*)com_android_internal_os_Zygote_nativeSupportsTaggedPointers},
2481  };

找到了对应的native方法 

 进一步看native方法

static jint com_android_internal_os_Zygote_nativeForkSystemServer(
2075          JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
2076          jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
2077          jlong effective_capabilities) {
2078    std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()),
2079                     fds_to_ignore(fds_to_close);
2080  
2081    fds_to_close.push_back(gUsapPoolSocketFD);
2082  
2083    if (gUsapPoolEventFD != -1) {
2084      fds_to_close.push_back(gUsapPoolEventFD);
2085      fds_to_ignore.push_back(gUsapPoolEventFD);
2086    }
2087  
2088    if (gSystemServerSocketFd != -1) {
2089        fds_to_close.push_back(gSystemServerSocketFd);
2090        fds_to_ignore.push_back(gSystemServerSocketFd);
2091    }
2092  
2093    pid_t pid = ForkCommon(env, true,
2094                           fds_to_close,
2095                           fds_to_ignore,
2096                           true);
2097    if (pid == 0) {
2098        // System server prcoess does not need data isolation so no need to
2099        // know pkg_data_info_list.
2100        SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
2101                         permitted_capabilities, effective_capabilities,
2102                         MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
2103                         false, nullptr, nullptr, /* is_top_app= */ false,
2104                         /* pkg_data_info_list */ nullptr,
2105                         /* whitelisted_data_info_list */ nullptr, false, false);
2106    } else if (pid > 0) {
2107        // The zygote process checks whether the child process has died or not.
2108        ALOGI("System server process %d has been created", pid);
2109        gSystemServerPid = pid;
2110        // There is a slight window that the system server process has crashed
2111        // but it went unnoticed because we haven't published its pid yet. So
2112        // we recheck here just to make sure that all is well.
2113        int status;
2114        if (waitpid(pid, &status, WNOHANG) == pid) {
2115            ALOGE("System server process %d has died. Restarting Zygote!", pid);
2116            RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
2117        }
2118  
2119        if (UsePerAppMemcg()) {
2120            // Assign system_server to the correct memory cgroup.
2121            // Not all devices mount memcg so check if it is mounted first
2122            // to avoid unnecessarily printing errors and denials in the logs.
2123            if (!SetTaskProfiles(pid, std::vector<std::string>{"SystemMemoryProcess"})) {
2124                ALOGE("couldn't add process %d into system memcg group", pid);
2125            }
2126        }
2127    }
2128    return pid;
2129  }

fork进程使用的是ForkCommon,

pid_t pid = ForkCommon(env, true,
2094                           fds_to_close,
2095                           fds_to_ignore,
2096                           true);

fork方法,fork出systemserver进程。

4.2 fork进程

fork会得到两个进程,一个父进程,一个子进程。因此有两个返回值,pid_t

怎么判断fork后的进程是父进程还是子进程?

根据返回值判断,pid==0,则是子进程。

ZygoteInit.main中

4.3 SystemServer启动服务

创建上下文 createSystemContext

SystemServer进程需要一直活着,存在Loop.loop()进入死循环

启动服务主要有三个主要函数:

startBootStrapServices

startCoreServices

startOtherServices

都是通过systemManager.startService启动的。

4.4 SystemServer

SystemServer: 是一个进程,管理服务的进程

SystemServerManager: 管理系统服务的类。这些服务都继承SystemServie

SystemManager:也是一个进程,管理系统服务的binder

ActivityManagerTaskService继承IActivityManagerTask.Stub

有需要继承SystemServie?怎么呢?采用Lyficycle类型,继承SysytemService,