当前位置: 首页 > news >正文

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

目录

一,SystemServer整体框架

二,SystemServer启动源码分析

2.1,重要的概念

2.2,启动入口

2.3,创建对应进程的binder

三,binder驱动和binder线程池

四,SystemServer真正启动方法

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

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

2)创建上下文createSystemContext,

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

4)Looper.prepareMainLooper()

5)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对象

SystemServiceRegistry

Android应用层将系统服务注册相关的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系统的大管家

五,结束语

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


文章转载自:
http://awe.elldm.cn
http://beatlemania.elldm.cn
http://checker.elldm.cn
http://bootee.elldm.cn
http://careful.elldm.cn
http://absurd.elldm.cn
http://baalish.elldm.cn
http://chemicophysical.elldm.cn
http://accessories.elldm.cn
http://chelonian.elldm.cn
http://appointor.elldm.cn
http://backhander.elldm.cn
http://ancientry.elldm.cn
http://antebrachium.elldm.cn
http://amimeche.elldm.cn
http://cardsharping.elldm.cn
http://captivation.elldm.cn
http://birthright.elldm.cn
http://alawite.elldm.cn
http://alimental.elldm.cn
http://celtic.elldm.cn
http://apartment.elldm.cn
http://centenary.elldm.cn
http://albumin.elldm.cn
http://basecoat.elldm.cn
http://chastely.elldm.cn
http://atli.elldm.cn
http://believer.elldm.cn
http://adieu.elldm.cn
http://blacksnake.elldm.cn
http://www.dtcms.com/a/30748.html

相关文章:

  • 002 SpringCloudAlibaba整合 - Feign远程调用、Loadbalancer负载均衡
  • 大数据学习之任务流调度系统Azkaban、Superset可视化系统
  • Cursor和Trae使用的感受
  • Spring 到 Spring Boot:配置文件管理的灵活封装与扩展
  • 爬虫第七篇数据爬取及解析
  • SpringBoot 配置文件
  • AGI觉醒假说的科学反驳:从数学根基到现实约束的深度解析
  • JavaScript变量的作用域介绍
  • 什么是矩阵账号?如何高效运营tiktok矩阵账号
  • 什么是超越编程(逾编程)(元编程?)
  • DuodooBMS源码解读之 odoo_phoenix_alarm模块
  • AI Agent实战:打造京东广告主的超级助手 | 京东零售技术实践
  • ICRA2024:CoLRIO,用于机器人群体的激光雷达测距-惯性集中状态估计
  • 虚拟机中ffplay播放RTSP流,不能播放交换机的设备,能播放虚拟机流
  • 冯·诺依曼体系结构、理解操作系统管理
  • 助力DeepSeek私有化部署服务:让企业AI落地更简单、更安全
  • TiDB 是一个分布式 NewSQL 数据库
  • 基于LangGraph和Ollama实现可调用AI搜索引擎Tavily的Agentic RAG问答机器人
  • 小程序的分包
  • Ubuntu 22.04 Install deepseek
  • 【HeadFirst系列之HeadFirst设计模式】第7天之命令模式:封装请求,轻松实现解耦!
  • Windows 下 Ollama 安装deepseek本地模型
  • Java集合框架大师课:从青铜到王者的数据结构指南(一)
  • 大白话React第一章基础入门
  • 纷析云开源版- Vue2-增加字典存储到localStorage
  • 若依按照时间段查询
  • 开源且免费的CMS系统有哪几个可以放心用?
  • 自动化之ansible(二)
  • 【反馈-建立负反馈,警惕正反馈-关键字摘要】
  • 【详细讲解在STM32的UART通信中使用DMA机制】