Android Runtime Environment Setup Process

Copyright:http://blog.csdn.net/myzhzygh/article/details/7721857


1Introduction

在文档“Android boot and init”中我们已经研究了Android系统的引导和加载过程。本章描述了在Kernel启动完成之后,Android系统执行了根文件系统目录下的init脚本,通过init脚本建立Android系统最初运行的环境。可以看出在这篇文章中,我们更多的侧重于内核启动和init脚本所完成的功能。而在本文中,我们将更多的讨论系统init脚本执行完之后,Android系统是如何完成后续启动过程,包括虚拟机创建,系统服务加载,系统应用程序启动等内容。

Android系统是基于Linux kernel的,抛开Linux kernel启动的过程,从另一个角度,我们可以认为Android的启动过程是从进程init开始的,也就是init脚本执行完成之后第一个执行的程序,所以它是后续所有进程的祖先进程。

2Native System Service

如果说init程序之前的操作是在为Android系统的启动做准备工作,那么从Android系统的init程序开始,我们就是在真正的创建Android系统运行的环境。在这个过程中,我们要完成文件系统节点的创建,设置系统环境变量和启动相应的系统服务等操作。Android系统提供了灵活的init.rc配置文件,能够实现对这个阶段系统操作进行灵活的配置。在每次系统启动的时候,init程序都会对init.rc配置文件进行解析,完成系统基本参数设置和基本服务的加载。下面我们看看在init.rc文件中所描述的的服务。

init.rc 文件里面的服务有2种, class coreclass main。对 init.rc文件中描述 service 按照 class <name>分类如下:

class core:

 

service ueventd /sbin/ueventd

service console /system/bin/sh

service adbd /sbin/adbd

service servicemanager /system/bin/servicemanager

service vold /system/bin/vold

 

class main:

 

service netd /system/bin/netd

service debuggerd /system/bin/debuggerd

service ril-daemon /system/bin/rild

service surfaceflinger /system/bin/surfaceflinger

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

service drm /system/bin/drmserver

service media /system/bin/mediaserver

service bootanim /system/bin/bootanimation

service dbus /system/bin/dbus-daemon --system --nofork

service bluetoothd /system/bin/bluetoothd -n

service installd /system/bin/installd

service flash_recovery /system/etc/install-recovery.sh

service racoon /system/bin/racoon

service mtpd /system/bin/mtpd

service keystore /system/bin/keystore /data/misc/keystore

service dumpstate /system/bin/dumpstate -s

上面列出了init.rc中描述的所有服务,针对具体的vendor,这些服务并不是都需要启动。在 class core服务启动以后, class main开始启动。下面列出针对Service的一些Options


1:init.rc service options

Options for Service

Description

setenv <name> <value>

在启动服务时设置环境变量

user <username>                    

运行服务之前切换用户

oneshot

如果服务已经存在,将不再启动

class <classname>                             

为服务设置名字,具有相同名字的服务将一起启动或者关闭

socket <name> <type> <perm> [ <user> [ <group> ] ]

创建以<name>命名的 socket,并将该 socket的文件描述符返回给启动的服务

onrestart <command>

在服务重新启动的时候执行<command>

对于init程序及init.rc其它规则我们在这里不再做详细的描述。具体可参考Android init language Spec

3Zygote Service

下面我们将研究Android系统最重要的服务zygote的启动流程。首先我们必须清楚zygote服务在init.rc配置文件中的描述形式:

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

         class main

         socket zygote stream 666

         onrestart write /sys/android_power/request_state wake

         onrestart write /sys/power/state on

         onrestart restart media

         onrestart restart netd

Zygote服务是标志进入 android系统的最重要服务之一,从上面的描述可以看到,服务名字为 zygote,实际的执行体是 ‘/system/bin/app_process’程序;同时zygote服务带有--zygote--start-system-server参数,这些参数对zygote服务的启动具有非常重要的作用。zygote服务相关选项所表示的含义如表1所示:


