android系统SystemServer进程启动流程分析

219 阅读10分钟

目录

一,SystemServer整体框架

二,SystemServer启动源码分析

2.1,重要的概念

2.2,启动入口

2.3,创建对应进程的binder

三,binder驱动和binder线程池

四,SystemServer真正启动方法

4.1 SystemServer main方法里面主要做了几件事情

1)创建SystemServiceManager管理所有的服务

2)创建上下文createSystemContext,

3)启动核心服务和其他服务

4)Looper.prepareMainLooper()Looper.prepareMainLooper())

5)Looper.loop()Looper.loop())

4.2 分析startBootstrapServices

4.3 分析startBootstrapServices

4.4 分析startBootstrapServices

五,结束语


一,SystemServer整体框架

1.1,SystemServer类图

​编辑

1.1,SystemServer时序图

​编辑

二,SystemServer启动源码分析

2.1,重要的概念

在开始讲解源码之前,需要搞清楚几个重要的概念

对象含义备注
SystemServerSystemServer是一个进程,这个进程是Android系统中的核心进程,该进程由zygote进程在开机时fork而出,管理了系统的核心服务,整个安卓系统只有一个SystemServer进程属于进程级别是一个单独的进程
SystemServiceManagerSystemServiceManager是为了管理SystemServer进程里面运行的90+多个服务(Services)设置的一个管理者角色,这个仅仅用于同一个进程之间使用普通的java对象
LocalServicesLocalServices是Android系统中用于在同一进程中注册和获取LocalService的工具类。它维护了一个ArrayMap来存储不同类型的LocalService实例,确保每个类型只对应一个实例。通过addService()方法注册服务,getService()方法获取服务。这些服务不是Binder对象,仅限于同一进程内通信,类似于ServiceManager但更私有化,和ServiceManager最本质的区别是ServiceManager管理的服务都是binder服务,这些服务都是可以在不同进程之间跑的对象管理的是普通的服务,只能在同一个进程之间使用的服务,不具备进程之间通信能力的服务,各个系统service在启动的过程中都会调用LocalServices.addService()把自己的local service注册到LocalServices中,比如AMS,WMS,PMS 注册到LocalServices中的service不是Binder对象,只能在同一个进程中使用,除此之外它的的使用方式和ServiceManager相似。普通的java对象
SystemServiceRegistryAndroid应用层将系统服务注册相关的API放在了SystemServiceRegistry类中,因为android系统的代码特别庞大,为了给上层应用开发者提供可以很方便的获取到被SystemServer进程管理的所有服务,那么通过SystemServiceRegistry可以方便获取比如ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);最终是调用到ServiceManager获取对应服务的Ibinder对象,普通的java对象
SystemService为了统一管理SystemServer进程运行的所有服务提供的一个统一接口对象普通的java对象
ServiceManagerServiceManager  android系统的服务守护进程,管理了整个android系统的所有Ibinder对象是一个单独的进程,和Zygote平级,都是由Init进程fork出来的

上面说了这么多,一图胜千言,下面看具体的

​编辑

2.2,启动入口

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

的main方法里面

if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
                if (r != null) {
                    r.run();
                    return;
                }
            }

fork出来,之所以后面可以通过java反射的方式调用到SystemServer,是因为在fork之前传递的参数重明确的说明了对象com.android.server.SystemServer,通知指定了运行所在的进程是在--nice-name=system_server

private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
        ....................................................................................
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };
        ....................................................................................

最后通过反射的方法调用MethodAndArgsCaller对象以后调用到SystemServer的main方法

static class MethodAndArgsCaller implements Runnable {
        /** method to call */
        private final Method mMethod;

        /** argument array */
        private final String[] mArgs;

        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });

2.3,创建对应进程的binder

上面只是完成了SystemServer的启动,但是此时SystemServer并不具备进程之间通信的能力,所以在SystemServer启之后,立刻打开binder,做进程映射,

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

 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();

        RuntimeInit.commonInit();
        ZygoteInit.nativeZygoteInit();
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

此时通过nativeZygoteInit调用到jni,frameworks/base/core/jni/AndroidRuntime.cpp

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

最后调用到/Volumes/aosp/android-8.1.0_r52/frameworks/base/cmds/app_process/app_main.cpp

virtual void onZygoteInit()
{
    sp<ProcessState> proc = ProcessState::self();
    ALOGV("App process: starting thread pool.\n");
    proc->startThreadPool();
}

