Android 启动过程分析 (二)


接上文Android 启动过程分析 (一), 从这里开始android启动分为两条线走,分别是:

startSystemServer(); ---------- Zygote 的子进程

runSelectLoopMode(); /*Zygote进程进入无限循环,不再返回,执行孵化工作具体下面接着分析 */

我们分别分析,先来阐述startSystemServer()进程:

源码位置:frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

/** Prepare the arguments and fork for the system server process.    */
    private static boolean startSystemServer()  throws MethodAndArgsCaller, RuntimeException {       /* 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,3001,3002,3003",
            "--capabilities=130104352,130104352",
            "--runtime-init",
            "--nice-name=system_server",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;
        try {
            parsedArgs = new ZygoteConnection.Arguments(args);  
/* 将上述参数列表构建为 ZygoteConnection.Arguments 类型   */
            /** Enable debugging of the system process if *either* the command line flags
             * indicate it should be debuggable or the ro.debuggable system property
             * is set to "1" */
            int debugFlags = parsedArgs.debugFlags;
            if ("1".equals(SystemProperties.get("ro.debuggable")))
                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;

            /* fork system_server进程 */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids, debugFlags, null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }
        /* 子进程执行下面的代码 */
        if (pid == 0) {
            handleSystemServerProcess(parsedArgs);
        }
	/* 父进程zygote在这里正常返回 */
        return true;
    }
   /*** Finish remaining work for the newly forked system server process.     */
    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {
        closeServerSocket();  /*在子进程中关闭父进程创建的socket,子进程执行新的工作 */
        /* Pass the remaining arguments to SystemServer."--nice-name=system_server com.android.server.SystemServer"      */
        RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
        /* should never reach here */
    }

下面分析具体启动system_server的流程:

源码位置:frameworks\base\core\java\com\android\internal\os\RuntimeInit.java

 public static final void zygoteInit(String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
        System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));

        commonInit();
        zygoteInitNative();
        int curArg = 0;
        for ( /* curArg */ ; curArg < argv.length; curArg++) {
            String arg = argv[curArg];
            if (arg.equals("--")) {
                curArg++;
                break;
            } else if (!arg.startsWith("--")) {
                break;
            } else if (arg.startsWith("--nice-name=")) {
                String niceName = arg.substring(arg.indexOf('=') + 1);
                Process.setArgV0(niceName);
            }
        }
        if (curArg == argv.length) {
            Slog.e(TAG, "Missing classname argument to RuntimeInit!");
            // let the process exit
            return;
        }
        //Remaining arguments are passed to the start class's static main
        String startClass = argv[curArg++];
        String[] startArgs = new String[argv.length - curArg];
        System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
/* 通过该函数调用执行startClass类的main函数,带参数 system_server  */
        invokeStaticMain(startClass, startArgs);
    }
调用如下:
  private static void invokeStaticMain(String className, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {

        // We want to be fairly aggressive about heap utilization, to avoid
        // holding on to a lot of memory that isn't needed.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);

        Class<?> cl;

        try {
            cl = Class.forName(className);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }

        /*    这里已经获取到了mian方法,已下面的函数调用来执行      */
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }

调用com.android.server.SystemServer类的main函数:

源码位置:frameworks\base\core\java\android\os\SystemService.java

  public static void main(String[] args) {
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
             Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }
        if (SamplingProfilerIntegration.isEnabled()) {
            SamplingProfilerIntegration.start();
            timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    SamplingProfilerIntegration.writeSnapshot("system_server");
                }
            }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
        }
        // 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);
        System.loadLibrary("android_servers");
        init1(args);    //最主要执行的是init1函数;
    }

实际上就是main--->init1(system_init)--->init2(systemThread)之后进入Loop.loop();

init1实际是通过jni层的frameworks\base\services\jni\com_android_server_SystemServer.cpp文件中的jni接口调用system_init();

extern "C" int system_init();

static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
    system_init();
}
static JNINativeMethod gMethods[] = {
    /* name, signature, funcPtr */
    { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },
};
system_init 的实现位于frameworks\base\cmds\system_server\library\System_init.cpp
extern "C" status_t system_init()
{
    LOGI("Entered system_init()");    
    sp<ProcessState> proc(ProcessState::self());    
    sp<IServiceManager> sm = defaultServiceManager();
    LOGI("ServiceManager: %p\n", sm.get());    
    sp<GrimReaper> grim = new GrimReaper();
    sm->asBinder()->linkToDeath(grim, grim.get(), 0);    
    char propBuf[PROPERTY_VALUE_MAX];
    property_get("system_init.startsurfaceflinger", propBuf, "1");
    if (strcmp(propBuf, "1") == 0) {
        // Start the SurfaceFlinger
        SurfaceFlinger::instantiate();    //启动SurfaceFlinger
    }

    // Start the sensor service
    SensorService::instantiate();  //启动SensorService

    //在模拟器上 audioflinger 等几个服务与设备上的启动过程不一样,所以我们在这里启动他们;
    if (!proc->supportsProcesses()) {

        // Start the AudioFlinger
        AudioFlinger::instantiate();   //启动AudioFlinger

        // Start the media playback service
        MediaPlayerService::instantiate();  //启动MediaPlayerService

        // Start the camera service
        CameraService::instantiate();  //启动CameraService

        // Start the audio policy service
        AudioPolicyService::instantiate();  //启动AudioPolicyService
    }
    // 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.
    LOGI("System server: starting Android runtime.\n");
    
    AndroidRuntime* runtime = AndroidRuntime::getRuntime();

    LOGI("System server: starting Android services.\n");
    runtime->callStatic("com/android/server/SystemServer", "init2");
//在这里执行com.android.server.SystemServer类的init2函数,下面详细分析;
        
    // If running in our own process, just go into the thread
    // pool.  Otherwise, call the initialization finished
    // func to let this process continue its initilization.
    if (proc->supportsProcesses()) {
        LOGI("System server: entering thread pool.\n");
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
        LOGI("System server: exiting thread pool.\n");
    }
    return NO_ERROR;
}

