Android启动过程分析

Android系统启动过程

 

首先看一张Android框架结构图

  

Linux内核启动之后就到Android Init进程,进而启动Android相关的服务和应用。

启动的过程如下图所示:(图片来自网上,后面有地址)

    

 

一 Init进程的启动

  init进程,它是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行,

并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。init始终是第一个进程。

  启动过程就是代码init.c中main函数执行过程:system\core\init\init.c

在函数中执行了:文件夹建立,挂载,rc文件解析,属性设置,启动服务,执行动作,socket监听……

下面看两个重要的过程:rc文件解析和服务启动。

1 rc文件解析

  .rc文件是Android使用的初始化脚本文件 (System/Core/Init/readme.txt中有描述:

four broad classes of statements which are Actions, Commands, Services, and Options.)

  其中Command 就是系统支持的一系列命令,如:export,hostname,mkdir,mount,等等,其中一部分是 linux 命令,

还有一些是 android 添加的,如:class_start <serviceclass>: 启动服务,class_stop <serviceclass>:关闭服务,等等。

  其中Options是针对 Service 的选项的。

系统初始化要触发的动作和要启动的服务及其各自属性都在rc脚本文件中定义。 具体看一下启动脚本:\system\core\rootdir\init.rc

       在解析rc脚本文件时,将相应的类型放入各自的List中:

  \system\core\init\Init_parser.c  :init_parse_config_file( )存入到

  action_queue、   action_list、 service_list中,解析过程可以看一下parse_config函数,类似状态机形式挺有意思。

  这其中包含了服务:adbd、servicemanager、vold、ril-daemon、debuggerd、surfaceflinger、zygote、media……

2 服务启动

       文件解析完成之后将service放入到service_list中。

 

文件解析完成之后将service放入到service_list中。

   \system\core\init\builtins.c

       Service的启动是在do_class_start函数中完成:

[html] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. int do_class_start(int nargs, char **args)  
  2. {  
  3.     service_for_each_class(args[1], service_start_if_not_disabled);  
  4.     return 0;  
  5. }  

遍历所有名称为classname,状态不为SVC_DISABLED的Service启动。

 

[html] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. void service_for_each_class(const char *classname,  
  2.                             void (*func)(struct service *svc))  
  3. {  
  4.        ……  
  5. }  
  6.   
  7. static void service_start_if_not_disabled(struct service *svc)  
  8. {  
  9.     if (!(svc->flags & SVC_DISABLED)) {  
  10.         service_start(svc, NULL);  
  11.     }  
  12. }  

 

 

do_class_start对应的命令:

 

  KEYWORD(class_start, COMMAND, 1, do_class_start)

 

init.rc文件中搜索class_start:class_start main 、class_start core、……

 

  main、core即为do_class_start参数classname

 

init.rc文件中Service class名称都是main:

 

       service drm /system/bin/drmserver

 

    class main

 

  service surfaceflinger /system/bin/surfaceflinger

 

       class main

 

于是就能够通过main名称遍历到所有的Service,将其启动。

do_class_start调用:

       init.rc中

    on boot  //action

      class_start core    //执行command 对应 do_class_start

          class_start main

 

Init进程main函数中:

 

system/core/init/init.c中:

[html] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. int main(){  
  2.      //挂在文件  
  3.   
  4.        //解析配置文件:init.rc……  
  5.   
  6.        //初始化化action queue  
  7.   
  8.      ……  
  9.        for(;;){  
  10.   
  11.               execute_one_command();  
  12.   
  13.               restart_processes();  
  14.   
  15.               for (i = 0; i fd_count; i++) {  
  16.   
  17.             if (ufds[i].revents == POLLIN) {  
  18.   
  19.                 if (ufds[i].fd == get_property_set_fd())  
  20.   
  21.                     handle_property_set_fd();  
  22.   
  23.                 else if (ufds[i].fd == get_keychord_fd())  
  24.   
  25.                     handle_keychord();  
  26.   
  27.                 else if (ufds[i].fd == get_signal_fd())  
  28.   
  29.                     handle_signal();  
  30.             }  
  31.         }  
  32.   
  33.        }  
  34. }  

