Zygote和System进程的启动过程—— 待整理

第11章 Zygote和System进程的启动过程

Zygote进程的启动

Zygote是进程孵化器,通过复制自身的方式创建 System进程和所有的应用程序进程。Linux内核加载完成后启动init进程。init读取了init.rc的脚本,里面有Zygote的启动信息。

源码位置system/core/rootdir/init.rc

service zygote /system/bin/app_process -Xzygote /system/bin 
--zygote --start-system-server socket zygote stream 666
  • 1
  • 2
  • 3
  • 4

指定以service的形式启动Zygote进程,启动时需要创建一个名称为zygote的Socket用来进程间通信并且指定在Zygote启动后立即启动System进程。

由于指定了service的形式启动Zygote,所以init进程启动是会调用service_start方法启动Zygote。

//通过fork创建一个子进程,也就是Zygote进程。
//pid等于0时,说明是从Zygote进程返回
pid = fork();
//Zygote进程创建后,遍历在init.rc中为Zygote配置的Socket列表。
//创建socket,返回一个文件描述符,对应的设备文件是
/dev/socket/zygote,AMS请求Zygote创建新的应用程序进程时会先打开这个
设备文件创建一个连接到Zygote进程的Client端 Socket。
create_socket();
//将这个文件描述符发布到系统中,这个过程会将文件描述符保存在
//一个名称为"ANDROID_SOCKET_zygote"的环境变量中。
publish_socket();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

以上是Zygote的启动分析,下面看Zygote的启动过程。 
init.rc指定了Zygote进程加载的文件是/system/bin/app_process

第一步 main

在脚本中指定了Zygote进程加载的应用程序文件为/system/bin/app_process,入口函数是main方法。

frameworks/base/cmds/app_process/app_main.cpp->main()
  • 1
1.1 创建一个AppRuntime对象 runtime,继承了AndroidRuntime。
1.2 set_process_name设置当前进程名称为zygote
1.3 AndroidRuntime继续启动Zygote
runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);
  • 1

这里的startSystemServer为true,指定Zygote进程启动完成之后,需要启动System进程。

第二步:start

AppRunTIme的 start方法从父类继承下来

frameworks/base/core/jni/AndroidRuntime.cpp->start()
  • 1
2.1 startVm()在Zygote创建一个虚拟机,
2.2 startReg()在虚拟机中注册JNI方法,
2.3 调用com.android.internal.os.ZygoteInit的 main方法继续启动 zygote进程

第三步:ZygoteInit.main

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java.main()
  • 1
3.1 通过registerZygoteSocket()创建一个 Server端Socket,用来与AMS通信。这个过程中首先通过上面提到的环境变量”ANDROID_SOCKET_zygote” 来获取文件描述符。最后根据这个文件描述符创建了一个LocalServerSocket对象sServerSocket。
3.2 通过startSystemServer()启动 System进程,系统的各种关键服务在System中启动。这个过程中首先是一系列的启动参数,然后通过Zygote.forkSystemserver()创建System进程。forkSystemserver最终调用fork();pid等于0时代表在System进程中执行,通过handleSystemServerProcess()进一步启动 System进程。
3.3 通过runSelectLoopMode()等待AMS发起请求,创建新的应用程序进程。首先创建一个大小为4的文件描水符的数组,将sServerSocket的文件描述符加入到数组,通过 while循环监控可读数据的索引index。如果index等于0,那么就说明AMS通过sServerSocket与Zygote建立了连接;如果index大于0,那么就说明 AMS向Zygote发起了一个创建应用程序进程的请求,调用ZygoteConnection->runOnce创建一个新的应用程序进程。

至此 Zygote已经启动完毕,通过无限循环监听sServerSocket接受AMS的创建新的应用程序的请求,并且通过 startSystemServer启动了 System进程,接下来来看System进程的启动。

System进程的启动

上面的 startSystemServer()中提到了通过handleSystemServerProcess()进一步启动System进程。

第一步:ZygoteInit.handleSystemServerProcess

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java.handleSystemServerProcess