com.android.server.SystemServer类的init2函数执行的是ServerThread线程

public static final void init2() {
        Slog.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        thr.start();
}

ServerThread线程的run函数启动android中大部分的service,并最后进入Loop.loop()

 public void run() {
             … ...
             // 主要的Service启动
        try {
            Slog.i(TAG, "Entropy Service");
            ServiceManager.addService("entropy", new EntropyService());

            Slog.i(TAG, "Power Manager");
            power = new PowerManagerService();
            ServiceManager.addService(Context.POWER_SERVICE, power);

            Slog.i(TAG, "Activity Manager");
            context = ActivityManagerService.main(factoryTest);
      
            Slog.i(TAG, "Window Manager");
            wm = WindowManagerService.main(context, power,
                    factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL);
            ServiceManager.addService(Context.WINDOW_SERVICE, wm);
           … …
/* 其它大部分的service的启动类似,这里不再贴出代码  ,有兴趣可以查看源文件  */
/* 这里说明一下,java部分的servicemanager调用的一系列添加、删除等的service操作盘实际最终还是通过binder机制由之前的servicemanager进程来最终完成的;
在java层由一个ServiceManagerNative 类来实现IServiceManager 定义的这些接口 */
         Looper.loop();
        Slog.d(TAG, "System ServerThread is exiting!");
    }
}

至此,分支startsystemserver分析完成;

再次回到frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

下面再来分析Zygote进程:runSelectLoopMode();

runSelectLoopMode-----done = peers.get(index).runOnce();

  private static void runSelectLoopMode() throws MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList();
        ArrayList<ZygoteConnection> peers = new ArrayList();
        FileDescriptor[] fdArray = new FileDescriptor[4];
        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);
        int loopCount = GC_LOOP_COUNT;
        while (true) {
            int index;
               if (loopCount <= 0) {
                gc();
                loopCount = GC_LOOP_COUNT;
            } else {
                loopCount--;
            }
            try {
                fdArray = fds.toArray(fdArray);
                index = selectReadable(fdArray);  /* Select 读取相关socket,在下面进行处理 */
            } catch (IOException ex) {
                throw new RuntimeException("Error in select()", ex);
            }
            if (index < 0) {
                throw new RuntimeException("Error in select()");
            } else if (index == 0) {
                ZygoteConnection newPeer = acceptCommandPeer();
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            } else {
                boolean done;
                done = peers.get(index).runOnce();
		/* 调用 ZygoteConnecttion的runOnce函数,在runOnce函数中通过Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids, parsedArgs.debugFlags, rlimits);
调用,Forks a new VM instance.
	然后,在runOnce函数中通过
	if (pid == 0) {
            // in child
            handleChildProc(parsedArgs, descriptors, newStderr);
	在子进程中处理相关的操作;
	父进程继续在 runSelectLoopMode的while(true)循环中select等待;
*/
               if (done) {
                    peers.remove(index);
                    fds.remove(index);
                }
            }
        }
    }

    1. init进程启动MediaServer

init.rc文件中有如下命令:servicemedia /system/bin/mediaserver

执行的mediaserver源码位置:frameworks/base/media/mediaserver/main_mediaserver.cpp

intmain(int argc, char** argv)

{

sp<ProcessState>proc(ProcessState::self());

sp<IServiceManager> sm =defaultServiceManager();

LOGI("ServiceManager: %p",sm.get());

AudioFlinger::instantiate();

MediaPlayerService::instantiate();

CameraService::instantiate();

AudioPolicyService::instantiate();

ProcessState::self()->startThreadPool();

IPCThreadState::self()->joinThreadPool();

}

分别调用相关的服务的instantiate函数启动服务;实际上调用的就是

sp<IServiceManager>sm(defaultServiceManager());

sm->addService(String16(SERVICE::getServiceName()),new SERVICE());

最终由servicemanager来将服务的添加到服务列表中,以便处理客户端的查询和访问;

至于如何处理,在各服务部分分析,通信部分就是binder机制,这个也需要单独分析;

本文内容分析到这,以上

2011-07-02 XA




  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值