// 1.init的main方法会执行两次,由is_first_stage控制,first_stage就是第一阶段要做的事 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是用来挂载文件系统的,mount属于Linux系统调用 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 }; // 用来将list数组中所标明的组加入到目前进程的组设置中 setgroups(arraysize(groups), groups); mount("sysfs", "/sys", "sysfs", 0, NULL); mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL); //mknod用于创建Linux中的设备文件 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... //将标准输入输出重定向到"/sys/fs/selinux/null" InitKernelLogging(argv);
LOG(INFO) << "init first stage started!";
if (!DoFirstStageMount()) { LOG(ERROR) << "Failed to mount required partitions early ..."; panic(); }
// Set up SELinux, loading the SELinux policy. //加载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. // 我们执行第一遍init的main方法是在kernel domain,所以要重新执行init文件,切换到加载了selinux策略的init domain, if (restorecon("/init") == -1) { PLOG(ERROR) << "restorecon failed"; security_failure(); }
// 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(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));
// If arguments are passed both on the command line and in DT, // properties set in DT always have priority over the command-line ones. //接下来的一系列操作都是从各个文件读取一些属性,然后通过property_set设置系统属性 // 1.这句英文的大概意思是,如果参数同时从命令行和DT传过来,DT的优先级总是大于命令行的。 // 2.DT即device-tree,中文意思是设备树,这里面记录自己的硬件配置和系统运行参数,参考http://www.wowotech.net/linux_kenrel/why-dt.html process_kernel_dt();//处理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. constchar* avb_version = getenv("INIT_AVB_VERSION"); // 将avb版本设置到系统属性中 if (avb_version) property_set("ro.boot.avb_version", avb_version);
// 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) parser.DumpState();//打印一些当前Parser的信息,默认是不执行的
// Queue an action that waits for coldboot done so we know ueventd has set up all of /dev... //QueueBuiltinAction用于添加Action,第一个参数是 Action要执行的Command,第二个是Trigger 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; //epoll超时时间,相当于阻塞时间
if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) { am.ExecuteOneCommand();//执行一个command } if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) { 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. //当还有命令要执行时,将epoll_timeout_ms设置为0 if (am.HasMoreCommands()) epoll_timeout_ms = 0; }
// system\core\init\init_parser.cpp voidParser::ParseData(conststd::string& filename, conststd::string& data){ //TODO: Use a parser with const input and remove this copy std::vector<char> data_copy(data.begin(), data.end()); data_copy.push_back('\0');
# \system\core\rootdir\init.rc L680 on nonencrypted class_start main #class_start是一个命令,通过do_class_start函数处理 class_start late_start
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# system\core\init\builtins.cpp static Result<Success> do_class_start(const BuiltinArguments& args){ // Starting a class does not start services which are explicitly disabled. // They must be started individually. for (constauto& service : ServiceList::GetInstance()) { if (service->classnames().count(args[1])) { // 调用刚刚注册的service的StartIfNotDisabled()方法 if (auto result = service->StartIfNotDisabled(); !result) { LOG(ERROR) << "Could not start service '" << service->name() << "' as part of class '" << args[1] << "': " << result.error(); } } } return Success(); }
boolService::Start(){ // Starting a service removes it from the disabled or reset state and // immediately takes it out of the restarting state if it was in there. flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
// 如果service已经启动了,就不启动了 if (flags_ & SVC_RUNNING) { returnfalse; }
// See if there were "writepid" instructions to write to files under /dev/cpuset/. auto cpuset_predicate = [](conststd::string& path) { return android::base::StartsWith(path, "/dev/cpuset/"); }; auto iter = std::find_if(writepid_files_.begin(), writepid_files_.end(), cpuset_predicate); if (iter == writepid_files_.end()) { // There were no "writepid" instructions for cpusets, check if the system default // cpuset is specified to be used for the process. std::string default_cpuset = android::base::GetProperty("ro.cpuset.default", ""); if (!default_cpuset.empty()) { // Make sure the cpuset name starts and ends with '/'. // A single '/' means the 'root' cpuset. if (default_cpuset.front() != '/') { default_cpuset.insert(0, 1, '/'); } if (default_cpuset.back() != '/') { default_cpuset.push_back('/'); } writepid_files_.push_back( StringPrintf("/dev/cpuset%stasks", default_cpuset.c_str())); } } std::string pid_str = StringPrintf("%d", getpid()); for (constauto& file : writepid_files_) { if (!WriteStringToFile(pid_str, file)) { PLOG(ERROR) << "couldn't write " << pid_str << " to " << file; } }
if (ioprio_class_ != IoSchedClass_NONE) { if (android_set_ioprio(getpid(), ioprio_class_, ioprio_pri_)) { PLOG(ERROR) << "failed to set pid " << getpid() << " ioprio=" << ioprio_class_ << "," << ioprio_pri_; } }
if (needs_console) { setsid(); OpenConsole(); } else { ZapStdio(); }
// As requested, set our gid, supplemental gids, uid, context, and // priority. Aborts on failure. SetProcessAttributes();
# It is recommended to put unnecessary data/ initialization from post-fs- data # to start-zygote in device's init.rc to unblock zygote start. on zygote-start && property:ro.crypto.state=unencrypted # A/B update verifier that marks a successful boot. exec_start update_verifier_nonencrypted start netd start zygote start zygote_secondary on zygote-start && property:ro.crypto.state=unsupported # A/B update verifier that marks a successful boot. exec_start update_verifier_nonencrypted start netd start zygote start zygote_secondary on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file # A/B update verifier that marks a successful boot. exec_start update_verifier_nonencrypted start netd start zygote start zygote_secondary
无论是否启动FDE/FBE加密,都依赖zygote-start,zygote-start 是在 on late-init 中触发的。
# Mount filesystems and start core system services. on late-init trigger early-fs # Mount fstab in init.{$device}.rc by mount_all command. Optional parameter #'--early' can be specified to skip entries with 'latemount'. # /system and /vendor must be mounted by the end of the fs stage, #while /data is optional. trigger fs trigger post-fs # Mount fstab in init.{$device}.rc by mount_all with '--late' parameter # to only mount entries with 'latemount'. This is needed if'--early' is # specified in the previous mount_all command on the fs stage. # With /system mounted and properties form /system + /factory available, # some services can be started. trigger late-fs # Now we can mount /data. File encryption requires keymaster to decrypt # /data, whichin turn can only be loaded when system properties are present. trigger post-fs-data # Now we can start zygote for devices with file based encryption trigger zygote-start #zygote-start 是在on late-init 中触发的。 # Load persist properties and override properties (if enabled) from /data. trigger load_persist_props_action # Remove a file to wake up anything waiting for firmware. trigger firmware_mounts_complete trigger early-boot trigger boot
/* * '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 */ constint LOG_BOOT_PROGRESS_START = 3000; LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); } }
// 获取环境变量,确认系统根目录 constchar* 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); }
/* * Register android functions. */ // 注册jni方法,以便java层可以调用 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. */ // 创建main方法中的两个参数 jclass stringClass; jobjectArray strArray; jstring 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); jclass startClass = env->FindClass(slashClassName); if (startClass == NULL) { ALOGE("JavaVM unable to locate class '%s'\n", slashClassName); /* keep going */ } else { // 调用main()启动对应的进程,如果是zygoteinit就调用zygoteinit的main方法启动zygote 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);
/* * Now that we're running in interpreted code, call back into native code * to run the system. */ // 回调native java Runtime已经启动完毕 nativeFinishInit();
if (DEBUG) Slog.d(TAG, "Leaving RuntimeInit!"); }
1 2 3 4 5 6
// \frameworks\base\core\jni\androidRuntime.cpp nativeFinishInit() L225 /** Code written in the Java Programming Language calls here from main(). */ staticvoidcom_android_internal_os_RuntimeInit_nativeFinishInit(JNIEnv* env, jobject clazz){ // 调到要启动的进程中 gCurRuntime->onStarted(); }
publicstaticvoidmain(String argv[]){ // 创建一个LocalServerSocket,等待AMS发起fork子进程通知 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) { thrownew RuntimeException("Failed to setpgid(0,0)", ex); }
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()); }
if (abiList == null) { thrownew RuntimeException("No ABI list supplied."); }
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. // 如果没有懒加载,就加载class和资源 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(); }
// Finish profiling the zygote initialization. SamplingProfilerIntegration.writeZygoteSnapshot();
// Do an initial gc to clean up after startup bootTimingsTraceLog.traceBegin("PostZygoteInitGC"); //主动进行一次资源GC gcAndFinalize(); bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
bootTimingsTraceLog.traceEnd(); // ZygoteInit // Disable tracing so that forked processes do not inherit stale tracing tags from // Zygote. Trace.setTracingEnabled(false);
// Zygote process unmounts root storage spaces. Zygote.nativeUnmountStorageOnInit();
// Set seccomp policy Seccomp.setPolicy();
ZygoteHooks.stopZygoteNoThreadCreation();
if (startSystemServer) { // 启动systemserver startSystemServer(abiList, socketName, zygoteServer); }
try { BufferedReader br = new BufferedReader(new InputStreamReader(is), 256); // 一下代码解析并且加载类 int count = 0; String line; while ((line = br.readLine()) != null) { // Skip comments and blank lines. line = line.trim(); if (line.startsWith("#") || line.equals("")) { continue; }
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line); try { if (false) { Log.v(TAG, "Preloading " + line + "..."); } // Load and explicitly initialize the given class. Use // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups // (to derive the caller's class-loader). Use true to force initialization, and // null for the boot classpath class-loader (could as well cache the // class-loader of this class in a variable). // null代表使用Bootstrap ClassLoader最高级引导类加载器加载,加载后的类保存在该类加载器中。之后的类加载都会依托双亲委托机制,不重复加载相同的类。 Class.forName(line, true, null); count++; } catch (ClassNotFoundException e) { ...... }
4.3.1.2 preloadResources();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
privatestaticvoidpreloadResources(){ final VMRuntime runtime = VMRuntime.getRuntime(); try { mResources = Resources.getSystem(); mResources.startPreloading(); if (PRELOAD_RESOURCES) { Log.i(TAG, "Preloading resources...");
long startTime = SystemClock.uptimeMillis(); TypedArray ar = mResources.obtainTypedArray( com.android.internal.R.array.preloaded_drawables); // 更具索引id加载图片资源 int N = preloadDrawables(ar); ar.recycle(); ...... }
// 需要支持的语言 for (int i = 0; i < AVAILABLE_LANGUAGES.length; i++) { HyphenationData data = AVAILABLE_LANGUAGES[i]; // 加载对应语言的字体 Hyphenator h = loadHyphenator(data); if (h != null) { sMap.put(Locale.forLanguageTag(data.mLanguageTag), h); } }
for (int i = 0; i < LOCALE_FALLBACK_DATA.length; i++) { String language = LOCALE_FALLBACK_DATA[i][0]; String fallback = LOCALE_FALLBACK_DATA[i][1]; // 解析后的语言保存到map中 sMap.put(Locale.forLanguageTag(language), sMap.get(Locale.forLanguageTag(fallback))); } }
1 2 3 4 5 6 7 8 9 10 11 12 13
privatestaticfinal HyphenationData[] AVAILABLE_LANGUAGES = { new HyphenationData("as", INDIC_MIN_PREFIX, INDIC_MIN_SUFFIX), // Assamese new HyphenationData("bg", 2, 2), // Bulgarian new HyphenationData("bn", INDIC_MIN_PREFIX, INDIC_MIN_SUFFIX), // Bengali new HyphenationData("cu", 1, 2), // Church Slavonic ...... new HyphenationData("pt", 2, 3), // Portuguese new HyphenationData("sl", 2, 2), // Slovenian new HyphenationData("ta", INDIC_MIN_PREFIX, INDIC_MIN_SUFFIX), // Tamil new HyphenationData("te", INDIC_MIN_PREFIX, INDIC_MIN_SUFFIX), // Telugu new HyphenationData("tk", 2, 2), // Turkmen new HyphenationData("und-Ethi", 1, 1), // Any language in Ethiopic script };
...... // 如果systemserver类已经被加载了,命中if;否则创建类加载器并且启动参数传给systemserver进程,首次我们分析SystemServer没有被夹在的情况 if (parsedArgs.invokeWith != null) { String[] args = parsedArgs.remainingArgs; // If we have a non-null system server class path, we'll have to duplicate the // existing arguments and append the classpath to it. ART will handle the classpath // correctly when we exec a new process. if (systemServerClasspath != null) { String[] amendedArgs = new String[args.length + 2]; amendedArgs[0] = "-cp"; amendedArgs[1] = systemServerClasspath; System.arraycopy(args, 0, amendedArgs, 2, args.length); args = amendedArgs; }
// should never get here, the child is expected to either // throw Zygote.MethodAndArgsCaller or exec(). returntrue; } else { // in parent...pid of < 0 means failure IoUtils.closeQuietly(childPipeFd); childPipeFd = null; return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs); } } finally { IoUtils.closeQuietly(childPipeFd); IoUtils.closeQuietly(serverPipeFd); } }
// frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java privatevoidhandleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr) throws Zygote.MethodAndArgsCaller { /** * By the time we get here, the native code has closed the two actual Zygote * socket connections, and substituted /dev/null in their place. The LocalSocket * objects still need to be closed properly. */
// 关闭客户端socket closeSocket(); ......
if (parsedArgs.niceName != null) { Process.setArgV0(parsedArgs.niceName); }
// End of the postFork event. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); if (parsedArgs.invokeWith != null) { WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, VMRuntime.getCurrentInstructionSet(), pipeFd, parsedArgs.remainingArgs); } else { // 通过zygote进程启动的进程,在此方法中调用待启动进程的main方法 ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null/* classLoader */); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// frameworks\base\core\java\com\android\internal\os\ZygoteInit.java publicstaticfinalvoidzygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)throws Zygote.MethodAndArgsCaller { if (RuntimeInit.DEBUG) { Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote"); }
// frameworks\base\core\java\com\android\internal\os\RuntimeInit.java protectedstaticvoidapplicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)throws Zygote.MethodAndArgsCaller { // If the application calls System.exit(), terminate the process // immediately without running any shutdown hooks. It is not possible to // shutdown an Android application gracefully. Among other things, the // Android runtime shutdown hooks close the Binder driver, which can cause // leftover running threads to crash before the process actually exits. nativeSetExitWithoutCleanup(true);
// We want to be fairly aggressive about heap utilization, to avoid // holding on to a lot of memory that isn't needed. // 让带启动的进程堆大小最大只能占0.75 * 最大堆内存 VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args; try { args = new Arguments(argv); } catch (IllegalArgumentException ex) { Slog.e(TAG, ex.getMessage()); // let the process exit return; }
// The end of of the RuntimeInit event (see #zygoteInit). Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// Remaining arguments are passed to the start class's static main // 反射得到待执行的类和得到其中的main(),最终通过抛异常的方式,回到zygoteInit的main方法中 invokeStaticMain(args.startClass, args.startArgs, classLoader); }
try { cl = Class.forName(className, true, classLoader); } catch (ClassNotFoundException ex) { thrownew RuntimeException( "Missing class when invoking static main " + className, ex); }
Method m; try { m = cl.getMethod("main", new Class[] { String[].class }); } catch (NoSuchMethodException ex) { thrownew RuntimeException( "Missing static main on " + className, ex); } catch (SecurityException ex) { thrownew RuntimeException( "Problem getting static main on " + className, ex); }
int modifiers = m.getModifiers(); if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { thrownew RuntimeException( "Main method is not public and static on " + className); }
/* * This throw gets caught in ZygoteInit.main(), which responds * by invoking the exception's run() method. This arrangement * clears up all the stack frames that were required in setting * up the process. */ thrownew Zygote.MethodAndArgsCaller(m, argv); }
privatevoidrun(){ try { traceBeginAndSlog("InitBeforeStartServices"); // If a device's clock is before 1970 (before 0), a lot of // APIs crash dealing with negative numbers, notably // java.io.File#setLastModified, so instead we fake it and // hope that time from cell towers or NTP fixes it shortly. // 初始化系统时间 if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { Slog.w(TAG, "System clock is before 1970; setting to 1970."); SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); }
// // Default the timezone property to GMT if not set. // // 设置时区 String timezoneProperty = SystemProperties.get("persist.sys.timezone"); if (timezoneProperty == null || timezoneProperty.isEmpty()) { Slog.w(TAG, "Timezone not set; setting to GMT."); SystemProperties.set("persist.sys.timezone", "GMT"); }
// If the system has "persist.sys.language" and friends set, replace them with // "persist.sys.locale". Note that the default locale at this point is calculated // using the "-Duser.locale" command line flag. That flag is usually populated by // AndroidRuntime using the same set of system properties, but only the system_server // and system apps are allowed to set them. // // NOTE: Most changes made here will need an equivalent change to // core/jni/AndroidRuntime.cpp // 设置语言 if (!SystemProperties.get("persist.sys.language").isEmpty()) { final String languageTag = Locale.getDefault().toLanguageTag();
// The system server should never make non-oneway calls Binder.setWarnOnBlocking(true);
// Here we go! Slog.i(TAG, "Entered the Android system server!"); int uptimeMillis = (int) SystemClock.elapsedRealtime(); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis); if (!mRuntimeRestart) { MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis); }
// In case the runtime switched since last boot (such as when // the old runtime was removed in an OTA), set the system // property so that it is in sync. We can | xq oqi't do this in // libnativehelper's JniInvocation::Init code where we already // had to fallback to a different runtime because it is // running as root and we need to be the system user to set // the property. http://b/11463182 SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
// Enable the sampling profiler. if (SamplingProfilerIntegration.isEnabled()) { SamplingProfilerIntegration.start(); mProfilerSnapshotTimer = new Timer(); mProfilerSnapshotTimer.schedule(new TimerTask() { @Override publicvoidrun(){ SamplingProfilerIntegration.writeSnapshot("system_server", null); } }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL); }
// Mmmmmm... more memory! VMRuntime.getRuntime().clearGrowthLimit();
// The system server has to run all of the time, so it needs to be // as efficient as possible with its memory usage. VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
// Some devices rely on runtime fingerprint generation, so make sure // we've defined it before booting further. Build.ensureFingerprintProperty();
// Within the system server, it is an error to access Environment paths without // explicitly specifying a user. Environment.setUserRequired(true);
// Within the system server, any incoming Bundles should be defused // to avoid throwing BadParcelableException. BaseBundle.setShouldDefuse(true);
// Ensure binder calls into the system always run at foreground priority. BinderInternal.disableBackgroundScheduling(true);
// Increase the number of binder threads in system_server BinderInternal.setMaxThreads(sMaxBinderThreads);
// Prepare the main looper thread (this thread). android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false); Looper.prepareMainLooper();
// Check whether we failed to shut down last time we tried. // This call may not return. performPendingShutdown();
//=======以上方法就是初始化系统的一些环境,看方法名都知道干了什么==== //=======以下开始实际干活了===================================== // Initialize the system context. // 创建系统句柄,有了该句柄后面的服务才能拿到系统资源 createSystemContext();
// Create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // Prepare the thread pool for init tasks that can be parallelized SystemServerInitThreadPool.get(); } finally { traceEnd(); // InitBeforeStartServices }
// For debug builds, log event loop stalls to dropbox for analysis. if (StrictMode.conditionallyEnableDebugLogging()) { Slog.i(TAG, "Enabled StrictMode for system server main thread."); } if (!mRuntimeRestart && !isFirstBootOrUpgrade()) { int uptimeMillis = (int) SystemClock.elapsedRealtime(); MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis); finalint MAX_UPTIME_MILLIS = 60 * 1000; if (uptimeMillis > MAX_UPTIME_MILLIS) { Slog.wtf(SYSTEM_SERVER_TIMING_TAG, "SystemServer init took too long. uptimeMillis=" + uptimeMillis); } }
// frameworks\base\core\java\android\app\ActivityThread.java publicstatic ActivityThread systemMain(){ // The system process on low-memory devices do not get to use hardware // accelerated drawing, since this can add too much overhead to the // process. if (!ActivityManager.isHighEndGfx()) { ThreadedRenderer.disable(true); } else { ThreadedRenderer.enableForegroundTrimming(); } // 创建ActivityThread,在ActivityThread中其实就是去获取ResourcesManager,不在赘述。 ActivityThread thread = new ActivityThread(); // 此处就体现了SystemServer的ActivityThread和应用的ActivityThread不同之处。 // 系统的attch传入的是true, 而应用的是传入的false thread.attach(true); return thread; }
// Wait for installd to finish starting up so that it has a chance to // create critical directories such as /data/user with the appropriate // permissions. We need this to complete before we initialize other services. traceBeginAndSlog("StartInstaller"); // 安装器 Installer installer = mSystemServiceManager.startService(Installer.class); traceEnd();
// In some cases after launching an app we need to access device identifiers, // therefore register the device identifier policy before the activity manager. traceBeginAndSlog("DeviceIdentifiersPolicyService"); mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class); traceEnd();
// Power manager needs to be started early because other services need it. // Native daemons may be watching for it to be registered so it must be ready // to handle incoming binder calls immediately (including being able to verify // the permissions for those calls). traceBeginAndSlog("StartPowerManager"); // 启动PMS mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); traceEnd();
// Now that the power manager has been started, let the activity manager // initialize power management features. traceBeginAndSlog("InitPowerManagement"); mActivityManagerService.initPowerManagement(); traceEnd();
// Bring up recovery system in case a rescue party needs a reboot if (!SystemProperties.getBoolean("config.disable_noncore", false)) { traceBeginAndSlog("StartRecoverySystemService"); mSystemServiceManager.startService(RecoverySystemService.class); traceEnd(); }
// Now that we have the bare essentials of the OS up and running, take // note that we just booted, which might send out a rescue party if // we're stuck in a runtime restart loop. RescueParty.noteBoot(mSystemContext);
// Manages LEDs and display backlight so we need it to bring up the display. traceBeginAndSlog("StartLightsService"); mSystemServiceManager.startService(LightsService.class); traceEnd();
// Display manager is needed to provide display metrics before package manager // starts up. traceBeginAndSlog("StartDisplayManager"); // 显示服务 mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); traceEnd();
// We need the default display before we can initialize the package manager. traceBeginAndSlog("WaitForDisplay"); // 等待显示阶段 mSystemServiceManager.startBootPhase(SystemService. PHASE_WAIT_FOR_DEFAULT_DISPLAY); traceEnd();
// Only run "core" apps if we're encrypting the device. String cryptState = SystemProperties.get("vold.decrypt"); if (ENCRYPTING_STATE.equals(cryptState)) { Slog.w(TAG, "Detected encryption in progress - only parsing core apps"); mOnlyCore = true; } elseif (ENCRYPTED_STATE.equals(cryptState)) { Slog.w(TAG, "Device encrypted - only parsing core apps"); mOnlyCore = true; }
// Start the package manager. if (!mRuntimeRestart) { MetricsLogger.histogram(null, "boot_package_manager_init_start", (int) SystemClock.elapsedRealtime()); } traceBeginAndSlog("StartPackageManagerService"); // 启动PKMS mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); traceEnd(); if (!mRuntimeRestart && !isFirstBootOrUpgrade()) { MetricsLogger.histogram(null, "boot_package_manager_init_ready", (int) SystemClock.elapsedRealtime()); } // Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename // A/B artifacts after boot, before anything else might touch/need them. // Note: this isn't needed during decryption (we don't have /data anyways). if (!mOnlyCore) { boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt", false); if (!disableOtaDexopt) { traceBeginAndSlog("StartOtaDexOptService"); try { OtaDexoptService.main(mSystemContext, mPackageManagerService); } catch (Throwable e) { reportWtf("starting OtaDexOptService", e); } finally { traceEnd(); } } }
// Initialize attribute cache used to cache resources from packages. traceBeginAndSlog("InitAttributerCache"); AttributeCache.init(mSystemContext); traceEnd();
// Set up the Application instance for the system process and get started. traceBeginAndSlog("SetSystemProcess"); //启动AMS系统进程的应用实例 mActivityManagerService.setSystemProcess(); traceEnd();
// DisplayManagerService needs to setup android.display scheduling related policies // since setSystemProcess() would have overridden policies due to setProcessGroup mDisplayManagerService.setupSchedulerPolicies();
// The sensor service needs access to package manager service, app ops // service, and permissions service, therefore we start it after them. // Start sensor service in a separate thread. Completion should be checked // before using it. mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> { BootTimingsTraceLog traceLog = new BootTimingsTraceLog( SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER); traceLog.traceBegin(START_SENSOR_SERVICE); startSensorService(); traceLog.traceEnd(); }, START_SENSOR_SERVICE); }
privatevoidstartCoreServices(){ // Records errors and logs, for example wtf() traceBeginAndSlog("StartDropBoxManager"); mSystemServiceManager.startService(DropBoxManagerService.class); traceEnd();
traceBeginAndSlog("StartBatteryService"); // Tracks the battery level. Requires LightService. mSystemServiceManager.startService(BatteryService.class); traceEnd();
// Tracks whether the updatable WebView is in a ready state and watches for update installs. traceBeginAndSlog("StartWebViewUpdateService"); mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class); traceEnd(); }
// No dependency on Webview preparation in system server. But this should // be completed before allowring 3rd party final String WEBVIEW_PREPARATION = "WebViewFactoryPreparation"; Future<?> webviewPrep = null; if (!mOnlyCore) { webviewPrep = SystemServerInitThreadPool.get().submit(() -> { Slog.i(TAG, WEBVIEW_PREPARATION); BootTimingsTraceLog traceLog = new BootTimingsTraceLog( SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER); traceLog.traceBegin(WEBVIEW_PREPARATION); ConcurrentUtils.waitForFutureNoInterrupt(mZygotePreload, "Zygote preload"); mZygotePreload = null; mWebViewUpdateService.prepareWebViewInSystemServer(); traceLog.traceEnd(); }, WEBVIEW_PREPARATION); }
// frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java publicvoidsystemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog){ traceLog.traceBegin("PhaseActivityManagerReady"); synchronized(this) { // 由于goingCallback中还有服务没有回调systemReady,所以此处为false,继续往下走。 if (mSystemReady) { // If we're done calling all the receivers, run the next "boot phase" passed in by the SystemServer if (goingCallback != null) { goingCallback.run(); } return; }
// 回调systemserver中的run(),通知其他服务SystemReady() if (goingCallback != null) goingCallback.run(); ......
synchronized (this) { // Only start up encryption-aware persistent apps; once user is // unlocked we'll come back around and start unaware apps // 启动Manifest中配置了Persistent属性的App startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);