Android启动

一、init进程

     init进程(system\core\init),它是系统内核kernel启动后的第一个用户级进程。这时候,手机或者模拟器出现的画面是一个console,显示“ANDROID”信息。内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。它执行的主要任务有:

(1)       解析并执行init.rcinit. marvell.rc

(2)       自动在/dev目录下产生设备节点

(3)       启动logproperty service

(4)       监控deviceproperty set以及子进程的退出事件

根据init.rc中的具体定义,通常init进程会启动如下的一些本地应用进程(Native Application Process):

(1)       console:启动shell

(2)       servicemanager:启动并绑定IPC service manager

(3)       mountd:挂载/system/etc/mountd.conf中定义的所有文件系统,接收本地socket发送的文件系统挂载命令

(4)       debuggerd:启动debug系统

(5)       rild:启动radio接口层进程

(6)       zygote:启动AndroidJava VM Runtimesystem server,这是最重要的进程

(7)       meidaserver:启动AudioFlingerMediaPlayerServiceCameraService

(8)       installd:启动install package进程

 

最后Init并不退出,而是担当起property service的功能。进入一个无限循环来等待device/property set/child process的退出事件。例如,如果SD卡被插入,init会收到一个设备插入事件,它会为这个设备创建节点。系统中比较重要的进程都是由initfork的,所以如果他们谁崩溃了,那么init 将会收到一个 SIGCHLD 信号,把这个信号转化为子进程退出事件,然后在loop中,init 会处理进程退出事件并且执行“*.rc”文件中定义的命令。

例如,在init.rc中,因为有:

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

所以,如果zygote因为启动某些服务导致异常退出后,init将会重新去启动它。

二、init.rc脚本

         Init.rcAndroid自己规定的初始化脚本(Android Init Language),该脚本是在init启动后被解析执行的启动脚本,可以在系统的初始化过程中进行一些简单的初始化操作。如果想要修改启动过程只需要修改init.csystem/core/init)或者init.rc里的内容即可。这个脚本被直接安装到目标系统的根文件系统中,其语法主要包含了以下内容:(可参考System/Core/Init/readme.txt

Commands:命令

Actions:动作

Triggers:触发条件

Services:服务

Options:选项

Properties:属性

1Commands是一些基本的操作,例如:

mkdir /sdcard 0000 system system

mkdir /system

mkdir /data 0771 system system

mkdir /cache 0770 system cache

mkdir /config 0500 root root

mkdir /sqlite_stmt_journals 01777 root root

    mount tmpfs tmpfs /sqlite_stmt_journals size=4m

这些命令在init可执行程序中被解析,然后调用相关的函数来实现。

2Actions(动作)表示一系列的命令,通常在Triggers(触发条件)中调用,动作和触发条件的形式为:

   on <trigger>

      <command>

      <command>

      <command>

动作的使用示例如下:

on init

export PATH /sbin:/system/sbin:/system/bin:/system/xbin

    mkdir /system

init表示一个触发条件,这个触发事件发生后,进行设置环境变量和建立目录的操作称为一个“动作”

3Services(服务)通常表示启动一个可执行程序,Options(选项)是服务的附加内容,用于配合服务使用。

service vold /system/bin/vold

    socket vold stream 0660 root mount

 

service bootsound /system/bin/playmp3

    user media

    group audio

        oneshot

voldbootsound分别是两个服务的名称,/system/bin/vold/system /bin/playmp3分别是他们所对应的可执行程序。

socketusergrouponeshot就是配合服务使用的选项。其中oneshot选项表示该服务只启动一次,而如果没有oneshot选项,这个可执行程序会一直存在——如果可执行程序被杀死,则会重新启动。

4Properties(属性)是系统中使用的一些值,可以进行设置和读取。

setprop ro.FOREGROUND_APP_MEM 1536

setprop ro.VISIBLE_APP_MEM 2048

on property:ro.kernel.qemu=1

    start adbd

setprop 用于设置属性,on property可以用于判断属性,这里的属性在整个Android系统运行中都是一致的。

三、脚本解析过程

init_parser.c中定义了三个比较重要的数据结构:两个列表,一个队列。

static list_declare(service_list);

static list_declare(action_list);

static list_declare(action_queue);

*.rc脚本中所有 service关键字定义的服务将会添加到 service_list 列表中。*.rc脚本中所有 on 关键开头的项将会被会添加到 action_list 列表中。每个action列表项都有一个action queue,此queue用来保存该段落下的Commands

init_parser.c中的parse_config函数会逐行对脚本进行解析,如果关键字类型为 SECTION ,那么将会执行 parse_new_section() 。类型为SECTION的关键字有:onseviceparse_new_section()中再分别对 service 或者 on 关键字开头的内容进行解析。

case K_service:

state->context = parse_service(state, nargs, args);

if (state->context) {

state->parse_line = parse_line_service;

return;

}

break;

case K_on:

state->context = parse_action(state, nargs, args);

if (state->context) {

state->parse_line = parse_line_action;

return;

}

break;

on 关键字开头的内容进行解析

static void *parse_action(struct parse_state *state, int nargs, char **args)

{ ...

act = calloc(1, sizeof(*act));

act->name = args[1];

list_init(&act->commands);

list_add_tail(&action_list, &act->alist);

...}

service 关键字开头的内容进行解析

static void *parse_service(struct parse_state *state, int nargs, char **args)

{ …

list_add_tail(&service_list, &svc->slist);

return svc;

}

服务的表现形式:

service [ ]*

申请一个service结构体,然后挂接到service_list链表上,name 为服务的名称,pathname 为执行的命令,argument 为命令的参数。之后的 option 用来控制这个service结构体的属性,parse_line_service 会对 service关键字后的内容进行解析并填充到 service 结构中,当遇到下一个service或者on关键字的时候此service选项解析结束。

例如:

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

服务名称为: zygote

启动该服务执行的命令: /system/bin/app_process

命令的参数: -Xzygote /system/bin --zygote --start-system-server

socket zygote stream 666:创建一个名为:/dev/socket/zygote socket ,类型为:stream

*.rc脚本文件解析完成以后,action_list列表项目如下:

on init

on boot

on property:ro.kernel.qemu=1

on property:persist.service.adb.enable=1

on property:persist.service.adb.enable=0

init.marvell.rc文件所对应的项目:

on early-init

on init

on early-boot

on boot

service_list 列表中的项有:

service console

service adbd

service servicemanager

service mountd

service debuggerd

service ril-daemon

service zygote

service media

service bootsound

service dbus

service hcid

service hfag

service hsag

service installd

service flash_recovery

四、Zygote

Zygote android 系统中最重要的一个服务,它将启动AndroidJava Runtimesystem serverZygotemain()@frameworks\base\cmds\app_process\app_main.cpp开始,一步一步完成如下一些任务:

(1)       建立Java Runtime

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

(2)       建立Java虚拟机

start(…)@frameworks/base/core/jni/AndroidRuntime.cpp

startVm(…)@frameworks/base/core/jni/AndroidRuntime.cpp

(3)       调用ZygoteInit类中的main函数:

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

a)  装载ZygoteInit

