一、init进程
init进程(system\core\init),它是系统内核kernel启动后的第一个用户级进程。这时候,手机或者模拟器出现的画面是一个console,显示“ANDROID”信息。内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。它执行的主要任务有:
(1) 解析并执行init.rc和init. marvell.rc
(2) 自动在/dev目录下产生设备节点
(3) 启动log和property service
(4) 监控device、property 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:启动Android的Java VM Runtime和system server,这是最重要的进程
(7) meidaserver:启动AudioFlinger,MediaPlayerService和CameraService
(8) installd:启动install package进程
最后Init并不退出,而是担当起property service的功能。进入一个无限循环来等待device/property set/child process的退出事件。例如,如果SD卡被插入,init会收到一个设备插入事件,它会为这个设备创建节点。系统中比较重要的进程都是由init来fork的,所以如果他们谁崩溃了,那么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.rc是Android自己规定的初始化脚本(Android Init Language),该脚本是在init启动后被解析执行的启动脚本,可以在系统的初始化过程中进行一些简单的初始化操作。如果想要修改启动过程只需要修改init.c(system/core/init)或者init.rc里的内容即可。这个脚本被直接安装到目标系统的根文件系统中,其语法主要包含了以下内容:(可参考System/Core/Init/readme.txt)
Commands:命令
Actions:动作
Triggers:触发条件
Services:服务
Options:选项
Properties:属性
(1)Commands是一些基本的操作,例如:
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可执行程序中被解析,然后调用相关的函数来实现。
(2)Actions(动作)表示一系列的命令,通常在Triggers(触发条件)中调用,动作和触发条件的形式为:
on <trigger>
<command>
<command>
<command>
动作的使用示例如下:
on init export PATH /sbin:/system/sbin:/system/bin:/system/xbin mkdir /system |
init表示一个触发条件,这个触发事件发生后,进行设置环境变量和建立目录的操作称为一个“动作”
(3)Services(服务)通常表示启动一个可执行程序,Options(选项)是服务的附加内容,用于配合服务使用。
service vold /system/bin/vold socket vold stream 0660 root mount
service bootsound /system/bin/playmp3 user media group audio oneshot |
vold和bootsound分别是两个服务的名称,/system/bin/vold和/system /bin/playmp3分别是他们所对应的可执行程序。
socket、user、group、oneshot就是配合服务使用的选项。其中oneshot选项表示该服务只启动一次,而如果没有oneshot选项,这个可执行程序会一直存在——如果可执行程序被杀死,则会重新启动。
(4)Properties(属性)是系统中使用的一些值,可以进行设置和读取。
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的关键字有:on和sevice。parse_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 系统中最重要的一个服务,它将启动Android的Java Runtime和system server。Zygote从main(…)@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)都是通过ActivityManagerService的startProcessLocked方法创建的,代码如下:
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调用SurfaceFlinger、SensorService、AudioFlinger、MediaPlayerService、CameraService、AudioPolicyService等多个动作或者服务。其中SurfaceFlinger用BootAnimation来实现开机动画,这时候手机或者模拟器显示的是一副背景图加一个动态的小机器人。
接下来system_init()函数调用SystemServer.java中的init2函数,此后我们就可以看到循环闭合管理框架:
{… SurfaceFlinger::instantiate(); … Call "com/android/server/SystemServer", "init2" … ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); } |
在init2()@SystemServer.java所启动的ServerThread线程中建立了一大堆Android中所有要用到的服务,并通过ServiceManager的addService函数把这些服务add到service 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的前半段,通过调用ActivityManagerService的main函数new出ActivityManagerService的实例。
在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。 startActivityLocked(…)CATEGORY_HOME |
在启动的最后,ActivityManagerService会发送ACTION_BOOT_COMPLETED消息,当前可能在其AndroidManifest.xml文件中注册了接收该消息的应用有MMS、AlarmClock、Calendar、MediaProvider、VoiceDialer、IM和Update等。
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> |
1、http://hi.baidu.com/j_fo/blog/item/a43fa60fb77dfbe3aa645741.html