Android源码学习之八—系统启动过程

http://blog.csdn.net/caowenbin/archive/2010/12/31/6110751.aspx

Android 源码数量庞大,虽然对它的学习从未停止,但是整理成这样的文字,实在是费时费力的一件事情,不过好在前文已经对其基本机制加以分析,相信以此为基础,其他的内容学习起来就没那么困难了。

今天是 2010 年的最后一天了,回顾这一年,从手机操作系统的角度来看,我把重点放在了 Android 上,对 Windows Phone IPhone 没有太深入研究,正好以此做一终结,把对 Android 源码的学习告一段落。从软件工程或项目管理角度来看,今年感触也很多,可能会成为明年的重点吧,希望到时能在软件工程方法、过程、架构设计、项目管理方面也能成些文字以供交流。

做为 Android 源码学习系列的最后一文,还是应该从大的角度写点东西,想写 Parcelable Binder ,也想写 WindowsManager Dialog ,或者是系统架构、 JNI ,最后还是落笔为 Android 的系统启动过程了,原因是友人问我这方面的问题,于是偷了懒,顺手成文。

 

Android 的启动过程可以分为两个阶段,第一阶段是 Linux 的启动,第二阶段才是 Android 的启动,下面我们分别来了解一下具体的过程。

首先是 Linux 启动,这一部分我想就可以略过了,无非是 Linux Bootloader Kernel Driver 之类的,在这里唯一要提到的就是 ServiceManager ,即服务管理器,这个是做为一个进程在 Android 加载之前就被启动了,我们可以从 init.rc 中看到这个配置项:

service servicemanager /system/bin/servicemanager

ServiceManager Binder 的服务管理守护进程,是 Binder 的核心,由其使用 Binder 驱动进行 IPC 管理,关于 IPC 通讯的机制,此处不再详述。在 APP Framework 中,应用程序使用的 ServiceManager.java 就是通过 Proxy 与这个守护进程进行的通讯。

 

然后是 Android 的启动,接下来要详细描述的部分。我们还是先看一下 init.rc 中的配置

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

linux 启动以后,启动 zygote 服务进程,这个进程恰如其名:孵化器,是所有 Android 应用程序的孵化器。

 

我们来看一下 app_process 的代码,位置是在:

frameworks/base/cmds/app_process/app_main.cpp

main() 函数中有如下代码:

        if (0 == strcmp("--zygote", arg)) {

            bool startSystemServer = (i < argc) ?

                     strcmp(argv[i], "--start-system-server") == 0 : false;

            setArgv0(argv0, "zygote");

            set_process_name("zygote");

            runtime.start("com.android.internal.os.ZygoteInit",

                startSystemServer);

        }

从中可以追踪到 AndroidRuntime ,代码位于:

frameworks/base/core/jni/AndroidRuntime.cpp

start() 函数中有如下代码:

    /* start the virtual machine */

    if (startVm(&mJavaVM, &env) != 0)

        goto bail;

         ……

                 env->CallStaticVoidMethod(startClass, startMeth, strArray);

即先启动了虚拟机,然后利用 JNI 调用了 zygoteInit 函数。

 

继续追踪到 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java main() 函数,代码如下:

            if (argv[1].equals("true")) {

                 startSystemServer();

            } else if (!argv[1].equals("false")) {

                throw new RuntimeException(argv[0] + USAGE_STRING);

            }

 

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

 

            if (ZYGOTE_FORK_MODE) {

                runForkMode();

            } else {

                runSelectLoopMode();

            }

前一部分是在启动系统服务,后一部分是虽然是一个条件判断,但 ZYGOTE_FORK_MODE 被赋了 false ,所以进行 else 分支的 runSelectLoopMode() 函数,在该函数中,实际上是在一死循环中利用 zygoteConnection 类通过 socket 的方式进行消息处理,用于 fork 出新的 zygote ,从而以最轻量级的方式实现每个进程一个虚拟机的机制。

 

继续来看 startSystemServer() ,代码位于:

frameworks/base/services/java/com/android/server/systemserver.java

在其 main() 函数中调用了 init1(args) 这个 native 函数,利用 JNI 机制,跟踪至

frameworks/base/services/jni/com_android_server_systemService.cpp ,然后到

frameworks/base/cmds/system_server/library/system_init.cpp

system_init() 函数中有如下代码:

    if (strcmp(propBuf, "1") == 0) {

        // Start the SurfaceFlinger

        SurfaceFlinger::instantiate();

    }

    AndroidRuntime* runtime = AndroidRuntime::getRuntime();

 

    LOGI("System server: starting Android services./n");

    runtime->callStatic("com/android/server/SystemServer", "init2");

即完成了 SurfaceFlinger 的实例化,然后利用运行时的 callStatic() 函数调用了 SystemServer init2() 函数,这个函数位于:

frameworks/base/services/java/com/android/server/SystemServer.java

代码是:

    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 线程中,可以看到我们熟悉的 Android 服务了,比如 WallpaperService 服务的启动:

            try {

                Slog.i(TAG, "Wallpaper Service");

                 wallpaper = new WallpaperManagerService(context);

                ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);

            } catch (Throwable e) {

                Slog.e(TAG, "Failure starting Wallpaper Service", e);

            }

最后,调用各服务的 systemReady() 函数通知系统就绪。

 

至此,系统的启动过程结束,借用两张图来说明问题:

 

从这里可以看出, linux init 在启动若干守护进程之后,就启动了 Android runtime zygote zygote 再启动虚拟机,系统服务,系统服务再启动完本地服务后,又启动了若干 Android 服务,并完成向 ServiceManager 的注册工作,最后系统启动完成。系统的进程空间如下图所示:

 

 

可见,由 zygote 孵化器为各进程以写时复制的方式用最小的代价实现了虚拟机。

 

好了,相信经过这一系列的源码跟踪,我们都能对 Android 的启动过程有更清晰的认识,新年即将到来,在结束本系列文章的同时,祝大家新年快乐。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值