b)  注册zygote socket

c)  装载preload Classes (the default file is device/java/android/preloaded-classes)

d)  装载preload Resources

e)  通过startSystemServer函数来调用forkSystemServer(…) JNI接口函数来fork一个新的进程,在新进程中调用com.android.server.SystemServer main函数。forkSystemServer(…)对应的C代码在Dalvik_dalvik_system_Zygote_forkSystemServer(…)@dalvik\vm\native\dalvik_system_Zygote.c中。

经过这几个步骤,Zygote就建立好了,利用Socket通讯,接收ActivityManangerService的请求,Fork应用程序。

五、SystemServer

Android系统中,system_server是比较特殊的Java进程,它是直接在zygote中启动的。除此之外,其它所有的Java应用进程(Java Application Process)都是通过ActivityManagerServicestartProcessLocked方法创建的,代码如下:

int pid = Process.start("android.app.ActivityThread",

mSimpleProcessManagement ? app.processName : null, uid, uid,

gids, debugFlags, null);

Android的所有服务循环框架都是建立在SystemServer@( frameworks\base\services\java\com\android\server\SystemServer.java)上。但在SystemServer.java中看不到循环结构,只是可以看到main函数调用了JNI接口init1函数,并且给出了init2函数的实现。

main() @ com/android/server/SystemServer

{…

init1();

    }

init1()是在Java Native Interface空间实现的,对应的C代码是android_server_SystemServer_init1(…)@ frameworks\base\services\jni\com_andoird_server_systemServer.cpp,实际上它唯一的动作就是调用函数system_init()@frameworks\base\cmds\system_server\library\system_init.cpp