1.1 closeServerSocket()

由于 System 进程是通过fork Zygote进程得到的,所以它复制了Zygote进程的地址空间,也获得了Zygote进程中创建的Socket,System用不到这个Socket需要关闭。

1.2 RuntimeInit.zygoteInit()

调用RuntimeInit的 zygoteInit方法进一步启动 System进程。

第二步 RuntimeInit.zygoteInit

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

2.1 commonInit()

初始化 System进程的时区和键盘布局等通用信息。

2.2 zygoteNative()

在System进程中启动一个Binder线程池。

2.3 invokeStaticMain()

进入到SystemServer的main()

第三步 SystemServer.main()

frameworks/base/services/java/com/server/SystemServer.java 
调用了init1方法启动一些由C++编写的系统服务,init1是一个JNI方法。

第四步 SystemServer.init1

frameworks/base/services/jni/com_android_server_SystemServer.cpp

static void android_server_SystemServer_init1()
调用了system_init()
  • 1
  • 2
  • 3
  • 4
4.1

创建了一个GrimReaper用来接受Service Manager的死亡通知,收到Service Manager死亡通知后,会杀死System进程。

4.2 启动SurfaceFlinger服务和SensorService服务。
SurfaceFlinger::instantiate();
SensorService::instantiate();
  • 1
  • 2
4.3
runtime->callStatic("com/android/server/SystemServer","init2");
调用com.android.server.SystemServer的静态方法init2启动java开发的系统服务。
  • 1
  • 2
4.4
//启动一个线程池,不过之前的 zygoteInitNative已经启动过线程池
//实际这里不起作用。
ProcessState::self()->startThreadPool();
//将当前线程加入到这个 Binder线程池
IPCThreadState::self()->joinThreadPool();
  • 1
  • 2
  • 3
  • 4
  • 5

第五步 SystemServer.init2

frameworks/base/service/java/com/android/server/SystemServer.java
  • 1

创建了一个ServerThread的线程,入口函数为run方法

    Thread thr = new ServerThread();
    thr.setName("android.server.ServerThread");
    thr.start();
  • 1
  • 2
  • 3

第6步 ServerThread.run

frameworks/base/services/java/com/android/server/SystemServer.java
  • 1
6.1 创建一个消息循环
Looper.prepare();
  • 1
6.2 启动系统服务
try{ 
 //启动AMS,没有被注册到ServiceManager
   context = ActivityManagerService.main(factoryTest);

 //启动PackageManagerService,立即被注册到ServiceManager
    pm = PachageManagerService.main(context,factoryTest!=
         SystemServer.FACTORY_TEST_OFF);

 //注册AMS到ServiceManager
     ActivityManagerService.setSystemProcess();

 //启动ContentService,立即被注册到ServiceManager
     ContentService.main(context,factoryTest==
                      SystemServer.FACTORY_TEST_LOW_LEVEL);

 //启动WMS,没有被注册到ServiceManager
     wm = WindowManagerService.main(context,power,
        factoryTest!=SystemServer,FACTORY_TEST_LOW_LEVEL);
 //注册WMS到ServiceManager
     ServiceManager.addService(Context.WINDOW_SERVICE,wm);

     }catch(RuntimeException e){}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
6.2.1 AMS的启动,启动后没有被立即添加到 ServiceManager

AMS在ActivityManagerService的main方法启动。

frameworks/base/servers/java/android/server/am/ActivityManagerService.java