循环调用service_start,将状态SVC_RESTARTING启动, 将启动后的service状态设置为SVC_RUNNING。

  pid=fork();

  execve();

  在消息循环中:Init进程执行了Android的Command,启动了Android的NativeService,监听Service的变化需求,Signal处理。

Init进程是作为属性服务(Property service),维护这些NativeService。

 

二 ServiceManager启动

       在.rc脚本文件中zygote的描述:

[html] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. service servicemanager /system/bin/servicemanager  
  2.   class core  
  3.   user system  
  4.   group system  
  5.   critical  
  6.   onrestart restart zygote  
  7.   onrestart restart media  
  8.   onrestart restart surfaceflinger  
  9.   onrestart restart drm  

 

   ServiceManager用来管理系统中所有的binder service,不管是本地的c++实现的还是Java语言实现的都需要

这个进程来统一管理,最主要的管理就是,注册添加服务,获取服务。所有的Service使用前都必须先在servicemanager中进行注册。

  do_find_service( )

  do_add_service( )

  svcmgr_handler( )

  代码位置:frameworks\base\cmds\servicemanager\Service_manager.c

 

三 Zygote进程的启动

  Zygote这个进程是非常重要的一个进程,Zygote进程的建立是真正的Android运行空间,初始化建立的Service都是Navtive service.

(1) 在.rc脚本文件中zygote的描述:

[html] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server  
  2.   class main  
  3.   socket zygote stream 666  
  4.   onrestart write /sys/android_power/request_state wake  
  5.   onrestart write /sys/power/state on  
  6.   onrestart restart media  
  7.   onrestart restart netd  

 

代码位置:frameworks/base/cmds/app_process/app_main.cpp

       上面的参数在这里就会用上,决定是否要启动和启动那些进程。

[html] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. int main( ){  
  2.        AppRuntime runtime;  
  3.        if (zygote) {  
  4.               runtime.start("com.android.internal.os.ZygoteInit",  
  5.                 startSystemServer ? "start-system-server" : "");  
  6.        }  
  7. }  
  8.   
  9. class AppRuntime : public AndroidRuntime{};  

 

(2) 接着到了AndroidRuntime类中:

frameworks\base\core\jni\AndroidRuntime.cpp

[html] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. void start(const char* className, const char* options){  
  2.   
  3.        // start the virtual machine Java在虚拟机中运行的  
  4.        JNIEnv* env;  
  5.        if (startVm(&mJavaVM, &env) != 0) {  
  6.               return;  
  7.        }  
  8.   
  9.        //向刚刚新建的虚拟机注册JNI本地接口  
  10.        if (startReg(env) 0) {  
  11.               return;  
  12.        }  
  13.   
  14.     // jni 调用 java 方法,获取对应类的静态main方法  
  15.     jmethodID startMeth = env->GetStaticMethodID(startClass,  
  16.          "main","([Ljava/lang/String;)V");  
  17.   
  18.        // jni调用 java方法,调用到ZygoteInit类的main函数  
  19.   
  20.        jclass startClass = env->FindClass(className);  
  21.   
  22.        env->CallStaticVoidMethod(startClass, startMeth, strArray);  
  23. }  

 到了ZygoteInit.java中的静态main函数中,从C++ ——》JAVA

 

(3)ZygoteInit

       真正Zygote进程:

              frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

[html] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. public static void main(String argv[]) {  
  2.        //Registers a server socket for zygote command connections  
  3.        registerZygoteSocket();  
  4.   
  5.        //Loads and initializes commonly used classes and  
  6.        //used resources that can be shared across processes  
  7.        preload();  
  8.   
  9.        // Do an initial gc to clean up after startup  
  10.        gc();  
  11.   
  12.        if (argv[1].equals("start-system-server")) {  
  13.               startSystemServer();  
  14.        }  
  15.   
  16.        /**  
  17.        * Runs the zygote process's select loop. Accepts new connections as  
  18.        * they happen, and reads commands from connections one spawn-request's  
  19.        * worth at a time.  
  20.        */  
  21.   
  22.        runSelectLoopMode();    //loop中  
  23.        /**  
  24.        * Close and clean up zygote sockets. Called on shutdown and on the  
  25.        * child's exit path.  
  26.        */  
  27.        closeServerSocket();  
  28. }  

