Android系统(Ver2.2)初始启动到SurfaceFlinger启动过程详细分析!
SurfaceFlinger启动先从Zygote分析开始,Zygote进程服务创建以前是Linux系统初始化过程,Zygote进程服务创建以后是Android系统开始初始化过程。
一。Zygote进程服务的产生
1. init进程服务的产生
Zygote进程服务的产生还是从init进程开始。
Android系统在启动时首先会启动Linux系统,引导加载Linux Kernel并启动init进程。Init进程是一个由内核启动的用户级进程,是Android系统的第一个进程。该进程的相关代码在./android-2.2/system/core/init/init.c。在main函数中,有如下代码:
- /* We must have some place other than / to create the
- * device nodes for kmsg and null, otherwise we won't
- * be able to remount / read-only later on.
- * Now that tmpfs is mounted on /dev, we can actually
- * talk to the outside world.
- */
- open_devnull_stdio();
- log_init();
-
- INFO("reading config file\n");
- init_parse_config_file("/init.rc");
- /* pull the kernel commandline and ramdisk properties file in */
- import_kernel_cmdline(0);
- get_hardware_name(hardware, &revision);
- snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
- init_parse_config_file(tmp);
这里会加载解析init.rc和init.hardware.rc两个初始化脚本。*.rc文件定义了在init进程中需要启动哪些进程服务和执行哪些动作。其详细说明参见./android-2.2/system/core/init/readme.txt。
其中init_parse_config_file("init.rc")函数调入了init.rc配置文件:
- service servicemanager /system/bin/servicemanager
- user system
- critical
- onrestart restart zygote
- onrestart restart media
- service vold /system/bin/vold
- socket vold stream 0660 root mount
- ioprio be 2
- service netd /system/bin/netd
- socket netd stream 0660 root system
- socket dnsproxyd stream 0660 root inet
- service debuggerd /system/bin/debuggerd
- service ril-daemon /system/bin/rild
- socket rild stream 660 root radio
- socket rild-debug stream 660 radio system
- user root
- group radio cache inet misc audio sdcard_rw
- service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
- socket zygote stream 666
- onrestart write /sys/android_power/request_state wake
- onrestart write /sys/power/state on
- onrestart restart media
- onrestart restart netd
- service drm /system/bin/drmserver
- user drm
- group system root inet
其中实现解析init.rc配置文件的过程详细见./android-2.2/system/core/init/parser.c文件,解析所得服务添加到service_list中,动作添加到action_list中。
在./android-2.2/system/core/init/init.c初始化文件中的main函数中,最后的一段初始化阶段代码进入主进程循环:
- for(;;) {
- int nr, i, timeout = -1;
- execute_one_command();
- restart_processes();
-
- .
- .
- .
- }
其中, execute_one_command()函数执行所有在queue_list列表里的action,restart_processes()函数运行重起service_list里的服务所有进程。其中包括ServiceManager进程、Zygote进程。
2. ServiceManager进程服务的产生
ServiceManager进程是所有服务的管理器。
在./android-2.2/system/core/rootdir/init.rc中对ServiceManager的描述为:
- service servicemanager /system/bin/servicemanager
- user system
- critical
- onrestart restart zygote
- onrestart restart media
其中,servicemanager服务进程由init启动,“user system”字段表明启动用户为系统用户;“critical”字段表明这是一个设备关键服务 (device-critical service) . 如果它在 4 分钟内退出超过 4 次, 设备将重启并进入恢复模式;“onrestart”字段表明当服务重启时执行一个命令,包括zygote的命令和media的命令。
而解析这段servicemanager配置文件的程序为./android-2.2/frameworks/base/cmds/servicemanager/service_manager.c源码,它实现了servicemanager服务进程的启动,其中main函数有如下代码:
- int main(int argc, char **argv)
- {
- struct binder_state *bs;
- void *svcmgr = BINDER_SERVICE_MANAGER;
- bs = binder_open(128*1024);
- if (binder_become_context_manager(bs)) {
- LOGE("cannot become context manager (%s)\n", strerror(errno));
- return -1;
- }
- svcmgr_handle = svcmgr;
- binder_loop(bs, svcmgr_handler);
- return 0;
- }
首先,调用binder_open()打开Binder设备(/dev/binder),调用binder_become_context_manager()把当前进程设置为ServiceManager。ServiceManager本身就是一个服务。
其中,binder_become_context_manager()函数在./android-2.2/frameworks/base/cmds/servicemanager/binder.c中实现:
- int binder_become_context_manager(struct binder_state *bs)
- {
- return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
- }
最后binder_loop()进入循环状态,并设置svcmgr_handler回调函数等待添加、查询、获取服务等请求。
3. Zygote进程服务的产生
Zygote进程用于产生Android系统其他进程。
在./android-2.2/system/core/rootdir/init.rc中对Zygote的描述为:
- service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
- socket zygote stream 666
- onrestart write /sys/android_power/request_state wake
- onrestart write /sys/power/state on
- onrestart restart media
- onrestart restart netd
其中,“socket zygote stream 666”字段表明创建一个名为 /dev/socket/zygote 的 unix domin socket ,并传送它的 fd 到已启动的进程,为stream流类型",用户和组默认为 0;“onrestart write /sys/android_power/request_state wake”字段表明Android系统电源状态唤醒被写入/sys/android_power/request_state文件;“onrestart write /sys/power/state on”字段表明系统电源状态被开启。
而解析这段zygote配置文件的程序为./android-2.2/frameworks/base/cmds/app_process/app_main.cpp源码,它实现了zygote服务进程的启动,其中main函数有如下代码:
- int main(int argc, const char* const argv[])
- {
- // These are global variables in ProcessState.cpp
- mArgC = argc;
- mArgV = argv;
-
- mArgLen = 0;
- for (int i=0; i<argc; i++) {
- mArgLen += strlen(argv[i]) + 1;
- }
- mArgLen--;
- AppRuntime runtime;
- const char *arg;
- const char *argv0;
- argv0 = argv[0];
- // Process command line arguments
- // ignore argv[0]
- argc--;
- argv++;
- // Everything up to '--' or first non '-' arg goes to the vm
-
- int i = runtime.addVmArguments(argc, argv);
- // Next arg is parent directory
- if (i < argc) {
- runtime.mParentDir = argv[i++];
- }
- // Next arg is startup classname or "--zygote"
- if (i < argc) {
- arg = argv[i++];
- if (0 == strcmp("--zygote", arg)) {
- bool startSystemServer = (i < argc) ?
- strcmp(argv[i], "--start-system-server") == 0 : false;
- setArgv0(argv0, "zygote");
- set_process_name("zygote");
- runtime.start("com.android.internal.os.ZygoteInit",
- startSystemServer);
- } else {
- set_process_name(argv0);
- runtime.mClassName = arg;
- // Remainder of args get passed to startup class main()
- runtime.mArgC = argc-i;
- runtime.mArgV = argv+i;
- LOGV("App process is starting with pid=%d, class=%s.\n",
- getpid(), runtime.getClassName());
- runtime.start();
- }
- } else {
- LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
- fprintf(stderr, "Error: no class name or --zygote supplied.\n");
- app_usage();
- return 10;
- }
- }
首先,创建AppRuntime的一个对象runtime,既AppRuntim类继承于AndroidRuntime,既建立了一个Dalvik虚拟机。从runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);语句,通过runtime对象传递com.android.internal.os.ZygoteInit参数,从而由Dalvik虚拟机运行./android-2.2/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中的main函数,开始创建Zygote进程。在其main()中,如下所示:
- public static void main(String argv[]) {
- try {
- VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);
- // Start profiling the zygote initialization.
- SamplingProfilerIntegration.start();
- registerZygoteSocket();
- EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
- SystemClock.uptimeMillis());
- preloadClasses();
- //cacheRegisterMaps();
- preloadResources();
- EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
- SystemClock.uptimeMillis());
- // Finish profiling the zygote initialization.
- SamplingProfilerIntegration.writeZygoteSnapshot();
- // Do an initial gc to clean up after startup
- gc();
- // If requested, start system server directly from Zygote
- if (argv.length != 2) {
- throw new RuntimeException(argv[0] + USAGE_STRING);
- }
- if (argv[1].equals("true")) {
- startSystemServer();
- } else if (!argv[1].equals("false")) {
- throw new RuntimeException(argv[0] + USAGE_STRING);
- }
- Log.i(TAG, "Accepting command socket connections");
- if (ZYGOTE_FORK_MODE) {
- runForkMode();
- } else {
- runSelectLoopMode();
- }
- closeServerSocket();
- } catch (MethodAndArgsCaller caller) {
- caller.run();
- } catch (RuntimeException ex) {
- Log.e(TAG, "Zygote died with exception", ex);
- closeServerSocket();
- throw ex;
- }
- }
首先通过registerZygoteSocket()登记端口,接着preloadClasses()装载相关类。这里大概要装载1000多个类,具体装载类见./android-2.2/frameworks/base/preloaded-classes文件。此文件由./android-2.2/frameworks/base/tools/preload/WritePreloadedClassFile.java产生。分析下该类的main函数:
- public static void main(String[] args) throws IOException,
- ClassNotFoundException {
- if (args.length != 1) {
- System.err.println("Usage: WritePreloadedClassFile [compiled log]");
- System.exit(-1);
- }
- String rootFile = args[0];
- Root root = Root.fromFile(rootFile);
- // No classes are preloaded to start.
- for (LoadedClass loadedClass : root.loadedClasses.values()) {
- loadedClass.preloaded = false;
- }
- // Open preloaded-classes file for output.
- Writer out = new BufferedWriter(new OutputStreamWriter(
- new FileOutputStream(Policy.PRELOADED_CLASS_FILE),
- Charset.forName("US-ASCII")));
- out.write("# Classes which are preloaded by"
- + " com.android.internal.os.ZygoteInit.\n");
- out.write("# Automatically generated by frameworks/base/tools/preload/"
- + WritePreloadedClassFile.class.getSimpleName() + ".java.\n");
- out.write("# MIN_LOAD_TIME_MICROS=" + MIN_LOAD_TIME_MICROS + "\n");
- out.write("# MIN_PROCESSES=" + MIN_PROCESSES + "\n");
- /*
- * The set of classes to preload. We preload a class if:
- *
- * a) it's loaded in the bootclasspath (i.e., is a system class)
- * b) it takes > MIN_LOAD_TIME_MICROS us to load, and
- * c) it's loaded by more than one process, or it's loaded by an
- * application (i.e., not a long running service)
- */
- Set<LoadedClass> toPreload = new TreeSet<LoadedClass>();
- // Preload classes that were loaded by at least 2 processes. Hopefully,
- // the memory associated with these classes will be shared.
- for (LoadedClass loadedClass : root.loadedClasses.values()) {
- Set<String> names = loadedClass.processNames();
- if (!Policy.isPreloadable(loadedClass)) {
- continue;
- }
- if (names.size() >= MIN_PROCESSES ||
- (loadedClass.medianTimeMicros() > MIN_LOAD_TIME_MICROS && names.size() > 1)) {
- toPreload.add(loadedClass);
- }
- }
- int initialSize = toPreload.size();
- System.out.println(initialSize
- + " classses were loaded by more than one app.");
- // Preload eligable classes from applications (not long-running
- // services).
- for (Proc proc : root.processes.values()) {
- if (proc.fromZygote() && !Policy.isService(proc.name)) {
- for (Operation operation : proc.operations) {
- LoadedClass loadedClass = operation.loadedClass;
- if (shouldPreload(loadedClass)) {
- toPreload.add(loadedClass);
- }
- }
- }
- }
- System.out.println("Added " + (toPreload.size() - initialSize)
- + " more to speed up applications.");
- System.out.println(toPreload.size()
- + " total classes will be preloaded.");
- // Make classes that were implicitly loaded by the zygote explicit.
- // This adds minimal overhead but avoid confusion about classes not
- // appearing in the list.
- addAllClassesFrom("zygote", root, toPreload);
- for (LoadedClass loadedClass : toPreload) {
- out.write(loadedClass.name + "\n");
- }
- out.close();
- // Update data to reflect LoadedClass.preloaded changes.
- for (LoadedClass loadedClass : toPreload) {
- loadedClass.preloaded = true;
- }
- root.toFile(rootFile);
- }
其中MIN_LOAD_TIME_MICROS等于1250,当类的装载时间大于1.25ms,则需要预装载。而Policy.isPreloadable()定义在./android-2.2/frameworks/base/tools/preload/Policy.java文件中如下:
- /**Reports if the given class should be preloaded. */
- public static boolean isPreloadable(LoadedClass clazz) {
- return clazz.systemClass && !EXCLUDED_CLASSES.contains(clazz.name);
- }
其中EXCLUDED_CLASSES在./android-2.2/frameworks/base/tools/preload/Policy.java文件中如下定义:
- /**
- * Classes which we shouldn't load from the Zygote.
- */
- private static final Set<String> EXCLUDED_CLASSES
- = new HashSet<String>(Arrays.asList(
- // Binders
- "android.app.AlarmManager",
- "android.app.SearchManager",
- "android.os.FileObserver",
- "com.android.server.PackageManagerService$AppDirObserver",
- // Threads
- "android.os.AsyncTask",
- "android.pim.ContactsAsyncHelper",
- "java.lang.ProcessManager"
- ));
这几个Binders和Thread是不会被预加载的。
另外,在./android-2.2/frameworks/base/tools/preload/WritePreloadedClassFile.java文件中还有一些application需要装载,要求满足条件proc.fromZygote()且不是属于常驻内存的服务Policy.isService(proc.name)。isService(String processName)定义在./android-2.2/frameworks/base/tools/preload/Policy.java文件中如下:
- /**
- * Returns true if the given process name is a "long running" process or
- * service.
- */
- public static boolean isService(String processName) {
- return SERVICES.contains(processName);
- }
其中的SERVICES在./android-2.2/frameworks/base/tools/preload/Policy.java文件中如下定义:
- /**
- * Long running services. These are restricted in their contribution to the
- * preloader because their launch time is less critical.
- */
- // TODO: Generate this automatically from package manager.
- private static final Set<String> SERVICES = new HashSet<String>(Arrays.asList(
- "system_server",
- "com.google.process.content",
- "android.process.media",
- "com.android.bluetooth",
- "com.android.calendar",
- "com.android.inputmethod.latin",
- "com.android.phone",
- "com.google.android.apps.maps.FriendService", // pre froyo
- "com.google.android.apps.maps:FriendService", // froyo
- "com.google.android.apps.maps.LocationFriendService",
- "com.google.android.deskclock",
- "com.google.process.gapps",
- "android.tts"
- ));
preloaded-classes是在下载源码的时候生成,WritePreloadedClassFile类并没有被用到,但可以通过这个类了解Android系统对预加载类的默认要求,参考修改preloaded-classes文件,减少开机初始化时要预加载的类,提高开机速度。
在./android-2.2/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中的main函数中:
- if (argv[1].equals("true")) {
- startSystemServer();
- } else if (!argv[1].equals("false")) {
- throw new RuntimeException(argv[0] + USAGE_STRING);
- }
最后来通过startSystemServer()启动SystemServer进程。其定义在./android-2.2/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:
- /**
- * Prepare the arguments and fork for the system server process.
- */
- private static boolean startSystemServer()
- throws MethodAndArgsCaller, RuntimeException {
- /* Hardcoded command line to start the system server */
- String args[] = {
- "--setuid=1000",
- "--setgid=1000",
- "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
- "--capabilities=130104352,130104352",
- "--runtime-init",
- "--nice-name=system_server",
- "com.android.server.SystemServer",
- };
- ZygoteConnection.Arguments parsedArgs = null;
- int pid;
- try {
- parsedArgs = new ZygoteConnection.Arguments(args);
- /*
- * Enable debugging of the system process if *either* the command line flags
- * indicate it should be debuggable or the ro.debuggable system property
- * is set to "1"
- */
- int debugFlags = parsedArgs.debugFlags;
- if ("1".equals(SystemProperties.get("ro.debuggable")))
- debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
- /* Request to fork the system server process */
- pid = Zygote.forkSystemServer(
- parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, debugFlags, null,
- parsedArgs.permittedCapabilities,
- parsedArgs.effectiveCapabilities);
- } catch (IllegalArgumentException ex) {
- throw new RuntimeException(ex);
- }
- /* For child process */
- if (pid == 0) {
- handleSystemServerProcess(parsedArgs);
- }
- return true;
- }
Zygote包装了Linux的fork。Zygote.forkSystemServer()调用forkAndSpecialize(),文件./android-2.2/dalvik/libcore/dalvik/src/main/java/dalvik/system/Zygote.java定义了forkAndSpecialize()函数:
- /**
- * Forks a new VM instance.
- * @deprecated use {@link Zygote#forkAndSpecialize(int, int, int[], int, int[][])}
- */
- @Deprecated
- public static int forkAndSpecialize(int uid, int gid, int[] gids,
- boolean enableDebugger, int[][] rlimits) {
- int debugFlags = enableDebugger ? DEBUG_ENABLE_DEBUGGER : 0;
- return forkAndSpecialize(uid, gid, gids, debugFlags, rlimits);
- }
最终穿过虚拟机调用./android-2.2/dalvik/vm/native/dalvik_system_Zygote.c文件中的Dalvik_dalvik_system_Zygote_forkAndSpecialize()函数,由dalvik完成fork新的进程。
在./android-2.2/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中的main函数中最后会调用runSelectLoopMode(),进入while循环,由peers创建新的进程。
二。SystemService进程服务的产生
从上面的分析可以知道,SystemService服务进程是由Zygote服务进程fork出来的一个服务子进程。SystemService用于创建init.rc定义的服务之外的所有服务。
在文件./android-2.2/frameworks/base/services/java/com/android/server/SystemServer.java中,main()函数中有如下代码:
- // 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);
-
- System.loadLibrary("android_servers");
- init1(args);
Init1()是在native空间实现的,用于启动native空间的服务,其实现是在./android-2.2/frameworks/base/services/jni/com_android_server_SystemServer.cpp文件中的android_server_SystemServer_init1()函数:
- static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
- {
- system_init();
- }
而system_init()函数服务初始化创建native层的各个服务,包括SurfaceFlinger服务的启动。system_init()函数被定义在./android-2.2/frameworks/base/cmds/system_server/library/system_init.cpp文件中:
- extern "C" status_t system_init()
- {
- LOGI("Entered system_init()");
-
- sp<ProcessState> proc(ProcessState::self());
-
- sp<IServiceManager> sm = defaultServiceManager();
- LOGI("ServiceManager: %p\n", sm.get());
-
- sp<GrimReaper> grim = new GrimReaper();
- sm->asBinder()->linkToDeath(grim, grim.get(), 0);
-
- char propBuf[PROPERTY_VALUE_MAX];
- property_get("system_init.startsurfaceflinger", propBuf, "1");
- if (strcmp(propBuf, "1") == 0) {
- // Start the SurfaceFlinger
- SurfaceFlinger::instantiate();
- }
在这里如果system_init.startsurfaceflinger字段值为1,就启动SurfaceFlinger线程类服务,其中SurfaceFlinger::instantiate();函数的定义在./android-2.2/frameworks/base/libs/surfaceflinger/SurfaceFlinger.cpp文件中定义:
- void SurfaceFlinger::instantiate() {
- defaultServiceManager()->addService(
- String16("SurfaceFlinger"), new SurfaceFlinger());
- }
通过addService()函数来注册SurfaceFlinger服务,这样就初始化了SurfaceFlinger服务环境,建造了对象,运行了构造函数。
阅读(2146) | 评论(0) | 转发(0) |