SystemServer分析过程

本文详细介绍了Android系统中SystemServer进程的启动过程,从zygote进程fork出SystemServer,到ZygoteInit类的startSystemServer方法,再到SystemServer.java的main函数。主要步骤包括设置uid/gid,forkSystemServer,handleSystemServerProcess,以及SystemServer的run方法,涉及服务初始化,Binder服务,Context创建,SystemServiceManager,以及服务启动等关键环节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SystemServer是由zygote进程fork出来的进程.

Step 1 如下代码,启动zygote进程以后,SystemServer进程由zygote start出来

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


Step 2. RuntimeInit.zygoteInit 中main调用StartSystemServer方法来启动SystemServer,接下来具体分析下startSystemServer方法.

       这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

    public static void main(String argv[]) {
        try {
            RuntimeInit.enableDdms();
            // Start profiling the zygote initialization.
            SamplingProfilerIntegration.start();

            boolean startSystemServer = false;
            String socketName = "zygote";
            String abiList = null;
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                    abiList = argv[i].substring(ABI_LIST_ARG.length());
                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }

            if (abiList == null) {
                throw new RuntimeException("No ABI list supplied.");
            }

            registerZygoteSocket(socketName);
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
            preload();
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());

            // Finish profiling the zygote initialization.
            SamplingProfilerIntegration.writeZygoteSnapshot();

            // Do an initial gc to clean up after startup
            gcAndFinalize();

            // Disable tracing so that forked processes do not inherit stale tracing tags from
            // Zygote.
            Trace.setTracingEnabled(false);

            if (startSystemServer) {
                startSystemServer(abiList, socketName);
            }

            Log.i(TAG, "Accepting command socket connections");
            runSelectLoop(abiList);

            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }
private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
        long capabilities = posixCapabilitiesAsBits(
            OsConstants.CAP_BLOCK_SUSPEND,
            OsConstants.CAP_KILL,
            OsConstants.CAP_NET_ADMIN,
            OsConstants.CAP_NET_BIND_SERVICE,
            OsConstants.CAP_NET_BROADCAST,
            OsConstants.CAP_NET_RAW,
            OsConstants.CAP_SYS_MODULE,
            OsConstants.CAP_SYS_NICE,
            OsConstants.CAP_SYS_RESOURCE,
            OsConstants.CAP_SYS_TIME,
            OsConstants.CAP_SYS_TTY_CONFIG
        );
        /* Hardcoded command line to start the system server */
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

在startSystemServer方法中主要做了三件事情

1.设置uid 和 gid 为1000.SystemServer执行类为com.android.server.SystemServer

2.调用zygote类中forkSystemServer来fork出来子进程.(注意对于fork出来的SystemServer,Zygote进程会进行判断是否启动成功,如果启动不成功Zygote进程会自动退出,另外有一个SetSigChildHander()函数还需要处理SIGCHLD信号的函数SigChidHander,其中SigChidHander来接受子进程死亡的信号后,除了调用waitpid()来防止子进程变成僵尸进程,还需要判断子进程是否是SystemServer进程,如果是systemServer被杀死,zygote则会自杀,这样就导致Init进程杀死所有用户进程并且重启Zygote)

static void SigChldHander(int signal_number){
    pid_t pid;
    while((pid = waitpid(-1, &status, WNOHANG)) > 0){
     ......
     if(pid == gSystemServerPid)
     {
         kill(getpid(), SIGKILL) ;//如果死亡的是SystemServer进程,Zygote将退出
     }
    }
}

3.fork出SystemServer进程后,在fork出的进程中调用handleSystemServerProcess()来初始化SystemServer进程.

//这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中

    /**  
     * Finish remaining work for the newly forked system server process.  
     */  
    private static void handleSystemServerProcess(  
            ZygoteConnection.Arguments parsedArgs)  
            throws ZygoteInit.MethodAndArgsCaller {  
      
        closeServerSocket();  
      
        // set umask to 0077 so new files and directories will default to owner-only permissions.  
        Os.umask(S_IRWXG | S_IRWXO);  
      
        if (parsedArgs.niceName != null) {  
            Process.setArgV0(parsedArgs.niceName);  
        }  
      
        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");  
        if (systemServerClasspath != null) {  
            performSystemServerDexOpt(systemServerClasspath);  
        }  
      
        if (parsedArgs.invokeWith != null) {  
            String[] args = parsedArgs.remainingArgs;  
            // If we have a non-null system server class path, we'll have to duplicate the  
            // existing arguments and append the classpath to it. ART will handle the classpath  
            // correctly when we exec a new process.  
            if (systemServerClasspath != null) {  
                String[] amendedArgs = new String[args.length + 2];  
                amendedArgs[0] = "-cp";  
                amendedArgs[1] = systemServerClasspath;  
                System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);  
            }  
      
            WrapperInit.execApplication(parsedArgs.invokeWith,  
                    parsedArgs.niceName, parsedArgs.targetSdkVersion,  
                    VMRuntime.getCurrentInstructionSet(), null, args);  
        } else {  
            ClassLoader cl = null;  
            if (systemServerClasspath != null) {  
                cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());  
                Thread.currentThread().setContextClassLoader(cl);  
            }  
      
            /*  
             * Pass the remaining arguments to SystemServer.  
             */  
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);  
        }  
      
        /* should never reach here */  
    }  