四 SystemServer启动

(1)在Zygote进程进入循环之前,调用了startSystemServer( );

[html] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. private static boolean startSystemServer(){  
  2.        /* Request to fork the system server process 孵化新的进程 */  
  3.     ZygoteConnection.Arguments parsedArgs = null;  
  4.        pid = Zygote.forkSystemServer(  
  5.               parsedArgs.uid, parsedArgs.gid,  
  6.               parsedArgs.gids,  
  7.               parsedArgs.debugFlags,  
  8.               null,  
  9.               parsedArgs.permittedCapabilities,  
  10.               parsedArgs.effectiveCapabilities);  
  11.    
  12.               /* For child process 对新的子进程设置 */  
  13.        if (pid == 0) {  
  14.               handleSystemServerProcess(parsedArgs);  
  15.        }  
  16. }  
  17.   
  18. void handleSystemServerProcess(parsedArgs){  
  19.        closeServerSocket();  
  20.        //"system_server"  
  21.        Process.setArgV0(parsedArgs.niceName);  
  22.   
  23.        //Pass the remaining arguments to SystemServer.  
  24.     RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,  
  25.       parsedArgs.remainingArgs);  
  26.        /* should never reach here */  
  27. }  

 

(2)RuntimeInit中:

       frameworks\base\core\java\com\android\internal\os\RuntimeInit.java

[java] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. //The main function called when started through the zygote process.  
  2. void zygoteInit(int targetSdkVersion, String[] argv){  
  3.         applicationInit(targetSdkVersion, argv);  
  4. }  
  5.   
  6. void applicationInit(int targetSdkVersion, String[] argv){  
  7.     // Remaining arguments are passed to the start class's static main  
  8.     invokeStaticMain(args.startClass, args.startArgs);  
  9. }  
  10.   
  11. void invokeStaticMain(String className, String[] argv){  
  12.     Class<?> cl;  
  13.     cl = Class.forName(className);  
  14.    
  15.     //获取SystemServer的main方法,抛出MethodAndArgsCaller异常  
  16.     Method m;  
  17.     m = cl.getMethod("main", new Class[] { String[].class });  
  18.     int modifiers = m.getModifiers();  
  19.     throw new ZygoteInit.MethodAndArgsCaller(m, argv);  
  20. }  

 

(3)从startSystemServer开始执行并没有去调用SystemServer的任何方法,

    只是通过反射获取了main方法,付给了MethodAndArgsCaller,并抛出了MethodAndArgsCaller异常。

    此异常是在哪里处理的呢?

       回到startSystemServer( )函数的调用处:

       在ZygoteInit的main函数中:

[html] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. public static void main(String argv[]) {  
  2.        try {  
  3.               ……  
  4.               if (argv[1].equals("start-system-server")) {  
  5.                   startSystemServer();       //这里如果抛出异常,跳过下面流程  
  6.               }  
  7.             
  8.         runSelectLoopMode();    //loop中  
  9.               ……  
  10.   
  11.   
  12.        } catch (MethodAndArgsCaller caller) {  
  13.               caller.run();        //处理的异常  
  14.        }  
  15. }  

 

如果startSystemServer抛出了异常,跳过执行ZygoteInit进程的循环,这是怎么回事呢?

  在startSystemServer中异常是由handleSystemServerProcess抛出,而

      pid = Zygote.forkSystemServer( )

      /* For child process 仅对新的子进程设置 */

      if (pid == 0) {

        handleSystemServerProcess(parsedArgs);

      }

      // Zygote.forkSystemServer根据参数fork 出一个子进程,若成功调用,则返回两次:

    一次返回的是 zygote 进程的 pid ,值大于0;一次返回的是子进程 pid,值等于0否则,出错返回-1;

  caller.run();

    MethodAndArgsCaller run函数:调用前面所提到的

    //SystemServer main方法

    m = cl.getMethod("main", new Class[] { String[].class });

    启动了进程SystemServer。