2zygote service sample

Option

Description

class main

说明service zygote属于main类型的service

socket zygote stream 666

在服务启动之前,需要创建一个命名为zygotesocket,该socket访问权限标示为666.

onrestart write /sys/android_power/request_state wake

该服务重启的时候,需要向电源管理中写入wake参数,电源管理请求为wake

onrestart restart media

该服务重启的时候,需要重新启动media服务

onrestart restart netd

该服务重启的时候,需要重新启动netd服务

从本文之前的内容我们知道,zygote服务只是init程序在系统启动阶段启动的服务之一,具体的说是main类型服务成员之一。但由于Android系统作为特殊的Linux系统,它所有应用程序都是运行在Java语言的基础上,所以为了支持这种特性,Android系统就必须构建支持Java程序运行的Runtime环境。而Zygote服务就是构建Java Runtime环境的起点,换句话说它是所有Java程序的始祖。所以我们有必要详细的研究,最终清楚Android Runtime构建的流程,并了解在这个过程中所进行的其它操作,如2D display环境的初始化等。

Zygote服务的执行实体为 ’/system/bin/app_process’,所以我们以app_process程序为研究的入口点,具体是以app_process程序的main方法为入口点,通过对main方法的代码实现进行宏观的分析,从分析的结果我们得出其实现的主要逻辑功能如下:

1.     构造AndroidRuntime类的实例

AppRuntime runtime;

系统的AndroidRuntime类定义了基本的Android Runtime接口,但AndroidRuntime类作为一个抽象类,不能实例化自己的对象。在app_process程序中定义了AppRuntime, AppRuntime类作为AndroidRuntime类的派生类,继承了AndroidRuntime类的部分接口实现,同时实现了AndroidRuntime类所定义的抽象接口,所以zygote服务的启动,我们首先实例化了一个AppRuntime类的对象,作为Runtime实例。接下来我们分析AppRuntime类和AndroidRuntime类的构造函数,从AppRuntime类的构造函数实现我们知道AppRuntime类在构造函数并没有做什么事,所以我们重点研究了AndroidRuntime类的构造函数。

AndroidRuntime::AndroidRuntime()

{

   SkGraphics::Init();

   // this sets our preference for 16bit images during decode

   // in case the src is opaque and 24bit

   SkImageDecoder::SetDeviceConfig(SkBitmap::kRGB_565_Config);

   // This cache is shared between browser native images, and java "purgeable"

   // bitmaps. This globalpool is for images that do not either use the java

   // heap, or are not backed by ashmem. See BitmapFactory.cpp for the key

   // java call site.

   SkImageRef_GlobalPool::SetRAMBudget(512 * 1024);

   // There is also a global font cache, but its budget is specified in code

   // see SkFontHost_android.cpp

 

   // Pre-allocate enough space to hold a fair number of options.

   mOptions.setCapacity(20);

 

   assert(gCurRuntime == NULL);        // one per process

   gCurRuntime = this;

}

从上面AndroidRuntime类的构造函数实现来看,构造函数最重要的任务就是初始化负责系统2D DisplaySkia库,指定系统默认颜色格式,设置images共享缓冲区的大小。

SkImageDecoder::SetDeviceConfig(SkBitmap::kRGB_565_Config);

SkImageRef_GlobalPool::SetRAMBudget(512 * 1024);

2.     解析init.rc中zygote传递的启动参数,设置Runtime启动参数

while (i < argc) {

       const char* arg = argv[i++];

       if (!parentDir) {

           parentDir = arg;

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

           zygote = true;

           niceName = "zygote";

       } else if (strcmp(arg, "--start-system-server") == 0) {

           startSystemServer = true;

       } else if (strcmp(arg, "--application") == 0) {

           application = true;

       } else if (strncmp(arg, "--nice-name=", 12) == 0) {

           niceName = arg + 12;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值