Init进程是Linux系统中用户空间的第一个进程,其进程号为1。
Android本质上就是一个基于Linux内核的操作系统。与 Linux的最大的区别是, Android 在应用层专门为移动设备添加了一些特有的支持。例如进程间通信机制中增加的Binder通信等。
Android系统启动流程的前几步:
1.启动电源以及系统启动
当电源按下时引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序Bootloader到RAM,然后执行。
2.引导程序Bootloader
引导程序是在Android操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行。
3.linux内核启动
内核启动时,设置缓存、被保护存储器、计划列表,加载驱动。当内核完成系统设置,它首先在系统文件中寻找”init”文件,然后启动root进程或者系统的第一个进程加载完Linux基本内核后开始初始化进程Init的。
4.init进程启动
本文主要分析init启动到zygote,systemserver启动的过程
1.init启动过程
Init进程主要做的事情为: /bionic/libc/bionic/libc_init_static.cpp
属性核心文件:
system/core/libcutils/properties.cpp
主要分为两部分:
1.初始化:初始化主要包括建立/dev、/proc等目录,初始化属性,执行init.rc等初始化文件中的Action等。
2.使用while的无限循环来建立子进程。
Linux中除过init外的其他进程都是init负责创建的,都是在这个无限while循环中完成的;而且init也会常驻内容
代码路径:/system/core/init/init.cpp
(http://androidxref.com/8.0.0_r4/xref/system/core/init/init.cpp)
在main函数一开始主要进行一开始的准备工作,例如ueventd和看门狗判断,和信号系统安装,系统环境变量的添加工作
948int main(int argc, char** argv) { 949 if (!strcmp(basename(argv[0]), "ueventd")) {//判断是否为ueventd 950 return ueventd_main(argc, argv); 951 } 952 //判断是否为看门狗 953 if (!strcmp(basename(argv[0]), "watchdogd")) { 954 return watchdogd_main(argc, argv); 955 } 956 957 if (REBOOT_BOOTLOADER_ON_PANIC) { 958 install_reboot_signal_handlers(); 959 } 960 961 add_environment("PATH", _PATH_DEFPATH);//添加环境变量 962
main函数中此段代码主要做的工作就是:创建文件系统目录并挂载相关的文件系统
963 bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);//创建文件并挂载 964 965 if (is_first_stage) { 966 boot_clock::time_point start_time = boot_clock::now(); 967 968 // Clear the umask. 969 umask(0); //清除屏蔽字(file mode creation mask),保证新建的目录的访问权限不受屏蔽字影响 970 971 // Get the basic filesystem setup we need put together in the initramdisk 972 // on / and then we'll let the rc file figure out the rest. 973 mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); //挂载tmpfs文件系统 974 mkdir("/dev/pts", 0755); 975 mkdir("/dev/socket", 0755); 976 mount("devpts", "/dev/pts", "devpts", 0, NULL);// 挂载devpts文件系统 977 #define MAKE_STR(x) __STRING(x) 978 mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));// 挂载proc文件系统 979 // Don't expose the raw commandline to unprivileged processes. 980 chmod("/proc/cmdline", 0440); 981 gid_t groups[] = { AID_READPROC }; 982 setgroups(arraysize(groups), groups); 983 mount("sysfs", "/sys", "sysfs", 0, NULL);// 挂载sysfs文件系统 984 mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);// 挂载selinuxfs文件系统 985 mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11)); 986 mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8)); 987 mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9)); 988
开始解析之前的各类初始化准备工作
989 // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually 990 // talk to the outside world... 991 InitKernelLogging(argv);//内核log初始化 992 993 LOG(INFO) << "init first stage started!"; 994 995 if (!DoFirstStageMount()) { 996 LOG(ERROR) << "Failed to mount required partitions early ..."; 997 panic(); 998 } 999 1000 SetInitAvbVersionInRecovery();//判断是否为recovery模式 1001 1002 // Set up SELinux, loading the SELinux policy. 1003 selinux_initialize(true);//初始化selinux 1004 1005 // We're in the kernel domain, so re-exec init to transition to the init domain now 1006 // that the SELinux policy has been loaded. 1007 if (restorecon("/init") == -1) { 1008 PLOG(ERROR) << "restorecon failed"; 1009 security_failure(); 1010 } 1011 1012 setenv("INIT_SECOND_STAGE", "true", 1); 1013 1014 static constexpr uint32_t kNanosecondsPerMillisecond = 1e6; 1015 uint64_t start_ms = start_time.time_since_epoch().count() / kNanosecondsPerMillisecond; 1016 setenv("INIT_STARTED_AT", StringPrintf("%" PRIu64, start_ms).c_str(), 1); 1017 1018 char* path = argv[0]; 1019 char* args[] = { path, nullptr }; 1020 execv(path, args); 1021 1022 // execv() only returns if an error happened, in which case we 1023 // panic and never fall through this conditional. 1024 PLOG(ERROR) << "execv(\"" << path << "\") failed"; 1025 security_failure(); 1026 } 1027 1028 // At this point we're in the second stage of init. 1029 InitKernelLogging(argv); 1030 LOG(INFO) << "init second stage started!"; 1031 1032 // Set up a session keyring that all processes will have access to. It 1033 // will hold things like FBE encryption keys. No process should override 1034 // its session keyring. 1035 keyctl(KEYCTL_GET_KEYRING_ID, KEY_SPEC_SESSION_KEYRING, 1); 1036 1037 // Indicate that booting is in progress to background fw loaders, etc. 1038 close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));// 检测/dev/.booting文件是否可读写、创建等
1039 1040 property_init();// 初始化属性域 --> 定义于system/core/init/property_service.cpp 1041 1042 // If arguments are passed both on the command line and in DT, 1043 // properties set in DT always have priority over the command-line ones. 1044 process_kernel_dt();//dt中的属性设置 1045 process_kernel_cmdline();//处理内核命令行,dt中的属性总是优先于内核命令行 1046 1047 // Propagate the kernel variables to internal variables 1048 // used by init as well as the current required properties. 1049 export_kernel_boot_props();//将内核变量传播给init使用的内部变量以及当前所需的属性 1050 1051 // Make the time that init started available for bootstat to log. 1052 property_set("ro.boottime.init", getenv("INIT_STARTED_AT"));//设置boot启动时间在log中 1053 property_set("ro.boottime.init.selinux", getenv("INIT_SELINUX_TOOK"));//设置selinux启动时间在log中 1054
1055 // Set libavb version for Framework-only OTA match in Treble build. 1056 const char* avb_version = getenv("INIT_AVB_VERSION"); 1057 if (avb_version) property_set("ro.boot.avb_version", avb_version);//在Treble版本中设置libavb版本以进行仅限框架的OTA匹配 1058 1059 // Clean up our environment. 1060 unsetenv("INIT_SECOND_STAGE"); 1061 unsetenv("INIT_STARTED_AT"); 1062 unsetenv("INIT_SELINUX_TOOK"); 1063 unsetenv("INIT_AVB_VERSION"); 1064 1065 // Now set up SELinux for second stage. 1066 selinux_initialize(false);//加载SELinux策略, 后面有一些初始化文件上下文的操作等 1067 selinux_restore_context(); 1068 1069 epoll_fd = epoll_create1(EPOLL_CLOEXEC); 1070 if (epoll_fd == -1) { 1071 PLOG(ERROR) << "epoll_create1 failed"; 1072 exit(1); 1073 } 1074 1075 signal_handler_init();///初始化子进程退出的信号处理过程 1076 1077 property_load_boot_defaults();//加载/default.prop文件 1078 export_oem_lock_status(); 1079 start_property_service();//启动属性服务器(通过socket通信) 1080 set_usb_controller(); 1081 1082 const BuiltinFunctionMap function_map; 1083 Action::set_function_map(&function_map); 1084
正式开启解析init.rc工作 1085 Parser& parser = Parser::GetInstance(); 1086 parser.AddSectionParser("service",std::make_unique());//设置对应的解析函数 “service”块以关键字“service”开始,表示启动某个进程的方式和参数 1087 parser.AddSectionParser("on", std::make_unique ());//“action”块以关键字“on”开始,表示一堆命令的集合 1088 parser.AddSectionParser("import", std::make_unique ()); //“import”是用来引入一个init配置文件,来扩展当前配置的 1089 std::string bootscript = GetProperty("ro.boot.init_rc", ""); 1090 if (bootscript.empty()) { 1091 parser.ParseConfig("/init.rc"); 1092 parser.set_is_system_etc_init_loaded( 1093 parser.ParseConfig("/system/etc/init")); 1094 parser.set_is_vendor_etc_init_loaded( 1095 parser.ParseConfig("/vendor/etc/init")); 1096 parser.set_is_odm_etc_init_loaded(parser.ParseConfig("/odm/etc/init")); 1097 } else { 1098 parser.ParseConfig(bootscript); 1099 parser.set_is_system_etc_init_loaded(true); 1100 parser.set_is_vendor_etc_init_loaded(true); 1101 parser.set_is_odm_etc_init_loaded(true); 1102 } 1103 1104 // Turning this on and letting the INFO logging be discarded adds 0.2s to 1105 // Nexus 9 boot time, so it's disabled by default. 1106 if (false) parser.DumpState(); 1107 1108 ActionManager& am = ActionManager::GetInstance(); 1109 1110 am.QueueEventTrigger("early-init"); 1111 1112 // Queue an action that waits for coldboot done so we know ueventd has set up all of /dev... 1113 am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done"); 1114 // ... so that we can start queuing up actions that require stuff from /dev. 1115 am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); 1116 am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits"); 1117 am.QueueBuiltinAction(set_kptr_restrict_action, "set_kptr_restrict"); 1118 am.QueueBuiltinAction(keychord_init_action, "keychord_init"); 1119 am.QueueBuiltinAction(console_init_action, "console_init"); 1120 1121 // Trigger all the boot actions to get us started. 1122 am.QueueEventTrigger("init"); 1123 1124 // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random 1125 // wasn't ready immediately after wait_for_coldboot_done 1126 am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); 1127 1128 // Don't mount filesystems or start core system services in charger mode. 1129 std::string bootmode = GetProperty("ro.bootmode", ""); 1130 if (bootmode == "charger") { 1131 am.QueueEventTrigger("charger"); 1132 } else { 1133 am.QueueEventTrigger("late-init"); 1134 } 1135 1136 // Run all property triggers based on current state of the properties. 1137 am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");
init.rc的过程就是识别一个个section的过程,将各个section的信息保存下来,然后在init.c的main()中去执行一个个命令。 android采用双向链表(关于双向链表详解见本文第三部分)来存储section的信息,解析完成之后,会得到三个双向链表action_list、service_list、import_list来分别存储三种section的信息上
init.rc解析完成之后,所有的启动项目都被放入到action_add_queue_tail中,接着调用action_for_each_trigger("early-init", action_add_queue_tail),触发early-init触发器来出发这些相关services和actions的运行。
使用while的无限循环来建立子进程
1138 1139 while (true) { 1140 // By default, sleep until something happens. 1141 int epoll_timeout_ms = -1;//以下决定epoll_timeout_ms的时间,将影响while循环的间隔 1142 1143 if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) { 1144 am.ExecuteOneCommand(); 1145 } 1146 if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) { 1147 restart_processes(); 1148 1149 // If there's a process that needs restarting, wake up in time for that. 1150 if (process_needs_restart_at != 0) {//有进程需要重启时,等待该进程重启 1151 epoll_timeout_ms = (process_needs_restart_at - time(nullptr)) * 1000; 1152 if (epoll_timeout_ms < 0) epoll_timeout_ms = 0; 1153 } 1154 1155 // If there's more work to do, wake up again immediately. 1156 if (am.HasMoreCommands()) epoll_timeout_ms = 0; 1157 } 1158 1159 epoll_event ev; 1160 int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, epoll_timeout_ms)); 1161 if (nr == -1) { 1162 PLOG(ERROR) << "epoll_wait failed"; 1163 } else if (nr == 1) { 1164 ((void (*)()) ev.data.ptr)(); 1165 } 1166 } 1167 1168 return 0; 1169}
1service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote 2 class main 3 priority -20 4 user root 5 group root readproc 6 socket zygote stream 660 root system 7 onrestart write /sys/android_power/request_state wake 8 onrestart write /sys/power/state on 9 onrestart restart audioserver 10 onrestart restart cameraserver 11 onrestart restart media 12 onrestart restart netd 13 onrestart restart wificond 14 writepid /dev/cpuset/foreground/tasks 15 16service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary 17 class main 18 priority -20 19 user root 20 group root readproc 21 socket zygote_secondary stream 660 root system 22 onrestart restart zygote 23 writepid /dev/cpuset/foreground/tasks
通过/system/bin/app_process32程序启动zygote进程,参数为--zygote和--start-system-server,这两个参数在后面我们会用到的。下面我们来看一下Zygote的main函数
zygote启动过程大体上分为七部分:
1.app_main.main
代码路径:/frameworks/base/cmds/app_process/app_main.cpp
(http://androidxref.com/8.0.0_r4/xref//frameworks/base/cmds/app_process/app_main.cpp)
在Zygote进程中加载的应用程序文件为system/bin/app_process。 因此,接下来就从这个应用程序文件的入口函数main开始分析Zygote进程的启动过程
187int main(int argc, char* const argv[]) 188{ 189 if (!LOG_NDEBUG) { 190 String8 argv_String; 191 for (int i = 0; i < argc; ++i) { 192 argv_String.append("\""); 193 argv_String.append(argv[i]); 194 argv_String.append("\" "); 195 } 196 ALOGV("app_process main with argv: %s", argv_String.string()); 197 } 198 199 AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));//创建了一个AppRuntime对象runtime 200 // Process command line arguments 201 // ignore argv[0] 202 argc--; 203 argv++; 204 205 // Everything up to '--' or first non '-' arg goes to the vm. 206 // 207 // The first argument after the VM args is the "parent dir", which 208 // is currently unused. 209 // 210 // After the parent dir, we expect one or more the following internal 211 // arguments : 212 // 213 // --zygote : Start in zygote mode 214 // --start-system-server : Start the system server. 215 // --application : Start in application (stand alone, non zygote) mode. 216 // --nice-name : The nice name for this process. 217 // 218 // For non zygote starts, these arguments will be followed by 219 // the main class name. All remaining arguments are passed to 220 // the main method of this class. 221 // 222 // For zygote starts, all remaining arguments are passed to the zygote. 223 // main function. 224 // 225 // Note that we must copy argument string values since we will rewrite the 226 // entire argument block when we apply the nice name to argv0. 227 // 228 // As an exception to the above rule, anything in "spaced commands" 229 // goes to the vm even though it has a space in it. 230 const char* spaced_commands[] = { "-cp", "-classpath" }; 231 // Allow "spaced commands" to be succeeded by exactly 1 argument (regardless of -s). 232 bool known_command = false; 233 234 int i; 235 for (i = 0; i < argc; i++) { 236 if (known_command == true) { 237 runtime.addOption(strdup(argv[i])); 238 ALOGV("app_process main add known option '%s'", argv[i]); 239 known_command = false; 240 continue; 241 } 242 243 for (int j = 0; 244 j < static_cast(sizeof(spaced_commands) / sizeof(spaced_commands[0])); 245 ++j) { 246 if (strcmp(argv[i], spaced_commands[j]) == 0) { 247 known_command = true; 248 ALOGV("app_process main found known command '%s'", argv[i]); 249 } 250 } 251 252 if (argv[i][0] != '-') { 253 break; 254 } 255 if (argv[i][1] == '-' && argv[i][2] == 0) { 256 ++i; // Skip --. 257 break; 258 } 259 260 runtime.addOption(strdup(argv[i])); 261 ALOGV("app_process main add option '%s'", argv[i]); 262 } 263 264 // Parse runtime arguments. Stop at first unrecognized option. 265 bool zygote = false; 266 bool startSystemServer = false; 267 bool application = false; 268 String8 niceName; 269 String8 className; 270 271 ++i; // Skip unused "parent dir" argument. 272 while (i < argc) { 273 const char* arg = argv[i++]; 274 if (strcmp(arg, "--zygote") == 0) {//检查应用程序 app_process 的启动参数arg是否包含了一个 “一zygote ” 选项。 275 zygote = true; //如果包含了 ,那么就说明这时候应用程序app_process是在Zygote进程中启动的 276 niceName = ZYGOTE_NICE_NAME; 277 } else if (strcmp(arg, "--start-system-server") == 0) { 278 startSystemServer = true; 279 } else if (strcmp(arg, "--application") == 0) { 280 application = true; 281 } else if (strncmp(arg, "--nice-name=", 12) == 0) { 282 niceName.setTo(arg + 12); 283 } else if (strncmp(arg, "--", 2) != 0) { 284 className.setTo(arg); 285 break; 286 } else { 287 --i; 288 break; 289 } 290 } 291 292 Vector args; 293 if (!className.isEmpty()) { 294 // We're not in zygote mode, the only argument we need to pass 295 // to RuntimeInit is the application argument. 296 // 297 // The Remainder of args get passed to startup class main(). Make 298 // copies of them before we overwrite them with the process name. 299 args.add(application ? String8("application") : String8("tool")); 300 runtime.setClassNameAndArgs(className, argc - i, argv + i); 301 302 if (!LOG_NDEBUG) { 303 String8 restOfArgs; 304 char* const* argv_new = argv + i; 305 int argc_new = argc - i; 306 for (int k = 0; k < argc_new; ++k) { 307 restOfArgs.append("\""); 308 restOfArgs.append(argv_new[k]); 309 restOfArgs.append("\" "); 310 } 311 ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string()); 312 } 313 } else { 314 // We're in zygote mode. 315 maybeCreateDalvikCache(); 316 317 if (startSystemServer) { 318 args.add(String8("start-system-server")); 319 } 320 321 char prop[PROP_VALUE_MAX]; 322 if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) { 323 LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.", 324 ABI_LIST_PROPERTY); 325 return 11; 326 } 327 328 String8 abiFlag("--abi-list="); 329 abiFlag.append(prop); 330 args.add(abiFlag); 331 332 // In zygote mode, pass all remaining arguments to the zygote 333 // main() method. 334 for (; i < argc; ++i) { 335 args.add(String8(argv[i])); 336 } 337 } 338 339 if (!niceName.isEmpty()) { 340 runtime.setArgv0(niceName.string(), true /* setProcName */); 341 } 342 343 if (zygote) {//AppRuntime类的成员函数start是从其父类AndroidRuntime继承下来的,接下来分析AndroidRuntime类的成员函数start的实现 344 runtime.start("com.android.internal.os.ZygoteInit", args, zygote); 345 } else if (className) { 346 runtime.start("com.android.internal.os.RuntimeInit", args, zygote); 347 } else { 348 fprintf(stderr, "Error: no class name or --zygote supplied.\n"); 349 app_usage(); 350 LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); 351 } 352}
2.AndroidRuntime.start
代码路径:/frameworks/base/core/jni/AndroidRuntime.cpp
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/jni/AndroidRuntime.cpp)
986/* 987 * Start the Android runtime. This involves starting the virtual machine 988 * and calling the "static void main(String[] args)" method in the class 989 * named by "className". 990 * 991 * Passes the main function two arguments, the class name and the specified 992 * options string. 993 */ 994void AndroidRuntime::start(const char* className, const Vector& options, bool zygote) 995{ 996 ALOGD(">>>>>> START %s uid %d <<<<<<\n", 997 className != NULL ? className : "(unknown)", getuid()); 998 999 static const String8 startSystemServer("start-system-server"); 1000 1001 /* 1002 * 'startSystemServer == true' means runtime is obsolete and not run from 1003 * init.rc anymore, so we print out the boot start event here. 1004 */ 1005 for (size_t i = 0; i < options.size(); ++i) { 1006 if (options[i] == startSystemServer) { 1007 /* track our progress through the boot sequence */ 1008 const int LOG_BOOT_PROGRESS_START = 3000; 1009 LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); 1010 } 1011 } 1012 1013 const char* rootDir = getenv("ANDROID_ROOT"); 1014 if (rootDir == NULL) { 1015 rootDir = "/system"; 1016 if (!hasDir("/system")) { 1017 LOG_FATAL("No root directory specified, and /android does not exist."); 1018 return; 1019 } 1020 setenv("ANDROID_ROOT", rootDir, 1); 1021 } 1022 1023 //const char* kernelHack = getenv("LD_ASSUME_KERNEL"); 1024 //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack); 1025 1026 /* start the virtual machine *///调用成员函数startVM在Zygote进程中创建一个虚拟机实例 1027 JniInvocation jni_invocation; 1028 jni_invocation.Init(NULL); 1029 JNIEnv* env; 1030 if (startVm(&mJavaVM, &env, zygote) != 0) { 1031 return; 1032 } 1033 onVmCreated(env); 1034 1035 /* 1036 * Register android functions. 1037 */ 1038 if (startReg(env) < 0) {//成员函数startReg在这个虚拟机实例中注册一系列JNI方法 1039 ALOGE("Unable to register all android natives\n"); 1040 return; 1041 } 1042 1043 /* 1044 * We want to call main() with a String array with arguments in it. 1045 * At present we have two arguments, the class name and an option string. 1046 * Create an array to hold them. 1047 */ 1048 jclass stringClass; 1049 jobjectArray strArray; 1050 jstring classNameStr; 1051 1052 stringClass = env->FindClass("java/lang/String"); 1053 assert(stringClass != NULL); 1054 strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL); 1055 assert(strArray != NULL); 1056 classNameStr = env->NewStringUTF(className); 1057 assert(classNameStr != NULL); 1058 env->SetObjectArrayElement(strArray, 0, classNameStr); 1059 1060 for (size_t i = 0; i < options.size(); ++i) { 1061 jstring optionsStr = env->NewStringUTF(options.itemAt(i).string()); 1062 assert(optionsStr != NULL); 1063 env->SetObjectArrayElement(strArray, i + 1, optionsStr); 1064 } 1065 1066 /* 1067 * Start VM. This thread becomes the main thread of the VM, and will 1068 * not return until the VM exits. 1069 */ 1070 char* slashClassName = toSlashClassName(className); 1071 jclass startClass = env->FindClass(slashClassName); 1072 if (startClass == NULL) { 1073 ALOGE("JavaVM unable to locate class '%s'\n", slashClassName); 1074 /* keep going */ 1075 } else { 1076 jmethodID startMeth = env->GetStaticMethodID(startClass, "main", 1077 "([Ljava/lang/String;)V"); 1078 if (startMeth == NULL) { 1079 ALOGE("JavaVM unable to find main() in '%s'\n", className); 1080 /* keep going */ 1081 } else { 1082 env->CallStaticVoidMethod(startClass, startMeth, strArray); 1083 //调用com.android.internal.os.Zygotelnit类的静态成员函数main来进一步启动Zygote进程 1084#if 0 1085 if (env->ExceptionCheck()) 1086 threadExitUncaughtException(env); 1087#endif 1088 } 1089 } 1090 free(slashClassName); 1091 1092 ALOGD("Shutting down VM\n"); 1093 if (mJavaVM->DetachCurrentThread() != JNI_OK) 1094 ALOGW("Warning: unable to detach main thread\n"); 1095 if (mJavaVM->DestroyJavaVM() != 0) 1096 ALOGW("Warning: VM did not shut down cleanly\n"); 1097}
3.ZygoteInit.main
代码路径:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
671 public static void main(String argv[]) { 672 ZygoteServer zygoteServer = new ZygoteServer(); 673 674 // Mark zygote start. This ensures that thread creation will throw 675 // an error. 676 ZygoteHooks.startZygoteNoThreadCreation(); 677 678 // Zygote goes into its own process group. 679 try { 680 Os.setpgid(0, 0); 681 } catch (ErrnoException ex) { 682 throw new RuntimeException("Failed to setpgid(0,0)", ex); 683 } 684 685 try { 686 // Report Zygote start time to tron unless it is a runtime restart 687 if (!"1".equals(SystemProperties.get("sys.boot_completed"))) { 688 MetricsLogger.histogram(null, "boot_zygote_init", 689 (int) SystemClock.elapsedRealtime()); 690 } 691 692 String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing"; 693 BootTimingsTraceLog bootTimingsTraceLog = new BootTimingsTraceLog(bootTimeTag, 694 Trace.TRACE_TAG_DALVIK); 695 bootTimingsTraceLog.traceBegin("ZygoteInit"); 696 RuntimeInit.enableDdms(); 697 // Start profiling the zygote initialization. 698 SamplingProfilerIntegration.start(); 699 700 boolean startSystemServer = false; 701 String socketName = "zygote"; 702 String abiList = null; 703 boolean enableLazyPreload = false; 704 for (int i = 1; i < argv.length; i++) { 705 if ("start-system-server".equals(argv[i])) { 706 startSystemServer = true; 707 } else if ("--enable-lazy-preload".equals(argv[i])) { 708 enableLazyPreload = true; 709 } else if (argv[i].startsWith(ABI_LIST_ARG)) { 710 abiList = argv[i].substring(ABI_LIST_ARG.length()); 711 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { 712 socketName = argv[i].substring(SOCKET_NAME_ARG.length()); 713 } else { 714 throw new RuntimeException("Unknown command line argument: " + argv[i]); 715 } 716 } 717 718 if (abiList == null) { 719 throw new RuntimeException("No ABI list supplied."); 720 } 721 //Server端Socket是用来等待Activity管理服务ActivityManagerService请求Zygote进程创建新的应用程序进程的 722 zygoteServer.registerServerSocket(socketName);//调用zygoteServer类的静态成员函数registerZygoteSocket来创建一个Server端Socket
执行preload函数来进行资源文件的预加载工作,加载类,加载资源文件,加载OPenGl,加载共享库,文本资源以及准备WebView.
723 // In some configurations, we avoid preloading resources and classes eagerly. 724 // In such cases, we will preload things prior to our first fork. 725 if (!enableLazyPreload) { 726 bootTimingsTraceLog.traceBegin("ZygotePreload"); 727 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, 728 SystemClock.uptimeMillis()); 729 preload(bootTimingsTraceLog); 730 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, 731 SystemClock.uptimeMillis()); 732 bootTimingsTraceLog.traceEnd(); // ZygotePreload 733 } else { 734 Zygote.resetNicePriority(); 735 } 736 737 // Finish profiling the zygote initialization. 738 SamplingProfilerIntegration.writeZygoteSnapshot(); 739 740 // Do an initial gc to clean up after startup 741 bootTimingsTraceLog.traceBegin("PostZygoteInitGC"); 742 gcAndFinalize(); 743 bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC 744 745 bootTimingsTraceLog.traceEnd(); // ZygoteInit 746 // Disable tracing so that forked processes do not inherit stale tracing tags from 747 // Zygote. 748 Trace.setTracingEnabled(false); 749 750 // Zygote process unmounts root storage spaces. 751 Zygote.nativeUnmountStorageOnInit(); 752 753 // Set seccomp policy 754 Seccomp.setPolicy(); 755 756 ZygoteHooks.stopZygoteNoThreadCreation(); 757 //调用Zygotelnit类的静态成员函数startSystemServer来启动System进程,以便它可以将系统的关键服务启动起来 758 if (startSystemServer) { 759 startSystemServer(abiList, socketName, zygoteServer); 760 } 761 762 Log.i(TAG, "Accepting command socket connections"); 763 zygoteServer.runSelectLoop(abiList); 764 765 zygoteServer.closeServerSocket(); 766 } catch (Zygote.MethodAndArgsCaller caller) { 767 caller.run(); 768 } catch (Throwable ex) { 769 Log.e(TAG, "System zygote died with exception", ex); 770 zygoteServer.closeServerSocket(); 771 throw ex; 772 } 773 } 774
通过参数判断是否启动systemServer,也就是通过刚刚我们记录下来的参数--start-system-server判定startSystemServer为true;接着通过调用registerZygoteSocket(socketName)函数来注册zygote套接字,进行进程间的通信
4.ZygoteInit.startSystemServer
代码路径:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
590 /** 591 * Prepare the arguments and fork for the system server process. 592 */ 593 private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) 594 throws Zygote.MethodAndArgsCaller, RuntimeException { 595 long capabilities = posixCapabilitiesAsBits( 596 OsConstants.CAP_IPC_LOCK, 597 OsConstants.CAP_KILL, 598 OsConstants.CAP_NET_ADMIN, 599 OsConstants.CAP_NET_BIND_SERVICE, 600 OsConstants.CAP_NET_BROADCAST, 601 OsConstants.CAP_NET_RAW, 602 OsConstants.CAP_SYS_MODULE, 603 OsConstants.CAP_SYS_NICE, 604 OsConstants.CAP_SYS_PTRACE, 605 OsConstants.CAP_SYS_TIME, 606 OsConstants.CAP_SYS_TTY_CONFIG, 607 OsConstants.CAP_WAKE_ALARM 608 ); 609 /* Containers run without this capability, so avoid setting it in that case */ 610 if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) { 611 capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND); 612 } 613 /* Hardcoded command line to start the system server */ 614 String args[] = { 615 "--setuid=1000", 616 "--setgid=1000", 617 "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010", 618 "--capabilities=" + capabilities + "," + capabilities, 619 "--nice-name=system_server", 620 "--runtime-args", 621 "com.android.server.SystemServer", 622 }; 623 ZygoteConnection.Arguments parsedArgs = null; 624 625 int pid; 626 627 try { 628 parsedArgs = new ZygoteConnection.Arguments(args); 629 ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); 630 ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); 631 632 /* Request to fork the system server process */ 633 pid = Zygote.forkSystemServer( 634 parsedArgs.uid, parsedArgs.gid, 635 parsedArgs.gids, 636 parsedArgs.debugFlags, 637 null, 638 parsedArgs.permittedCapabilities, 639 parsedArgs.effectiveCapabilities); 640 } catch (IllegalArgumentException ex) { 641 throw new RuntimeException(ex); 642 } 643 644 /* For child process */ 645 if (pid == 0) { 646 if (hasSecondZygote(abiList)) { 647 waitForSecondaryZygote(socketName); 648 } 649 650 zygoteServer.closeServerSocket(); 651 handleSystemServerProcess(parsedArgs); 652 } 653 654 return true; 655 }
准备系统服启动的参数,并通过forkSystemServer来创建系统服务进程,接着调用handleSystemServerProcess(parsedArgs)来进行系统服务的处理。
5.ZygoteServer.registerServerSocket
代码路径:/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java)
调用zygoteServer类的静态成员函数registerZygoteSocket来创建一个Server端Socket, Zygote进程将System进程启动起来之 后 ,就会在这个Server端Socket上等待Activity管理服务ActivityManagerService请求Zygote进程创建新的应用程序进程.
51 /** 52 * Registers a server socket for zygote command connections 53 * 54 * @throws RuntimeException when open fails 55 */ 56 void registerServerSocket(String socketName) { 57 if (mServerSocket == null) { 58 int fileDesc; 59 final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName; 60 try { 61 String env = System.getenv(fullSocketName); 62 fileDesc = Integer.parseInt(env); 63 } catch (RuntimeException ex) { 64 throw new RuntimeException(fullSocketName + " unset or invalid", ex); 65 } 66 67 try { 68 FileDescriptor fd = new FileDescriptor(); 69 fd.setInt$(fileDesc); 70 mServerSocket = new LocalServerSocket(fd); 71 } catch (IOException ex) { 72 throw new RuntimeException( 73 "Error binding to local socket '" + fileDesc + "'", ex); 74 } 75 } 76 }
6.ZygoteServer.runSelectLoop
代码路径:/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java)
运行zygote进程的选择循环。 在发生时接受新的连接,并且一次从连接读取一次产生请求的价值。
128 /** 129 * Runs the zygote process's select loop. Accepts new connections as 130 * they happen, and reads commands from connections one spawn-request's 131 * worth at a time. 132 * 133 * @throws Zygote.MethodAndArgsCaller in a child process when a main() 134 * should be executed. 135 */ 136 void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller { 137 ArrayListfds = new ArrayList (); 138 ArrayList peers = new ArrayList (); 139 140 fds.add(mServerSocket.getFileDescriptor()); 141 peers.add(null); 142 143 while (true) { 144 StructPollfd[] pollFds = new StructPollfd[fds.size()]; 145 for (int i = 0; i < pollFds.length; ++i) { 146 pollFds[i] = new StructPollfd(); 147 pollFds[i].fd = fds.get(i); 148 pollFds[i].events = (short) POLLIN; 149 } 150 try { 151 Os.poll(pollFds, -1); 152 } catch (ErrnoException ex) { 153 throw new RuntimeException("poll failed", ex); 154 } 155 for (int i = pollFds.length - 1; i >= 0; --i) { 156 if ((pollFds[i].revents & POLLIN) == 0) { 157 continue; 158 } 159 if (i == 0) { 160 ZygoteConnection newPeer = acceptCommandPeer(abiList); 161 peers.add(newPeer); 162 fds.add(newPeer.getFileDesciptor()); 163 } else { 164 boolean done = peers.get(i).runOnce(this); 165 if (done) { 166 peers.remove(i); 167 fds.remove(i); 168 } 169 } 170 } 171 } 172 }
7.ZygoteServer.closeServerSocket
代码路径:/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java)
关闭zygoteServer类的静态成员函数registerZygoteSocket创建的socket
96 /** 97 * Close and clean up zygote sockets. Called on shutdown and on the 98 * child's exit path. 99 */ 100 void closeServerSocket() { 101 try { 102 if (mServerSocket != null) { 103 FileDescriptor fd = mServerSocket.getFileDescriptor(); 104 mServerSocket.close(); 105 if (fd != null) { 106 Os.close(fd); 107 } 108 } 109 } catch (IOException ex) { 110 Log.e(TAG, "Zygote: error closing sockets", ex); 111 } catch (ErrnoException ex) { 112 Log.e(TAG, "Zygote: error closing descriptor", ex); 113 } 114 115 mServerSocket = null; 116 }
3.System启动过程
System进程是在ZygoteInit类的静态成员函数handleSystemServerProcess中开始启动的
1.ZygoteInit.handleSystemServerProcess
代码路径:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
593 private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) 594 throws Zygote.MethodAndArgsCaller, RuntimeException { .......................................................... 643 644 /* For child process */ 645 if (pid == 0) { 646 if (hasSecondZygote(abiList)) { 647 waitForSecondaryZygote(socketName); 648 } 649 650 zygoteServer.closeServerSocket(); 651 handleSystemServerProcess(parsedArgs); 652 } 653 654 return true; 655 }
446 /** 447 * Finish remaining work for the newly forked system server process. 448 */ 449 private static void handleSystemServerProcess( 450 ZygoteConnection.Arguments parsedArgs) 451 throws Zygote.MethodAndArgsCaller { 452 453 // set umask to 0077 so new files and directories will default to owner-only permissions. 454 Os.umask(S_IRWXG | S_IRWXO); 455 456 if (parsedArgs.niceName != null) { 457 Process.setArgV0(parsedArgs.niceName); 458 } 459 460 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); 461 if (systemServerClasspath != null) { 462 performSystemServerDexOpt(systemServerClasspath); 463 // Capturing profiles is only supported for debug or eng builds since selinux normally 464 // prevents it. 465 boolean profileSystemServer = SystemProperties.getBoolean( 466 "dalvik.vm.profilesystemserver", false); 467 if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) { 468 try { 469 File profileDir = Environment.getDataProfilesDePackageDirectory( 470 Process.SYSTEM_UID, "system_server"); 471 File profile = new File(profileDir, "primary.prof"); 472 profile.getParentFile().mkdirs(); 473 profile.createNewFile(); 474 String[] codePaths = systemServerClasspath.split(":"); 475 VMRuntime.registerAppInfo(profile.getPath(), codePaths); 476 } catch (Exception e) { 477 Log.wtf(TAG, "Failed to set up system server profile", e); 478 } 479 } 480 } 481 482 if (parsedArgs.invokeWith != null) { 483 String[] args = parsedArgs.remainingArgs; 484 // If we have a non-null system server class path, we'll have to duplicate the 485 // existing arguments and append the classpath to it. ART will handle the classpath 486 // correctly when we exec a new process. 487 if (systemServerClasspath != null) { 488 String[] amendedArgs = new String[args.length + 2]; 489 amendedArgs[0] = "-cp"; 490 amendedArgs[1] = systemServerClasspath; 491 System.arraycopy(args, 0, amendedArgs, 2, args.length); 492 args = amendedArgs; 493 } 494 495 WrapperInit.execApplication(parsedArgs.invokeWith, 496 parsedArgs.niceName, parsedArgs.targetSdkVersion, 497 VMRuntime.getCurrentInstructionSet(), null, args); 498 } else { 499 ClassLoader cl = null; 500 if (systemServerClasspath != null) { 501 cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion); 502 503 Thread.currentThread().setContextClassLoader(cl); 504 } 505 506 /* 507 * Pass the remaining arguments to SystemServer. 508 */ 509 ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); 510 } 511 512 /* should never reach here */ 513 }System进程不需要使用这个Socket,因此,会调用zygoteServer类的静态成员函数closeServerSocket来关闭它。由于System进程复制了Zygote进程的地址空间,因此,它就会获得Zygote进程在启动过程中所创建的Socket。接下来调用ZygoteInit.zygoteInit,在ZygoteInit.zygoteInit中RuntimeInit类的静态成员函数zygoteInit来进一步启动System进程
2.ZygoteInit.zygoteInit
代码路径:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
创建的系统服务剩余的工作,最后调用ZygoteInit.zygoteInit将剩余的参数传递到系统服务
829 public static final void zygoteInit(int targetSdkVersion, String[] argv, 830 ClassLoader classLoader) throws Zygote.MethodAndArgsCaller { 831 if (RuntimeInit.DEBUG) { 832 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote"); 833 } 834 835 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit"); 836 RuntimeInit.redirectLogStreams();//将System.out和System.err重定向到Android日志 837 838 RuntimeInit.commonInit(); 839 ZygoteInit.nativeZygoteInit(); 840 RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); 841 }
3.RuntimeInit.applicationInit
代码路径:/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java)
nativeZygoteInit()用于进程间通信的初始化操作,applicationInit函数用于服务的启动
289 protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) 290 throws Zygote.MethodAndArgsCaller { 291 // If the application calls System.exit(), terminate the process 292 // immediately without running any shutdown hooks. It is not possible to 293 // shutdown an Android application gracefully. Among other things, the 294 // Android runtime shutdown hooks close the Binder driver, which can cause 295 // leftover running threads to crash before the process actually exits. 296 nativeSetExitWithoutCleanup(true); 297 298 // We want to be fairly aggressive about heap utilization, to avoid 299 // holding on to a lot of memory that isn't needed. 300 VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); 301 VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); 302 303 final Arguments args; 304 try { 305 args = new Arguments(argv); 306 } catch (IllegalArgumentException ex) { 307 Slog.e(TAG, ex.getMessage()); 308 // let the process exit 309 return; 310 } 311 312 // The end of of the RuntimeInit event (see #zygoteInit). 313 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 314 315 // Remaining arguments are passed to the start class's static main 316 invokeStaticMain(args.startClass, args.startArgs, classLoader); 317 }
该函数主要是一些运行时的一些工作,同时调用invokeStaticMain来进行main函数的执行,看这个方法的注释,意思便是剩下的参数被传递,用于启动类的静态main函数。这里传递的类参数便是SystemServer类,所以这个函数的工作便是启动SystemServer的main函数
4.SystemServer.main
代码路径:/frameworks/base/services/java/com/android/server/SystemServer.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/java/com/android/server/SystemServer.java)该函数位于frameworks/base/services/java/com/android/server/SystemServer.java类中,这里运行SystemServer的run函数,该函数设置环境变量,启动其他服务,
257 * The main entry point from zygote.
258 */
259 public static void main(String[] args) {
260 new SystemServer().run();
261 }
接着返回到ZygoteInit.java的main函数中,这个函数最后执行runSelectLoop函数,这里运行一个循环,接收新的连接,读取来自连接的命令
参考:
http://blog.csdn.net/gaugamela/article/details/52133186
https://www.jianshu.com/p/88e3a64d3a3e