(4)SystemServer的执行 init1( )

              //frameworks\base\services\java\com\android\server\SystemServer.java

[html] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. public static void main(String[] args) {  
  2.   
  3.          System.loadLibrary("android_servers");      
  4.   
  5.          /*  
  6.   
  7.          * This method is called from Zygote to initialize the system.  
  8.          * This will cause the native services (SurfaceFlinger, AudioFlinger, etc..)  
  9.          * to be started. After that it will call back  
  10.          * up into init2() to start the Android services.  
  11.          */  
  12.          init1(args);    //native 完了回调init2( )  
  13.   }  
  14.   
  15. //init1:  
  16.   frameworks/base/services/jni/com_android_server_SystemServer.cpp:: android_server_SystemServer_init1( )   
  17.   中调用:system_init  
  18. extern "C" status_t system_init()  
  19. {  
  20.        sp<ProcessState> proc(ProcessState::self());  
  21.        sp<IServiceManagersm = defaultServiceManager();  
  22.   
  23.        //启动SurfaceFlinger 和传感器  
  24.        property_get("system_init.startsurfaceflinger", propBuf, "1");  
  25.        SurfaceFlinger::instantiate();  
  26.   
  27.        property_get("system_init.startsensorservice", propBuf, "1");  
  28.        SensorService::instantiate();  
  29.   
  30.        // And now start the Android runtime.  We have to do this bit  
  31.        // of nastiness because the Android runtime initialization requires  
  32.        // some of the core system services to already be started.  
  33.     // All other servers should just start the Android runtime at  
  34.        // the beginning of their processes's main(), before calling  
  35.        // the init function.  
  36.        AndroidRuntime* runtime = AndroidRuntime::getRuntime();  
  37.   
  38.   
  39.        //回调 com.android.server.SystemServer init2 方法        
  40.   
  41.        JNIEnv* env = runtime->getJNIEnv();  
  42.   
  43.        jclass clazz = env->FindClass("com/android/server/SystemServer");  
  44.   
  45.        jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");  
  46.   
  47.        env->CallStaticVoidMethod(clazz, methodId);  
  48.       
  49.   
  50.        //启动线程池 做为binder 服务  
  51.        ProcessState::self()->startThreadPool();  
  52.        IPCThreadState::self()->joinThreadPool();  
  53.        return NO_ERROR;  
  54.   
  55. }  

 

ProcessState:

  每个进程在使用binder 机制通信时,均需要维护一个ProcessState 实例来描述当前进程在binder 通信时的binder 状态。

  ProcessState 有如下2 个主要功能:

  1. 创建一个thread, 该线程负责与内核中的binder 模块进行通信,称该线程为Pool thread ;

  2. 为指定的handle 创建一个BpBinder 对象,并管理该进程中所有的BpBinder 对象。

 

Pool thread:

  在Binder IPC 中,所有进程均会启动一个thread 来负责与BD 来直接通信,也就是不停的读写BD ,

  这个线程的实现主体是一个IPCThreadState 对象,下面会介绍这个类型。

  下面是Pool thread 的启动方式:

  ProcessState::self()->startThreadPool();

IPCThreadState :

  IPCThreadState 也是以单例模式设计的。由于每个进程只维护了一个ProcessState 实例,同时ProcessState 只启动一个Pool thread ,

也就是说每一个进程只会启动一个Pool thread ,因此每个进程则只需要一个IPCThreadState 即可。

Pool thread 的实际内容则为:

IPCThreadState::self()->joinThreadPool();

 

(5)SystemServer的执行 init2( )

