zoukankan      html  css  js  c++  java
  • Android系统启动过程

    首先Android框架架构图:

      

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

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

        image


      

      下面将从Android4.0源码中,和网络达人对此的总结中,对此过程加以学习了解和总结,

    以下学习过程中代码片段中均有省略不完整,请参照源码。

     

    一 Init进程的启动

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

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

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

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

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

    1 rc文件解析

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

    four broad classes of statements which are ActionsCommandsServices, and Options.)

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

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

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

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

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

      systemcoreinitInit_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中。

       systemcoreinituiltins.c

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

    int do_class_start(int nargs, char **args)
    {
        service_for_each_class(args[1], service_start_if_not_disabled); return 0;
    }

     

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

     void service_for_each_class(const char *classname, void (*func)(struct service *svc))

    {
           ……
    } static void service_start_if_not_disabled(struct service *svc)
    { if (!(svc->flags & SVC_DISABLED)) {
            service_start(svc, NULL);
        }
    }
    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中:

    int main(){ 

         //挂在文件

           //解析配置文件:init.rc……

           //初始化化action queue

         …… for(;;){
    
                  execute_one_command();
    
                  restart_processes(); for (i = 0; i < fd_count; i++) { if (ufds[i].revents == POLLIN) { if (ufds[i].fd == get_property_set_fd())
    
                        handle_property_set_fd(); else if (ufds[i].fd == get_keychord_fd())
    
                        handle_keychord(); else if (ufds[i].fd == get_signal_fd())
    
                        handle_signal();
                }
            }
    
           }
    }

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

      pid=fork();

      execve();

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

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

     

    二 ServiceManager启动

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

    service servicemanager /system/bin/servicemanager
      class core
      user system
      group system
      critical
      onrestart restart zygote
      onrestart restart media
      onrestart restart surfaceflinger
      onrestart restart drm
     

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

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

      do_find_service( )

      do_add_service( )

      svcmgr_handler( )

      代码位置:frameworksasecmdsservicemanagerService_manager.c

     

    三 Zygote进程的启动

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

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

    service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
      class main
      socket zygote stream 666   onrestart write /sys/android_power/request_state wake
      onrestart write /sys/power/state on
      onrestart restart media
      onrestart restart netd
    
    参数:--zygote --start-system-server
     

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

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

    int main( ){
           AppRuntime runtime; if (zygote) { runtime.start("com.android.internal.os.ZygoteInit",
                    startSystemServer ? "start-system-server" : ""); }
    } class AppRuntime : public AndroidRuntime{};
     

    (2) 接着到了AndroidRuntime类中:

    frameworksasecorejniAndroidRuntime.cpp

    void start(const char* className, const char* options){ // start the virtual machine Java在虚拟机中运行的 JNIEnv* env; if (startVm(&mJavaVM, &env) != 0) { return;
           } //向刚刚新建的虚拟机注册JNI本地接口 if (startReg(env) < 0) { return;
           }
    
        // jni 调用 java 方法,获取对应类的静态main方法     jmethodID startMeth = env->GetStaticMethodID(startClass,
             "main","([Ljava/lang/String;)V"); // jni调用 java方法,调用到ZygoteInit类的main函数  jclass startClass = env->FindClass(className);
    
           env->CallStaticVoidMethod(startClass, startMeth, strArray);
    }

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

     

    (3)ZygoteInit

           真正Zygote进程:

                  frameworksasecorejavacomandroidinternalosygoteInit.java


    public static void main(String argv[]) { //Registers a server socket for zygote command connections registerZygoteSocket(); //Loads and initializes commonly used classes and //used resources that can be shared across processes preload(); // Do an initial gc to clean up after startup gc(); if (argv[1].equals("start-system-server")) {
                  startSystemServer();
           } /** * Runs the zygote process's select loop. Accepts new connections as
           * they happen, and reads commands from connections one spawn-request's
           * worth at a time. */ runSelectLoopMode(); //loop中 /** * Close and clean up zygote sockets. Called on shutdown and on the
           * child's exit path. */ closeServerSocket();
    }
           Zygote就建立好了,利用Socket通讯,接收请求,Fork应用程序进程,进入Zygote进程服务框架中。

     

    四 SystemServer启动

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

    private static boolean startSystemServer(){ /* Request to fork the system server process 孵化新的进程 */     ZygoteConnection.Arguments parsedArgs = null;
           pid = Zygote.forkSystemServer(
                  parsedArgs.uid, parsedArgs.gid,
                  parsedArgs.gids,
                  parsedArgs.debugFlags, null,
                  parsedArgs.permittedCapabilities,
                  parsedArgs.effectiveCapabilities); /* For child process 对新的子进程设置 */ if (pid == 0) {
                  handleSystemServerProcess(parsedArgs);
           }
    } void handleSystemServerProcess(parsedArgs){
           closeServerSocket(); //"system_server" Process.setArgV0(parsedArgs.niceName); //Pass the remaining arguments to SystemServer.     RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
          parsedArgs.remainingArgs); /* should never reach here */ }

    (2)RuntimeInit中:

           frameworksasecorejavacomandroidinternalosRuntimeInit.java

    //The main function called when started through the zygote process. void zygoteInit(int targetSdkVersion, String[] argv){
            applicationInit(targetSdkVersion, argv);
    } void applicationInit(int targetSdkVersion, String[] argv){ // Remaining arguments are passed to the start class's static main invokeStaticMain(args.startClass, args.startArgs);
    } void invokeStaticMain(String className, String[] argv){
        Class<?> cl;
        cl = Class.forName(className); //获取SystemServer的main方法,抛出MethodAndArgsCaller异常 Method m;
        m = cl.getMethod("main", new Class[] { String[].class }); int modifiers = m.getModifiers(); throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }
     

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

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

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

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

           在ZygoteInit的main函数中:

    public static void main(String argv[]) { try {
                  …… if (argv[1].equals("start-system-server")) {
                      startSystemServer(); //这里如果抛出异常,跳过下面流程 }
              
            runSelectLoopMode(); //loop中 ……
    
    
           } catch (MethodAndArgsCaller caller) {
                  caller.run(); //处理的异常 }
    }

      如果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( )

                  //frameworksaseservicesjavacomandroidserverSystemServer.java

           

    public static void main(String[] args) {
             System.loadLibrary("android_servers");    
    
             /*   * This method is called from Zygote to initialize the system.
             * This will cause the native services (SurfaceFlinger, AudioFlinger, etc..)
             * to be started. After that it will call back
             * up into init2() to start the Android services.
             */    init1(args); //native 完了回调init2( )   } //init1:   frameworks/base/services/jni/com_android_server_SystemServer.cpp:: android_server_SystemServer_init1( ) 
      中调用:system_init
    extern "C" status_t system_init()
    {
           sp<ProcessState> proc(ProcessState::self());
           sp<IServiceManager> sm = defaultServiceManager(); //启动SurfaceFlinger 和传感器 property_get("system_init.startsurfaceflinger", propBuf, "1");
           SurfaceFlinger::instantiate();
    
           property_get("system_init.startsensorservice", propBuf, "1");
           SensorService::instantiate(); // And now start the Android runtime.  We have to do this bit // of nastiness because the Android runtime initialization requires // some of the core system services to already be started.
        // All other servers should just start the Android runtime at // the beginning of their processes's main(), before calling // the init function. AndroidRuntime* runtime = AndroidRuntime::getRuntime(); //回调 com.android.server.SystemServer init2 方法   JNIEnv* env = runtime->getJNIEnv();
    
           jclass clazz = env->FindClass("com/android/server/SystemServer");
    
           jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
    
           env->CallStaticVoidMethod(clazz, methodId); //启动线程池 做为binder 服务 ProcessState::self()->startThreadPool();
           IPCThreadState::self()->joinThreadPool(); return NO_ERROR;
    
    }

    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( )

    public static final void init2() {   
        //建立线程来处理 Thread thr = new ServerThread();      
           thr.setName("android.server.ServerThread");
           thr.start();
    } //看看线程ServerThread里面都做了什么事情? public void run() {
        addBootEvent(new String("Android:SysServerInit_START"));
        Looper.prepare();
        android.os.Process.setThreadPriority(
        android.os.Process.THREAD_PRIORITY_FOREGROUND); //初始化服务,创建各种服务实例,如:电源、网络、Wifi、蓝牙,USB等,   //初始化完成以后加入到 ServiceManager中, //事我们用 Context.getSystemService (String name) 才获取到相应的服务 PowerManagerService power = null;
        NetworkManagementService networkManagement = null;
        WifiP2pService wifiP2p = null;
        WindowManagerService wm = null;
        BluetoothService bluetooth = null;
        UsbService usb = null;
        NotificationManagerService notification = null;
        StatusBarManagerService statusBar = null;
        ……
    
        power = new PowerManagerService();
        ServiceManager.addService(Context.POWER_SERVICE, power);
        …… // ActivityManagerService作为ApplicationFramework最重要的服务 ActivityManagerService.setSystemProcess();
        ActivityManagerService.installSystemProviders();
        ActivityManagerService.self().setWindowManager(wm);   
      // We now tell the activity manager it is okay to run third party   // code.  It will call back into us once it has gotten to the state   // where third party code can really run (but before it has actually   // started launching the initial applications), for us to complete our   // initialization.   //系统服务初始化准备就绪,通知各个模块 ActivityManagerService.self().systemReady(new Runnable() { public void run() {
                      startSystemUi(contextF);
                      batteryF.systemReady();
                      networkManagementF.systemReady();
                      usbF.systemReady();
                      …… // It is now okay to let the various system services start their // third party code... appWidgetF.systemReady(safeMode);
                      wallpaperF.systemReady();
               }
        }); // //BOOTPROF addBootEvent(new String("Android:SysServerInit_END"));
        Looper.loop();
    }

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

      HomeActivity又是如何启动的呢?

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

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

     

    五 Home界面启动

            

     public void systemReady(final Runnable goingCallback) {
        ……     //ready callback if (goingCallback != null)
                  goingCallback.run(); synchronized (this) { // Start up initial activity. // ActivityStack mMainStack; mMainStack.resumeTopActivityLocked(null);
           }
    ……
    
    } final boolean resumeTopActivityLocked(ActivityRecord prev) {
      // Find the first activity that is not finishing.   ActivityRecord next = topRunningActivityLocked(null);
      if (next == null) {     // There are no more activities!  Let's just start up the
        // Launcher...     if (mMainStack) {
          //ActivityManagerService mService;       return mService.startHomeActivityLocked();
        }
      }
      ……
    }

     

     

           然后就启动了Home界面,完成了整个Android启动流程。

          整个过程如下:

      

  • 相关阅读:
    车牌定位与畸变校正(python3.7,opencv4.0)
    TensorFlow 2.0 Alpha/Beta pip安装指令
    pandas 获取数据帧DataFrame的行、列数
    pandas 对数据帧DataFrame中数据的增删、补全及转换操作
    pandas 对数据帧DataFrame中数据的索引及切片操作
    Exception: Exception caught in workbook destructor. Explicit close() may be required for workbook. 错误解决办法
    pandas对Excel文件的读写操作
    第一个WPF程序(串口调试)
    [C#]AdvPropertyGrid的使用示例(第三方控件:DevComponents.DotNetBar2.dll)
    C# 获得本地通用网卡信息
  • 原文地址:https://www.cnblogs.com/bill-technology/p/4130797.html
Copyright © 2011-2022 走看看