这里的方法作用是

1)通过closeServerSocket();函数关闭了从zygote进程来的子进程,因为这里用不到,

2)接着将SystemServer进程umask设置为0077,这样创建的文件属性就是0700了

只有SystemServer进程可以访问

3)将进程名称参数改成''system_server'.

Step 3 接下来来分析下SystemServer核心入口main函数.

这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中

    public static void main(String[] args) {
        new SystemServer().run();
    }

 private void run() {
        // If a device's clock is before 1970 (before 0), a lot of
        // APIs crash dealing with negative numbers, notably
        // java.io.File#setLastModified, so instead we fake it and
        // hope that time from cell towers or NTP fixes it shortly.
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }

        // If the system has "persist.sys.language" and friends set, replace them with
        // "persist.sys.locale". Note that the default locale at this point is calculated
        // using the "-Duser.locale" command line flag. That flag is usually populated by
        // AndroidRuntime using the same set of system properties, but only the system_server
        // and system apps are allowed to set them.
        //
        // NOTE: Most changes made here will need an equivalent change to
        // core/jni/AndroidRuntime.cpp
        if (!SystemProperties.get("persist.sys.language").isEmpty()) {
            final String languageTag = Locale.getDefault().toLanguageTag();

            SystemProperties.set("persist.sys.locale", languageTag);
            SystemProperties.set("persist.sys.language", "");
            SystemProperties.set("persist.sys.country", "");
            SystemProperties.set("persist.sys.localevar", "");
        }

        // Here we go!
        Slog.i(TAG, "Entered the Android system server!");
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());

        // In case the runtime switched since last boot (such as when
        // the old runtime was removed in an OTA), set the system
        // property so that it is in sync. We can't do this in
        // libnativehelper's JniInvocation::Init code where we already
        // had to fallback to a different runtime because it is
        // running as root and we need to be the system user to set
        // the property. http://b/11463182
        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

        // Enable the sampling profiler.
        if (SamplingProfilerIntegration.isEnabled()) {
            SamplingProfilerIntegration.start();
            mProfilerSnapshotTimer = new Timer();
            mProfilerSnapshotTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    SamplingProfilerIntegration.writeSnapshot("system_server", null);
                }
            }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
        }

        // Mmmmmm... more memory!
        VMRuntime.getRuntime().clearGrowthLimit();

        // The system server has to run all of the time, so it needs to be
        // as efficient as possible with its memory usage.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

        // Some devices rely on runtime fingerprint generation, so make sure
        // we've defined it before booting further.
        Build.ensureFingerprintProperty();

        // Within the system server, it is an error to access Environment paths without
        // explicitly specifying a user.
        Environment.setUserRequired(true);

        // Ensure binder calls into the system always run at foreground priority.
        BinderInternal.disableBackgroundScheduling(true);

        // Prepare the main looper thread (this thread).
        android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);
        android.os.Process.setCanSelfBackground(false);
        Looper.prepareMainLooper();

        // Initialize native services.
        System.loadLibrary("android_servers");
        nativeInit();
        // Check whether we failed to shut down last time we tried.
        // This call may not return.
        performPendingShutdown();

        // Initialize the system context.
        createSystemContext();

        // Create the system service manager.
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

        // Start services.
        try {
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        }

        // For debug builds, log event loop stalls to dropbox for analysis.
        if (StrictMode.conditionallyEnableDebugLogging()) {
            Slog.i(TAG, "Enabled StrictMode for system server main thread.");
        }

        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

有以上代码可以知道main 函数 调用了run方法'new SystemServer().run();',

接下来我们具体分析下run方法实现的内容

1.main 函数里面首先要初始化工作,然后加载libandroid_servers.so文件.

改函数libandroid_servers.so实现库代码如下.

2.调用nativeInit()方法初始化native层Binder服务.

3.调用createSystemContext()来获取Context.

4.创建SystemServiceManager的对象mSystemServiceManager.这个对象负责系统Service启动.

5.调用  startBootstrapServices();startCoreServices(); startOtherServices();创建并且运行所有java服务.

6.调用Loop.loop进入处理消息循环.

2.启动各项服务包括AMS PMS WMS等其他服务


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值