[html] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. public static final void init2() {     
  2.     //建立线程来处理  
  3.        Thread thr = new ServerThread();        
  4.        thr.setName("android.server.ServerThread");  
  5.        thr.start();  
  6. }  
  7.   
  8. //看看线程ServerThread里面都做了什么事情?  
  9. public void run() {  
  10.     addBootEvent(new String("Android:SysServerInit_START"));  
  11.     Looper.prepare();  
  12.     android.os.Process.setThreadPriority(  
  13.     android.os.Process.THREAD_PRIORITY_FOREGROUND);  
  14.   
  15.     //初始化服务,创建各种服务实例,如:电源、网络、Wifi、蓝牙,USB等,  
  16.   //初始化完成以后加入到 ServiceManager中,  
  17.     //事我们用 Context.getSystemService (String name) 才获取到相应的服务  
  18.     PowerManagerService power = null;  
  19.     NetworkManagementService networkManagement = null;  
  20.     WifiP2pService wifiP2p = null;  
  21.     WindowManagerService wm = null;  
  22.     BluetoothService bluetooth = null;  
  23.     UsbService usb = null;  
  24.     NotificationManagerService notification = null;  
  25.     StatusBarManagerService statusBar = null;  
  26.     ……  
  27.   
  28.     power = new PowerManagerService();  
  29.     ServiceManager.addService(Context.POWER_SERVICE, power);  
  30.     ……  
  31.   
  32.     // ActivityManagerService作为ApplicationFramework最重要的服务  
  33.     ActivityManagerService.setSystemProcess();  
  34.     ActivityManagerService.installSystemProviders();  
  35.     ActivityManagerService.self().setWindowManager(wm);     
  36.   // We now tell the activity manager it is okay to run third party  
  37.   // code.  It will call back into us once it has gotten to the state  
  38.   // where third party code can really run (but before it has actually  
  39.   // started launching the initial applications), for us to complete our  
  40.   // initialization.  
  41.   //系统服务初始化准备就绪,通知各个模块  
  42.     ActivityManagerService.self().systemReady(new Runnable() {  
  43.   
  44.            public void run() {  
  45.                   startSystemUi(contextF);  
  46.                   batteryF.systemReady();  
  47.                   networkManagementF.systemReady();  
  48.                   usbF.systemReady();  
  49.                   ……  
  50.   
  51.                   // It is now okay to let the various system services start their  
  52.                   // third party code...  
  53.                   appWidgetF.systemReady(safeMode);  
  54.                   wallpaperF.systemReady();  
  55.            }  
  56.     });  
  57.   
  58.     //  
  59.     //BOOTPROF  
  60.     addBootEvent(new String("Android:SysServerInit_END"));  
  61.     Looper.loop();  
  62. }  

 

 到这里系统ApplicationFramework层的XxxServiceManager准备就绪,可以开始跑上层应用了,我们的第一个上层应用HomeLauncher。

  HomeActivity又是如何启动的呢?

  Activity的启动必然和ActivityManagerService有关,我们需要去看看

  ActivityManagerService.systemReady( )中都干了些什么。

[html] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. public void systemReady(final Runnable goingCallback) {  
  2.     ……  
  3.     //ready callback  
  4.        if (goingCallback != null)  
  5.               goingCallback.run();  
  6.   
  7.        synchronized (this) {  
  8.               // Start up initial activity.  
  9.               // ActivityStack mMainStack;  
  10.               mMainStack.resumeTopActivityLocked(null);  
  11.        }  
  12. ……  
  13.   
  14. }  
  15.   
  16. final boolean resumeTopActivityLocked(ActivityRecord prev) {  
  17.   // Find the first activity that is not finishing.  
  18.   ActivityRecord next = topRunningActivityLocked(null);  
  19.   if (next == null) {  
  20.     // There are no more activities!  Let's just start up the  
  21.     // Launcher...  
  22.     if (mMainStack) {  
  23.       //ActivityManagerService mService;  
  24.       return mService.startHomeActivityLocked();  
  25.     }  
  26.   }  
  27.   ……  
  28. }  


大家可以参考下面的Uml图来加深理解:



参考文档:

    http://www.cnblogs.com/linucos/archive/2012/05/22/2513760.html#commentform

    http://www.cnblogs.com/idiottiger/archive/2012/05/25/2516295.html

posted @ 2017-04-21 22:25  天涯海角路  阅读(147)  评论(0)    收藏  举报