Android启动过程分析详解手机开发

Android系统启动过程

首先看一张Android框架结构图

  Android启动过程分析详解手机开发

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

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

    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 ActionsCommandsServices, 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函数中完成:

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

  代码位置:frameworks/base/cmds/servicemanager/Service_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 

代码位置: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类中:

frameworks/base/core/jni/AndroidRuntime.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进程:

              frameworks/base/core/java/com/android/internal/os/ZygoteInit.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(); 
}

四 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中:

       frameworks/base/core/java/com/android/internal/os/RuntimeInit.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( )

              //frameworks/base/services/java/com/android/server/SystemServer.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( )中都干了些什么。

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(); 
    } 
  } 
  …… 
}

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

Android启动过程分析详解手机开发

参考文档:

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

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

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/app/5983.html

(0)
上一篇 2021年7月17日 00:29
下一篇 2021年7月17日 00:29

相关推荐

发表回复

登录后才能评论