public static final Context main(int factoryTest){
//创建一个 AThread线程,在线程中实例化一个AMS对象,就是系统的 AMS。
    AThread thr = new AThread();
    thr.start();
    synchronized(thr){
    while(thr.mService==null){
        try{
             thr.wait();
        } catch(InterruptedException e){}
    }
    ActivityManagerService m = thr.mService;
    mSelf = m;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

AThread创建AMS对象

static class AThread extends Thread{
    ActivityManagerService mService;
    public void run(){
    Looper.prepare();
    ActivityManagerService mm = new ActivityManagerService();
    synchronized(this){
    mService = m;
    notifyAll();
    }
    Looper.loop();
}}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

此时 AMS刚被实例化,还没有注册到ServiceManager。

6.2.2 PMS启动后立即被添加到ServiceManager
frameworks/base/services/java/com/android/server/PackageManagerService.java

public static final IPackageManager main(Context context,boolean factoryTest){
    PackageManagerService m = new PackageManagerService(context,factoryTest);
    ServiceManager.addService("package",m);
    return m;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
6.2.3 注册AMS到ServiceManager

ActivityManageService.setSystemProcess();

ActivityManagerService m = mSelf;
ActivityManagerService.addService("activity",m);
  • 1
  • 2
6.2.4 启动ContentService
frameworks/base/core/java/android/content/ContentService.java

public final class ContentService extends IContentService.stub{
    public static IContentService main(Context context,
                                        boolean factoryTest){
    ContentService service = new ContentService(context,
                            factoryTest);
    ServiceManager.addService("content",service);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
6.2.5 WMS的启动

WindowManagerService的创建与ActivityManagerService类似。

6.2.6 注册WMS到ServiceManager
ServiceManager.addService("window",wm);
  • 1
6.3 使当前线程进入消息循环中
Looper.loop(); 
  • 1
至此,System进程就将系统的关键服务启动完毕, 包括ActivityManagerService,PackageManagerService,ContentService,WindowManagerService,其他进程可以通过 ServiceManager获取服务的代理对象

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
     class main
     socket zygote stream 660 root system 
   
     第一行表示zygote进程是以服务的形式启动的,其对应的可执行程序是/system/bin/app_process,后面四个参数是它的启动参数。第二名表示在Zygote启动过程中,要在其内部创建一个名为zygote的socket,它在Linux下的权限是666,即所有用户多可以对它进行读写。
     因为Zygote是以service的形式启动,所以在init启动过程中,android-5.1.0_r3\android5.1\system\core\init\init.c的service_start()函数会被调用。
    
     service_start函数的主要工作是:
  • 通过fork()方法创建一个新的子线程,即Zygote线程
  • 调用create_socket()函数创建启动脚本中的zygote socket,并保存该socket的int型的文件描述符。创建时,还会为此socket创建一个类型为AF_UNIX的Socket地址,并调用bind()方法将socket与此地址进行绑定。该socket还有一个对应的设备文件,/dev/socket/zygote。
  • 创建完socket后,会调用publish_socket()函数将该socket发布到系统中。采用环境变量的方式,ANDROID_SOCKET_zygote -- socket的文件描述符。
  • 调用execve(svc->args[0]),执行app_process的主程序app_main.cpp。此时,代码进入到native层。
 
     app_main.cpp的main函数的主要工作是:
  • 通过调用AppRuntime::start()函数,通过JNI的方式,进一步启动Zygote:AppRuntime.start("com.android.internal.os.ZygoteInit", args);args是参数列表,其中较重要的是标记是否要启动System进程、记录socket名称。
 
     ZygoteInit的main函数的主要工作是:
  • 调用registerZygoteSocket("zygote")函数获取到zygote socket文件描述,并根据此描述符创建一个本地服务Socket:LocalServerSocket。这个服务Socket是用来等待Activity管理服务ActivityManagerService请求Zygote进程创建新的应用程序进程的。
  • 调用startSystemServer()函数启动System进程,以便它可以将系统的关键服务启动起来。该方法中通过forkSystemServer()函数创建System进程,最后调用handleSystemServerProcess()进一步启动System进程("com.android.server.SystemServer",通过反射技术),"--runtime-init"表示需要提供Binder服务。
  • 调用runSelectLoop()来等待Activity管理服务ActivityManagerService请求Zygote进程创建新的应用程序进程。
 
     SystemServer的main函数的主要工作是:
  • 启动一个线程,启动系统的关键服务。

猜你喜欢

转载自www.cnblogs.com/qiangge-python/p/10584372.html