system_init调用SurfaceFlingerSensorServiceAudioFlingerMediaPlayerServiceCameraServiceAudioPolicyService等多个动作或者服务。其中SurfaceFlingerBootAnimation来实现开机动画,这时候手机或者模拟器显示的是一副背景图加一个动态的小机器人。

接下来system_init()函数调用SystemServer.java中的init2函数,此后我们就可以看到循环闭合管理框架

{…

    SurfaceFlinger::instantiate();

    …

Call "com/android/server/SystemServer", "init2"

        …

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

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

}

init2()@SystemServer.java所启动的ServerThread线程中建立了一大堆Android中所有要用到的服务,并通过ServiceManageraddService函数把这些服务addservice Manager中。

Core 服务:

1. Starting Power Manager(电源管理)

2. Creating Activity Manager(活动服务)

3. Starting Telephony Registry(电话注册服务)

4. Starting Package Manager(包管理器)

5. Set Activity Manager Service as System Process

6. Starting Content Manager

7. Starting System Content Providers (初始化数据库内容)

8. Starting Battery Service(电池服务)

9. Starting Alarm Manager(闹钟服务)

10. Starting Sensor Service

11. Starting Window Manager(启动窗口管理器)

12. Starting Bluetooth Service(蓝牙服务)

13. Starting Mount Service

其他services

1. Starting Status Bar Service(状态服务)

2. Starting Hardware Service(硬件服务)

3. Starting NetStat Service(网络状态服务)

4. Starting Connectivity Service

5. Starting Notification Manager

6. Starting DeviceStorageMonitor Service

7. Starting Location Manager

8. Starting Search Service(查询服务)

9. Starting Clipboard Service

10. Starting Checkin Service

11. Starting Wallpaper Service

12. Starting Audio Service

13. Starting HeadsetObserver

14. Starting AdbSettingsObserver

最后init2()@SystemServer.java函数将会调用systemReady(…)@ frameworks\base\services\java\com\android\server\am\ActivityManagerService.java。该函数将会启动所有的具有“persistent”属性的应用。

static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;

List apps = AppGlobals.getPackageManager().

                        getPersistentApplications(STOCK_PM_FLAGS);

例如PhoneApp具有该属性:

<application android:name="PhoneApp"

android:persistent="true"

android:label="@string/dialerIconLabel"

android:icon="@drawable/ic_launcher_phone">

还有另外一种启动system server的方法是:通过名为 system_main.cpp@ frameworks\base\cmds\system_server程序调用 system_init 来启动 system services

六、Home启动

         ServerThread@SystemServer.java的前半段,通过调用ActivityManagerServicemain函数newActivityManagerService的实例。

ServerThread@SystemServer.java后半段,我们可以看到系统在启动完所有的Android服务后,做了这样一些动作:

1)使用xxx.systemReady()通知各个服务,系统已经就绪。

2)特别对于ActivityManagerService.systemReady(回调)Widget.wallpaper,imm(输入法)ready通知。

Home就是在ActivityManagerService.systemReady()通知的过程中建立的。下面是ActivityManagerService.systemReady()的伪代码:

systemReady()@ActivityManagerService.java

resumeTopActivityLocked()

startHomeActivityLocked();//如果是第一个则启动HomeActivity

startActivityLockedCATEGORY_HOME

         在启动的最后,ActivityManagerService会发送ACTION_BOOT_COMPLETED消息,当前可能在其AndroidManifest.xml文件中注册了接收该消息的应用有MMSAlarmClockCalendarMediaProviderVoiceDialerIMUpdate等。

         Email同样在其AndroidManifest.xml文件中注册了接收ACTION_BOOT_COMPLETED消息,但它定义了android:enable=”false”,所以并不会自动启动。

<receiver android:name=".service.BootReceiver" android:enabled="false" >

<intent-filter>

<action android:name="android.intent.action.BOOT_COMPLETED" />

</intent-filter>

<intent-filter>

<action android:name="android.intent.action.DEVICE_STORAGE_LOW" />

</intent-filter>

<intent-filter>

<action android:name="android.intent.action.DEVICE_STORAGE_OK" />

</intent-filter>

</receiver>

DownloadProvider也注册了接收ACTION_BOOT_COMPLETED消息,但其定义了android:exported=”false”,所以同样也不会被自动启动。

<receiver android:name=".DownloadReceiver" android:exported="false">

<intent-filter>

<action android:name="android.intent.action.BOOT_COMPLETED" />

<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />

</intent-filter>

</receiver>

 

 

1http://hi.baidu.com/j_fo/blog/item/a43fa60fb77dfbe3aa645741.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值