/Volumes/aosp/android-8.1.0_r52/frameworks/native/libs/binder/ProcessState.cpp

ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(driver))
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
   ............................
{
    if (mDriverFD >= 0) {
............................
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
...................................
        }
    }
............................v
}

可以看到这里其实就是做了三件事情

1)打开binder驱动,和binder通信,通过

status_t result = ioctl(fd, BINDER_VERSION, &vers);

2)mmap内存映射

mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);

3)设置binder驱动最多可以创建的线程数,

result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);

#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
#define DEFAULT_MAX_BINDER_THREADS 15

所以通过这里可以看到binder之前通信的时候最大的传递数据大小是1M-8K(同步),异步场景下是减半,binder驱动最多可以创建的线程数是15个,不包含主线程,包含的话是16个,上面这部分牵扯到binder驱动源码的分析,后续会用单独的文章讲解,敬请期待

2.4 创建binder线程池

/Volumes/aosp/android-8.1.0_r52/frameworks/native/libs/binder/ProcessState.cpp

 virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }

启动binder线程池 

void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {
        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}

设置binder线程名字:Binder:%d_%X", pid, s,通过这段代码可以看到binder线程的名字是从0递增

void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        String8 name = makeBinderThreadName();
        ALOGV("Spawning new pooled thread, name=%s\n", name.string());
        sp<Thread> t = new PoolThread(isMain);
        t->run(name.string());
    }
}

可以看到 PoolThread本身就是一个线程,在创建进程的时候此时启动的线程就是主线程,也是唯一的一个主线程,ProcessState是Application在Framework Native层面的对象,代表一个进程


class PoolThread : public Thread
{
public:
    explicit PoolThread(bool isMain)
        : mIsMain(isMain)
    {
    }
    
protected:
    virtual bool threadLoop()
    {
        IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
    }
    
    const bool mIsMain;
};

在ProcessState里面调用了run方法以后,最后调用到了/Volumes/aosp/android-8.1.0_r52/system/core/libutils/Threads.cpp的run----->_threadLoop

status_t Thread::run(const char* name, int32_t priority, size_t stack)
{
    ................................................

    bool res;
    if (mCanCallJava) {
        res = createThreadEtc(_threadLoop,
                this, name, priority, stack, &mThread);
    } else {
        res = androidCreateRawThreadEtc(_threadLoop,
                this, name, priority, stack, &mThread);
    }

     ................................................
    return NO_ERROR;
}

int Thread::_threadLoop(void* user)
{
    ----------------------------------------------------------------------

    do {
        bool result;
        if (first) {
            first = false;
            self->mStatus = self->readyToRun();
            result = (self->mStatus == NO_ERROR);

            if (result && !self->exitPending()) {
               ----------------------------------------------------------------------

                result = self->threadLoop();
            }
        } else {
            result = self->threadLoop();
        }

         
    } while(strong != 0);

    return 0;
}

到这里以后会开始binder线程池,通过/Volumes/aosp/android-8.1.0_r52/frameworks/native/libs/binder/IPCThreadState.cpp ,IPCThreadState.cpp代表一个IPC线程池管理

IPCThreadState* IPCThreadState::self()
{
   ---------------------------------------------

    pthread_mutex_lock(&gTLSMutex);
    if (!gHaveTLS) {
        int key_create_value = pthread_key_create(&gTLS, threadDestructor);
        if (key_create_value != 0) {
            pthread_mutex_unlock(&gTLSMutex);
   ---------------------------------------------

            return NULL;
        }
        gHaveTLS = true;
    }
    pthread_mutex_unlock(&gTLSMutex);
    goto restart;
}

到这里为止才开始创建了一个真正的线程pthread_key_create,目前这种场景下只是创建了一个线程,所以读者有时候觉得joinThreadPool线程池不太明白,其实joinThreadPool后续还会被binder驱动调用,创建更多的线程,所以这个方法的名字叫做线程池

对于isMain=true的情况下, command为BC_ENTER_LOOPER,代表的是Binder主线程,不会退出的线程;
对于isMain=false的情况下,command为BC_REGISTER_LOOPER,表示是由binder驱动创建的线程。

Binder系统中可分为3类binder线程:

Binder主线程:进程创建过程会调用startThreadPool()过程中再进入spawnPooledThread(true),来创建Binder主线程。编号从1开始,也就是意味着binder主线程名为binder_1,并且主线程是不会退出的。
Binder普通线程:是由Binder Driver来根据是否有空闲的binder线程来决定是否创建binder线程,回调spawnPooledThread(false) ,isMain=false,该线程名格式为binder_x。
Binder其他线程:其他线程是指并没有调用spawnPooledThread方法,而是直接调用IPC.joinThreadPool(),将当前线程直接加入binder线程队列。例如: mediaserver和servicemanager的主线程都是binder线程,但system_server的主线程并非binder线程

对于joinThreadPoo其实最主要做了三件事情

1)processPendingDerefs 清除队列的引用

2)getAndExecuteCommand,如果有下一条命令的话,执行下一条命令,没有的话在这里等待,只有主进程创建的主线程会一直在这里等待,非主线程出现timeout则线程退出

3)mOut.writeInt32(BC_EXIT_LOOPER);推出循环以后通知binde驱动

4)talkWithDriver 和binder驱动通信交互数据

void IPCThreadState::joinThreadPool(bool isMain)
{
    LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());

    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);

    status_t result;
    do {
        processPendingDerefs();
        // now get the next command to be processed, waiting if necessary
        result = getAndExecuteCommand();

        if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
            ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
                  mProcess->mDriverFD, result);
            abort();
        }

        // Let this thread exit the thread pool if it is no longer
        // needed and it is not the main process thread.
        if(result == TIMED_OUT && !isMain) {
            break;
        }
    } while (result != -ECONNREFUSED && result != -EBADF);

    LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%d\n",
        (void*)pthread_self(), getpid(), result);

    mOut.writeInt32(BC_EXIT_LOOPER);
    talkWithDriver(false);
}

这块需要结合binder驱动源码来讲解,参考下面

三,binder驱动和binder线程池

binder驱动源码android-msm-angler-3.10-oreo-r6/msm/drivers/staging/android/binder.c

​编辑

四,SystemServer真正启动方法

4.1 SystemServer main方法里面主要做了几件事情

1)创建SystemServiceManager管理所有的服务

2)创建上下文createSystemContext,

这里可以看到会创建ActivityThread,因为systemserver是一个进程和app一样,都有自己的looper

,同时把自己也注入到ActivityThread,让ActivityThread持有自己的IBinder对象

mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool.get();

3)启动核心服务和其他服务

try {
            traceBeginAndSlog("StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();

4)Looper.prepareMainLooper()

5)Looper.loop()

永远循环,这样子SystemServer进程才不会推出

4.2 分析startBootstrapServices

.....................................
Installer installer = mSystemServiceManager.startService(Installer.class);
   

 
        mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
    
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
   

    
        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
 
        mActivityManagerService.initPowerManagement();
    

     
        mSystemServiceManager.startService(LightsService.class);
        
        mDisplayManagerService = 
       mSystemServiceManager.startService(DisplayManagerService.class);
    
        
 mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
         .....................................

4.3 分析startBootstrapServices

mSystemServiceManager.startService(DropBoxManagerService.class);
      
mSystemServiceManager.startService(BatteryService.class);
       
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
       
mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        mFirstBoot = mPackageManagerService.isFirstBoot();

      mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();

AMS启动之后会通过mActivityManagerService.setSystemProcess();

添加到ServiceManager

public void setSystemProcess() {
        try {
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
            ServiceManager.addService("meminfo", new MemBinder(this));
            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
            ServiceManager.addService("dbinfo", new DbBinder(this));
            if (MONITOR_CPU_USAGE) {
                ServiceManager.addService("cpuinfo", new CpuBinder(this));
            }
            ServiceManager.addService("permission", new PermissionController(this));
            ServiceManager.addService("processinfo", new ProcessInfoService(this));

            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

          
                updateLruProcessLocked(app, false, null);
               
            }
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(
                    "Unable to find android system package", e);
        }
    }

4.4 分析startBootstrapServices

  

wm = WindowManagerService.main(context, inputManager,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
                    !mFirstBoot, mOnlyCore, new PhoneWindowManager());
            ServiceManager.addService(Context.WINDOW_SERVICE, wm);
            ServiceManager.addService(Context.INPUT_SERVICE, inputManager);

可以看到所有的Service在启动以后,都会添加到ServiceManager进程来管理,通过这里就可以看到ServiceManager是整个android系统的大管家

五,结束语

鉴于作者水平有限,文章之中难免有错误或者遗漏地方,欢迎大家批评指正,也欢迎大家讨论,积极评论哈,谢谢