android 系统启动过程

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()函数中有如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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()函数中有如下代码:

1
2
3
4
5
6
7
8
9
/* 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()函数,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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()函数中有如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

代码是:

1
2
3
4
5
6
7
8
9
10
11
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服务的启动:

1
2
3
4
5
6
7
8
9
10
11
12
13
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的启动过程有更清晰的认识
原文链接:http://blog.csdn.net/caowenbin/archive/2010/12/31/6110751.aspx

转载编辑: Fgamers
转载地址:http://disanji.net/2011/05/06/android-code-study-8-system-startup/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值