Android init 啟動過程分析分析android的啟動過程,從內(nèi)核之上,我們首先應該從文件系統(tǒng)的init開始,因為 init是內(nèi)核進入文件系統(tǒng)后第一個運行的程序,通常我們可以在linux的命令行中指定內(nèi)核第一個調(diào)用誰,如果沒指定那么內(nèi)核將會到/sbin/, /bin/等目錄下查找默認的init,如果沒有找到那么就報告出錯。
下面是曾經(jīng)用過的幾種開發(fā)板的命令行參數(shù):
S3C2410 啟動參數(shù):
noinitrdroot=/dev/nfs nfsroot=192.168.2.56:/nfsroot/rootfs ip=192.168.2.188:192.168.2.56:192.168.2.56:255.255.255.0::eth0:onconsole=ttySAC0
S3C2440 啟動參數(shù):
setenv bootargs console=ttySAC0root=/dev/nfs nfsroot=192.168.2.56:/nfsroot/rootfsip=192.168.2.175:192.168.2.56:192.168.2.201:255.255.255.0::eth0:onmem=64M init=/init
marvell 310 啟動參數(shù):
boot root=/dev/nfsnfsroot=192.168.2.56:/nfsroot/rootfs,rsize=1024,wsize=1024ip=192.168.2.176:192.168.2.201:192.168.2.201:255.255.255.0::eth0:-On console=ttyS2,115200 mem=64M init=/init
init的源代碼在文件:./system/core/init/init.c 中,init會一步步完成下面的任務:
1.初始化log系統(tǒng)
2.解析/init.rc和/init.%hardware%.rc文件
3. 執(zhí)行 early-init action in the two filesparsed in step 2.
4. 設(shè)備初始化,例如:在 /dev 下面創(chuàng)建所有設(shè)備節(jié)點,下載 firmwares.
5. 初始化屬性服務器,Actually the property system is working as ashare memory. Logically it looks like a registry under Windows system.
6.執(zhí)行 init action in the two files parsed in step 2.
7. 開啟 屬性服務。
8.執(zhí)行 early-boot and boot actions in the two files parsed in step 2.
9.執(zhí)行 Execute property action in the two files parsed in step 2.
10.進入一個無限循環(huán) to wait for device/property set/child process exit events.例如,如果SD卡被插入,init會收到一個設(shè)備插入事件,它會為這個設(shè)備創(chuàng)建節(jié)點。系統(tǒng)中比較重要的進程都是由init來fork的,所以如果他們他誰崩潰了,那么init 將會收到一個 SIGCHLD 信號,把這個信號轉(zhuǎn)化為子進程退出事件, 所以在loop中,init 會操作進程退出事件并且執(zhí)行*.rc 文件中定義的命令。
例如,在init.rc中,因為有:
service zygote/system/bin/app_process -Xzygote /system/bin --zygote--start-system-server
socket zygote stream 666
onrestartwrite /sys/android_power/request_state wake
onrestart write/sys/power/state on
所以,如果zygote因為啟動某些服務導致異常退出后,init將會重新去啟動它。
intmain(int argc, char **argv)
{
...
//需要在后面的程序中看打印信息的話,需要屏蔽open_devnull_stdio()函數(shù)
open_devnull_stdio();
...
//初始化log系統(tǒng)
log_init();
//解析/init.rc和/init.%hardware%.rc文件
parse_config_file("/init.rc");
...
snprintf(tmp,sizeof(tmp), "/init.%s.rc", hardware);
parse_config_file(tmp);
...
//執(zhí)行 early-init action in the two files parsed in step 2.
action_for_each_trigger("early-init", action_add_queue_tail);
drain_action_queue();
...
/* execute all the boot actionsto get us started */
/* 執(zhí)行 init action in the two files parsed instep 2 */
action_for_each_trigger("init",action_add_queue_tail);
drain_action_queue();
...
/* 執(zhí)行 early-boot and boot actions in the two files parsed in step 2 */
action_for_each_trigger("early-boot", action_add_queue_tail);
action_for_each_trigger("boot", action_add_queue_tail);
drain_action_queue();
/* run all property triggers based oncurrent state of the properties */
queue_all_property_triggers();
drain_action_queue();
/* enable property triggers */
property_triggers_enabled = 1;
...
for(;;) {
int nr, timeout = -1;
...
drain_action_queue();
restart_processes();
if (process_needs_restart) {
timeout = (process_needs_restart - gettime()) * 1000;
if(timeout < 0)
timeout = 0;
}
...
nr = poll(ufds, 3, timeout);
if (nr <= 0)
continue;
if (ufds[2].revents == POLLIN) {
/* we got a SIGCHLD - reap and restart as needed */
read(signal_recv_fd, tmp, sizeof(tmp));
while(!wait_for_one_process(0))
;
continue;
}
if (ufds[0].revents == POLLIN)
handle_device_fd(device_fd);
if (ufds[1].revents ==POLLIN)
{
handle_property_set_fd(property_set_fd);
}
}
return 0;
}
2.解析init.rc腳本
init.rc腳本的具體語法可以參考下面文檔
http://www.kandroid.org/android_pdk/bring_up.html
名詞解釋:
Android初始化語言由四大類聲明組成:行為類(Actions),命令類(Commands),服務類(Services),選項類(Options).
初始化語言以行為單位,由以空格間隔的語言符號組成。C風格的反斜杠轉(zhuǎn)義符可以用來插入空白到語言符號。雙引號也可以用來防止文本被空格分成多個語言符號。當反斜杠在行末時,作為換行符。
* 以#開始(前面允許空格)的行為注釋。
*Actions和Services隱含聲明一個新的段落。所有該段落下Commands或Options的聲明屬于該段落。第一段落前的Commands或Options被忽略。
* Actions和Services擁有唯一的命名。在他們之后聲明相同命名的類將被當作錯誤并忽略。
Actions是一系列命令的命名。Actions擁有一個觸發(fā)器(trigger)用來決定action何時執(zhí)行。當一個action在符合觸發(fā)條件被執(zhí)行時,如果它還沒被加入到待執(zhí)行隊列中的話,則加入到隊列最后。
隊列中的action依次執(zhí)行,action中的命令也依次執(zhí)行。Init在執(zhí)行命令的中間處理其他活動(設(shè)備創(chuàng)建/銷毀,property 設(shè)置,進程重啟)。
Actions的表現(xiàn)形式:
on<trigger>
<command>
<command>
<command>
重要的數(shù)據(jù)結(jié)構(gòu)
兩個列表,一個隊列。
staticlist_declare(service_list);
static list_declare(action_list);
staticlist_declare(action_queue);
*.rc 腳本中所有 service關(guān)鍵字定義的服務將會添加到service_list 列表中。
*.rc 腳本中所有 on 關(guān)鍵開頭的項將會被會添加到 action_list 列表中。
每個action列表項都有一個列表,此列表用來保存該段落下的 Commands
腳本解析過程:
parse_config_file("/init.rc")
intparse_config_file(const char *fn)
{
char *data;
data =read_file(fn, 0);
if (!data) return -1;
parse_config(fn, data);
DUMP();
return 0;
}
staticvoid parse_config(const char *fn, char *s)
{
...
caseT_NEWLINE:
if (nargs) {
int kw =lookup_keyword(args[0]);
if (kw_is(kw, SECTION)) {
state.parse_line(&state, 0, 0);
parse_new_section(&state, kw, nargs, args);
} else {
state.parse_line(&state, nargs, args);
}
nargs = 0;
}
...
}
parse_config會逐行對腳本進行解析,如果關(guān)鍵字類型為 SECTION ,那么將會執(zhí)行 parse_new_section()
類型為 SECTION 的關(guān)鍵字有: on 和sevice
關(guān)鍵字類型定義在 Parser.c (system\core\init) 文件中
Parser.c(system\core\init)
#define SECTION 0x01
#define COMMAND 0x02
#defineOPTION 0x04
關(guān)鍵字 屬性
capability, OPTION, 0, 0)
class, OPTION, 0, 0)
class_start, COMMAND, 1, do_class_start)
class_stop, COMMAND, 1, do_class_stop)
console, OPTION, 0, 0)
critical, OPTION, 0, 0)
disabled, OPTION, 0, 0)
domainname, COMMAND,1, do_domainname)
exec, COMMAND, 1, do_exec)
export, COMMAND, 2, do_export)
group, OPTION, 0, 0)
hostname, COMMAND, 1, do_hostname)
ifup, COMMAND, 1, do_ifup)
insmod, COMMAND, 1, do_insmod)
import, COMMAND, 1, do_import)
keycodes, OPTION, 0, 0)
mkdir, COMMAND, 1, do_mkdir)
mount, COMMAND, 3, do_mount)
on, SECTION, 0, 0)
oneshot, OPTION, 0, 0)
onrestart, OPTION, 0, 0)
restart, COMMAND,1, do_restart)
service, SECTION, 0, 0)
setenv, OPTION, 2, 0)
setkey, COMMAND, 0, do_setkey)
setprop, COMMAND, 2,do_setprop)
setrlimit, COMMAND, 3, do_setrlimit)
socket, OPTION, 0, 0)
start, COMMAND, 1, do_start)
stop, COMMAND, 1, do_stop)
trigger, COMMAND, 1, do_trigger)
symlink, COMMAND, 1, do_symlink)
sysclktz, COMMAND, 1, do_sysclktz)
user, OPTION, 0, 0)
write, COMMAND, 2, do_write)
chown, COMMAND, 2, do_chown)
chmod, COMMAND, 2, do_chmod)
loglevel, COMMAND, 1, do_loglevel)
device, COMMAND, 4, do_device)
parse_new_section()中再分別對 service 或者 on 關(guān)鍵字開頭的內(nèi)容進行解析。
...
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 關(guān)鍵字開頭的內(nèi)容進行解析
staticvoid *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 關(guān)鍵字開頭的內(nèi)容進行解析
static void *parse_service(struct parse_state*state, int nargs, char **args)
{
struct service *svc;
if (nargs < 3) {
parse_error(state, "services must have aname and a program\n");
return 0;
}
if(!valid_name(args[1])) {
parse_error(state, "invalid servicename '%s'\n", args[1]);
return 0;
}
//如果服務已經(jīng)存在service_list列表中將會被忽略
svc =service_find_by_name(args[1]);
if (svc) {
parse_error(state, "ignored duplicate definition of service '%s'\n",args[1]);
return 0;
}
nargs -= 2;
svc = calloc(1, sizeof(*svc) + sizeof(char*) * nargs);
if (!svc){
parse_error(state, "out of memory\n");
return0;
}
svc->name = args[1];
svc->classname ="default";
memcpy(svc->args, args + 2, sizeof(char*) * nargs);
svc->args[nargs] = 0;
svc->nargs = nargs;
svc->onrestart.name = "onrestart";
list_init(&svc->onrestart.commands);
//添加該服務到 service_list列表
list_add_tail(&service_list, &svc->slist);
return svc;
}
服務的表現(xiàn)形式:
service <name> <pathname> [<argument> ]*
<option>
<option>
...
申請一個service結(jié)構(gòu)體,然后掛接到service_list鏈表上,name 為服務的名稱 pathname 為執(zhí)行的命令 argument
為命令的參數(shù)。之后的 option 用來控制這個service結(jié)構(gòu)體的屬性,parse_line_service 會對 service關(guān)鍵字后的
內(nèi)容進行解析并填充到 service 結(jié)構(gòu)中 ,當遇到下一個service或者on關(guān)鍵字的時候此service選項解析結(jié)束。
例如:
servicezygote /system/bin/app_process -Xzygote /system/bin --zygote--start-system-server
socket zygote stream 666
onrestartwrite /sys/android_power/request_state wake
服務名稱為: zygote
啟動該服務執(zhí)行的命令: /system/bin/app_process
命令的參數(shù): -Xzygote/system/bin --zygote --start-system-server
socket zygote stream 666:創(chuàng)建一個名為:/dev/socket/zygote 的 socket ,類型為:stream
當*.rc 文件解析完成以后:
action_list列表項目如下:
on init
on boot
on property:ro.kernel.qemu=1
onproperty:persist.service.adb.enable=1
onproperty:persist.service.adb.enable=0
init.marvell.rc 文件
onearly-init
on init
on early-boot
on boot
service_list列表中的項有:
service console
service adbd
service servicemanager
servicemountd
service debuggerd
service ril-daemon
service zygote
servicemedia
service bootsound
service dbus
service hcid
servicehfag
service hsag
service installd
service flash_recovery
狀態(tài)服務器相關(guān):
在init.c 的main函數(shù)中啟動狀態(tài)服務器。
property_set_fd =start_property_service();
狀態(tài)讀取函數(shù):
Property_service.c(system\core\init)
const char* property_get(const char *name)
Properties.c(system\core\libcutils)
int property_get(const char *key, char*value, const char *default_value)
狀態(tài)設(shè)置函數(shù):
Property_service.c(system\core\init)
int property_set(const char *name, const char*value)
Properties.c (system\core\libcutils)
intproperty_set(const char *key, const char *value)
在終端模式下我們可以通過執(zhí)行命令setprop <key> <value>
setprop 工具源代碼所在文件: Setprop.c(system\core\toolbox)
Getprop.c (system\core\toolbox): property_get(argv[1], value, default_value);
Property_service.c(system\core\init)
中定義的狀態(tài)讀取和設(shè)置函數(shù)僅供init進程調(diào)用,
handle_property_set_fd(property_set_fd);
property_set() //Property_service.c (system\core\init)
property_changed(name, value) //Init.c (system\core\init)
queue_property_triggers(name, value)
drain_action_queue()
只要屬性一改變就會被觸發(fā),然后執(zhí)行相應的命令:
例如:
在init.rc 文件中有
onproperty:persist.service.adb.enable=1
start adbd
onproperty:persist.service.adb.enable=0
stop adbd
所以如果在終端下輸入:
setpropproperty:persist.service.adb.enable 1或者0
那么將會開啟或者關(guān)閉adbd 程序。
執(zhí)行action_list 中的命令:
從action_list 中取出 act->name 為 early-init的列表項,再調(diào)用 action_add_queue_tail(act)將其插入到
隊列 action_queue尾部。drain_action_queue() 從action_list隊列中取出隊列項 ,然后執(zhí)行act->commands
列表中的所有命令。
所以從 ./system/core/init/init.c mian()函數(shù)的程序片段:
action_for_each_trigger("early-init",action_add_queue_tail);
drain_action_queue();
action_for_each_trigger("init",action_add_queue_tail);
drain_action_queue();
action_for_each_trigger("early-boot",action_add_queue_tail);
action_for_each_trigger("boot",action_add_queue_tail);
drain_action_queue();
/* run all propertytriggers based on current state of the properties */
queue_all_property_triggers();
drain_action_queue();
可以看出,在解析完init.rc init.marvell.rc 文件后,action 命令執(zhí)行順序為:
執(zhí)行act->name 為early-init,act->commands列表中的所有命令
執(zhí)行act->name 為 init, act->commands列表中的所有命令
執(zhí)行act->name 為early-boot,act->commands列表中的所有命令
執(zhí)行act->name 為 boot, act->commands列表中的所有命令
關(guān)鍵的幾個命令:
class_start default 啟動所有service 關(guān)鍵字定義的服務。
class_start 在act->name為boot的act->commands列表中,所以當 class_start 被觸發(fā)后,實際
上調(diào)用的是函數(shù) do_class_start()
intdo_class_start(int nargs, char **args)
{
/* Starting aclass does not start services
* which are explicitlydisabled. They must
* be started individually.
*/
service_for_each_class(args[1],service_start_if_not_disabled);
return 0;
}
voidservice_for_each_class(const char *classname,
void (*func)(struct service *svc))
{
struct listnode *node;
struct service *svc;
list_for_each(node, &service_list) {
svc = node_to_item(node, struct service, slist);
if(!strcmp(svc->classname, classname)) {
func(svc);
}
}
}
因為在調(diào)用 parse_service() 添加服務列表的時候,所有服務svc->classname 默認取值:"default",
所以 service_list 中的所有服務將會被執(zhí)行。
參考文檔:
http://blog.chinaunix.net/u1/38994/showart_1775465.html
http://blog.chinaunix.net/u1/38994/showart_1168440.html
淺析kernel啟動的第1個用戶進程init如何解讀init.rc腳本
http://blog.chinaunix.net/u1/38994/showart_1168440.html
Zygote服務概論:
Zygote 是android 系統(tǒng)中最重要的一個服務,它將一步一步完成下面的任務:
start AndroidJava Runtime and start system server. It’s the most important service.The source is in device/servers/app.
1. 創(chuàng)建JAVA 虛擬機
2. 為JAVA虛擬機注冊android 本地函數(shù)
3. 調(diào)用 com.android.internal.os.ZygoteInit類中的main函數(shù),android/com/android/internal/os/ZygoteInit.java.
a)裝載ZygoteInit類
b) 注冊zygote socket
c) 裝載preload classes(the defaultfile is device/java/android/preloaded-classes)
d) 裝載Load preload 資源
e)調(diào)用 Zygote::forkSystemServer(定義在./dalvik/vm/InternalNative.c)來fork一個新的進程,在新進程中調(diào)用com.android.server.SystemServer 的main函數(shù)。
a) 裝載 libandroid_servers.so庫
bb)調(diào)用JNI native init1 函數(shù)(device/libs/android_servers/com_android_server_SystemServers)
Loadlibandroid_servers.so
Call JNI native init1 function implemented indevice/libs/android_servers/com_android_server_SystemServers. It onlycalls system_init implemented indevice/servers/system/library/system_init.cpp.
If running onsimulator, instantiate AudioFlinger, MediaPlayerService andCameraService here.
Call init2 function in JAVA class namedcom.android.server.SystemServer, whose source is indevice/java/services/com/android/server. This function is very criticalfor Android because it start all of Android JAVA services.
If notrunning on simulator, call IPCThreadState::self()->joinThreadPool()to enter into service dispatcher.
SystemServer::init2將會啟動一個新的線程來啟動下面的所有JAVA服務:
Core 服務:
1. Starting PowerManager(電源管理)
2. Creating Activity Manager(活動服務)
3. StartingTelephony Registry(電話注冊服務)
4. Starting Package Manager(包管理器)
5. Set Activity Manager Service as System Process
6. Starting ContextManager
7. Starting System Context Providers
8. Starting BatteryService(電池服務)
9. Starting Alarm Manager(鬧鐘服務)
10. StartingSensor Service
11. Starting Window Manager(啟動窗口管理器)
12. StartingBluetooth Service(藍牙服務)
13. Starting Mount Service
其他services:
1. Starting Status Bar Service(狀態(tài)服務)
2. Starting HardwareService(硬件服務)
3. Starting NetStat Service(網(wǎng)絡狀態(tài)服務)
4. StartingConnectivity 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. StartingAdbSettingsObserver
最后SystemServer::init2 將會調(diào)用ActivityManagerService.systemReady 通過發(fā)送
Intent.CATEGORY_HOMEintent來啟動第一個 activity.還有另外一種啟動system server的方法是:
通過名為system_server的程序(源代碼:device/servers/system/system_main.cpp)它也是通過
調(diào)用system_init 來啟動 system services,這時候就有個問題:為什么android 有兩種方式啟動systemservices?
我的猜想是:
My guess is that directly start system_server mayhave synchronous problem with zygote because system_server will callJNI to start SystemServer::init2, while at that time zygote may notstart JAVA VM yet. So Android uses another method. After zynote isinitialized, fork a new process to start system services.
Zygote服務啟動的詳細過程:
通過啟動服務列表的 app_process 進程,實際上進入的是
App_main.cpp(frameworks\base\cmds\app_process)
main()
根據(jù) init.rc 中的 --zygote--start-system-server
分別調(diào)用的是
runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);
或者
runtime.start();
start()函數(shù)在 AndroidRuntime.cpp(frameworks\base\core\jni)文件中
從打印信息:
D/AndroidRuntime( 56):>>>>>>>>>>>>>> AndroidRuntimeSTART <<<<<<<<<<<<<<
也可以看出調(diào)用的是:
AndroidRuntime::start(const char* className, const boolstartSystemServer)
JNI_CreateJavaVM()
startReg()
LOGD("--- registering native functions ---\n");
startMeth =env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");
從上面的調(diào)用可以看出一類引用的過程都是從 main方法
所以接著調(diào)用了 ZygoteInit 類的main方法
main方法主要完成:
1.Register zygote socket, Registers a server socket for zygotecommand connections
2.Load preload classes(the default file isdevice/java/android/preloaded-classes).
3.Load preload resources,Load in commonly used resources, so they can be shared across processes.
4.StartSystemServer, Prepare the arguments and fork for the system serverprocess.
具體執(zhí)行過程如下:
ZygoteInit.java(frameworks\base\core\java\com\android\internal\os)中的mian
main()
registerZygoteSocket()
preloadClasses()
loadLibrary()
Log.i(TAG, "Preloading classes...");
Runtime.loadLibrary
Dalvik_java_lang_Runtime_nativeLoad()
dvmLoadNativeCode()
LOGD("Trying to load lib %s %p\n", pathName, classLoader);
System.loadLibrary("media_jni");
preloadResources();
startSystemServer()
Zygote.forkSystemServer(parsedArgs.uid,parsedArgs.gid,parsedArgs.gids, debugFlags, null);
//Zygote.java(dalvik\libcore\dalvik\src\main\java\dalvik\system)
forkSystemServer()
forkAndSpecialize() //Zygote.java(dalvik\libcore\dalvik\src\main\java\dalvik\system)
Dalvik_dalvik_system_Zygote_forkAndSpecialize() //dalvik_system_Zygote.c(dalvik\vm\native)
Dalvik_dalvik_system_Zygote_forkAndSpecialize()
setSignalHandler()
fork()
handleSystemServerProcess() //handleChildProc(parsedArgs, descriptors,newStderr);
closeServerSocket();
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
zygoteInit() //RuntimeInit.java(frameworks\base\core\java\com\android\internal\os)
zygoteInitNative()
invokeStaticMain()
System.loadLibrary("android_servers");
//com.android.server.SystemServer startSystemServer() 函數(shù)中
m = cl.getMethod("main", new Class[] { String[].class });
//執(zhí)行的是SystemServer 類的main函數(shù) SystemServer.java(frameworks\base\services\java\com\android\server)
init1() //SystemServer.java(frameworks\base\services\java\com\android\server)
//init1()實際上是調(diào)用android_server_SystemServer_init1(JNIEnv* env, jobjectclazz)
//com_android_server_SystemServer.cpp(frameworks\base\services\jni)
android_server_SystemServer_init1()//JNI 調(diào)用
system_init() //System_init.cpp(frameworks\base\cmds\system_server\library)
//Start the SurfaceFlinger
SurfaceFlinger::instantiate();
//Start theAudioFlinger media playback camera service
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
//調(diào)用 SystemServer類的init2
runtime->callStatic("com/android/server/SystemServer", "init2");
init2()//SystemServer.java(frameworks\base\services\java\com\android\server)
ServerThread()
run()//在run中啟動電源管理,藍牙,等核心服務以及狀態(tài),查找等其他服務
((ActivityManagerService)ServiceManager.getService("activity")).setWindowManager(wm);
...
ActivityManagerNative.getDefault().systemReady();
runSelectLoopMode();
done = peers.get(index).runOnce();
forkAndSpecialize() //Zygote.java(dalvik\libcore\dalvik\src\main\java\dalvik\system)
Dalvik_dalvik_system_Zygote_forkAndSpecialize() //dalvik_system_Zygote.c(dalvik\vm\native)
forkAndSpecializeCommon()
setSignalHandler()
RETURN_INT(pid);
closeServerSocket();
見附A
主進程runSelectLoopMode()
5.Runs thezygote process's select loop runSelectLoopMode(), Accepts newconnections as they happen, and reads commands from connections onespawn-request's worth at a time.
如果運行正常,則zygote進程會在runSelectLoopMode()中循環(huán):
zygote 被siganl(11)終止
在 dalvik_system_Zygote.c (dalvik\vm\native)
的 static voidsigchldHandler(int s) 函數(shù)中打?。?nbsp;
"Process %d terminated bysignal (%d)\n",
"Exit zygote because system server (%d) hasterminated\n",
startSystemServer() ZygoteInit.java(frameworks\base\core\java\com\android\internal\os)
SystemServer的mian()函數(shù)會調(diào)用
SystemServer.java(frameworks\base\services\java\com\android\server)中的 init1()函數(shù)。
init1()實際執(zhí)行的是com_android_server_SystemServer.cpp (frameworks\base\services\jni)
中的 android_server_SystemServer_init1()。
android_server_SystemServer_init1()調(diào)用的是
System_init.cpp (frameworks\base\cmds\system_server\library) 中的system_init()函數(shù)
system_init()函數(shù)定義如下:
extern "C" status_tsystem_init()
{
...
sp<IServiceManager> sm =defaultServiceManager();
...
property_get("system_init.startsurfaceflinger", propBuf, "1");
if(strcmp(propBuf, "1") == 0) {
//讀取屬性服務器,開啟啟動SurfaceFlinger服務
//接著會開始顯示機器人圖標
//BootAnimation.cpp (frameworks\base\libs\surfaceflinger):status_tBootAnimation::readyToRun()
SurfaceFlinger::instantiate();
}
//在模擬器上 audioflinger 等幾個服務與設(shè)備上的啟動過程不一樣,所以
//我們在這里啟動他們。
if (!proc->supportsProcesses()) {
//啟動 AudioFlinger,mediaplayback service,camera service服務
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
}
//現(xiàn)在開始運行 the Androidruntime ,我們這樣做的目的是因為必須在 core system services
//起來以后才能 Androidruntime initialization,其他服務在調(diào)用他們自己的main()時,都會
//調(diào)用 Androidruntime
//before calling the init function.
LOGI("Systemserver: starting Android runtime.\n");
AndroidRuntime* runtime =AndroidRuntime::getRuntime();
LOGI("System server: startingAndroid services.\n");
//調(diào)用 SystemServer.java(frameworks\base\services\java\com\android\server)
//中的init2函數(shù)
runtime->callStatic("com/android/server/SystemServer", "init2");
// If running in our own process, just go into the thread
// pool. Otherwise, call the initialization finished
// func tolet this process continue its initilization.
if(proc->supportsProcesses()) {
LOGI("System server:entering thread pool.\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOGI("Systemserver: exiting thread pool.\n");
}
return NO_ERROR;
}
Systemserver: entering thread pool 表明已經(jīng)進入服務線程 ServerThread
在 ServerThread類的run 服務中開啟核心服務:
@Override
public void run() {
EventLog.writeEvent(LOG_BOOT_PROGRESS_SYSTEM_RUN,
SystemClock.uptimeMillis());
ActivityManagerService.prepareTraceFile(false); // create dir
Looper.prepare();
//設(shè)置線程的優(yōu)先級
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
...
//關(guān)鍵(核心)服務
try {
Log.i(TAG, "Starting PowerManager.");
Log.i(TAG, "Starting activity Manager.");
Log.i(TAG, "Starting telephony registry");
Log.i(TAG,"Starting Package Manager.");
Log.i(TAG, "tartingContent Manager.");
Log.i(TAG, "Starting System ContentProviders.");
Log.i(TAG, "Starting Battery Service.");
Log.i(TAG, "Starting Alarm Manager.");
Log.i(TAG,"Starting Sensor Service.");
Log.i(TAG, "Starting WindowManager.");
Log.i(TAG, "Starting Bluetooth Service.");
//如果是模擬器,那么跳過藍牙服務。
// Skip Bluetooth if we have anemulator kernel
//其他的服務
Log.i(TAG, "StartingStatus Bar Service.");
Log.i(TAG, "Starting ClipboardService.");
Log.i(TAG, "Starting Input Method Service.");
Log.i(TAG, "Starting Hardware Service.");
Log.i(TAG,"Starting NetStat Service.");
Log.i(TAG, "StartingConnectivity Service.");
Log.i(TAG, "StartingNotification Manager.");
// MountService must start afterNotificationManagerService
Log.i(TAG, "Starting MountService.");
Log.i(TAG, "Starting DeviceStorageMonitorservice");
Log.i(TAG, "Starting Location Manager.");
Log.i(TAG, "Starting Search Service.");
...
if (INCLUDE_DEMO) {
Log.i(TAG, "Installing demodata...");
(new DemoThread(context)).start();
}
try {
Log.i(TAG, "Starting CheckinService.");
Intent intent = newIntent().setComponent(new ComponentName(
"com.google.android.server.checkin",
"com.google.android.server.checkin.CheckinService"));
if (context.startService(intent) == null) {
Log.w(TAG, "Using fallback Checkin Service.");
ServiceManager.addService("checkin", newFallbackCheckinService(context));
}
}catch (Throwable e) {
Log.e(TAG, "Failure startingCheckin Service", e);
}
Log.i(TAG,"Starting Wallpaper Service");
Log.i(TAG, "Starting AudioService");
Log.i(TAG, "Starting HeadsetObserver");
Log.i(TAG, "Starting AppWidget Service");
...
try {
com.android.server.status.StatusBarPolicy.installIcons(context,statusBar);
} catch (Throwable e) {
Log.e(TAG, "Failure installing status bar icons", e);
}
}
// make sure the ADB_ENABLED setting value matches thesecure property value
Settings.Secure.putInt(mContentResolver, Settings.Secure.ADB_ENABLED,
"1".equals(SystemProperties.get("persist.service.adb.enable")) ? 1 :0);
// register observer to listen for settings changes
mContentResolver.registerContentObserver(Settings.Secure.getUriFor(Settings.Secure.ADB_ENABLED),
false, new AdbSettingsObserver());
// It is now time tostart up the app processes...
boolean safeMode =wm.detectSafeMode();
if (statusBar != null) {
statusBar.systemReady();
}
if (imm != null) {
imm.systemReady();
}
wm.systemReady();
power.systemReady();
try {
pm.systemReady();
} catch (RemoteException e) {
}
if (appWidget !=null) {
appWidget.systemReady(safeMode);
}
// After making the following code, third party code may be running...
try {
ActivityManagerNative.getDefault().systemReady();
} catch (RemoteException e) {
}
Watchdog.getInstance().start();
Looper.loop();
Log.d(TAG, "System ServerThread is exiting!");
}
startActivity()
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
ActivityManagerService.java3136p (frameworks\base\services\java\com\android\server\am)
startActivity()
startActivityLocked() //3184
int res =startActivityLocked(caller, intent, resolvedType,grantedUriPermissions,grantedMode, aInfo,
resultTo, resultWho,requestCode, -1, -1,
onlyIfNeeded,componentSpecified);
public abstract classActivityManagerNative extends Binder implements IActivityManager
ActivityManagerService.java1071p (frameworks\base\services\java\com\android\server\am)
ActivityManagerService.main()
//ActivityManagerService.java 7375p(frameworks\base\services\java\com\android\server\am)
m.startRunning(null, null, null, null);
//ActivityManagerService.java 7421p(frameworks\base\services\java\com\android\server\am)
systemReady();
ActivityManagerService.java 3136p(frameworks\base\services\java\com\android\server\am)
startActivity(IApplicationThread caller,Intent intent,...)
intstartActivityLocked(caller, intent,...) //3184L 定義:2691L
void startActivityLocked() //3132L 定義:2445L
resumeTopActivityLocked(null); //2562p 定義:2176L
if(next=NULL)
{
intent.addCategory(Intent.CATEGORY_HOME);
startActivityLocked(null, intent, null, null, 0, aInfo,null, null, 0, 0,0, false, false);
}
else
{
startSpecificActivityLocked(next, true, false); //2439L 定義:1628L
realStartActivityLocked() //1640L 定義:1524L
//1651L定義:1654L
startProcessLocked(r.processName,r.info.applicationInfo, true, 0,"activity", r.intent.getComponent());
//1717L 定義:1721L
startProcessLocked(app, hostingType,hostingNameStr);
//1768L 定義:Process.java222L(frameworks\base\core\java\android\os)
int pid =Process.start("android.app.ActivityThread",...)
startViaZygote(processClass, niceName, uid, gid, gids,debugFlags,zygoteArgs);
pid =zygoteSendArgsAndGetPid(argsForZygote);
sZygoteWriter.write(Integer.toString(args.size()));
}
runSelectLoopMode();
done = peers.get(index).runOnce();
forkAndSpecialize() //Zygote.java(dalvik\libcore\dalvik\src\main\java\dalvik\system)
Dalvik_dalvik_system_Zygote_forkAndSpecialize() //dalvik_system_Zygote.c(dalvik\vm\native)
forkAndSpecializeCommon()
setSignalHandler()
RETURN_INT(pid);
ActivityThread main()
ActivityThread attach()//ActivityThread.java 3870p (frameworks\base\core\java\android\app)
mgr.attachApplication(mAppThread)
//ActivityManagerService.java 4677p(frameworks\base\services\java\com\android\server\am)
attachApplication()
//ActivityManagerService.java 4677p(frameworks\base\services\java\com\android\server\am)
attachApplicationLocked()
if(realStartActivityLocked(hr, app, true, true))//ActivityManagerService.java 4609p(frameworks\base\services\java\com\android\server\am)
realStartActivityLocked()
//ActivityManagerService.java(frameworks\base\services\java\com\android\server\am)
app.thread.scheduleLaunchActivity(new Intent(r.intent), r,r.info,r.icicle, results, newIntents, !andResume,isNextTransitionForward());
scheduleLaunchActivity()
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
ActivityThread.H.handleMessage()
handleLaunchActivity() //ActivityThread.java(frameworks\base\core\java\android\app)
performLaunchActivity() //ActivityThread.java(frameworks\base\core\java\android\app)
activity = mInstrumentation.newActivity(cl, component.getClassName(),r.intent);
/////////////////////////////////////////////////
init 守護進程:
//andriod init 函數(shù)啟動過程分析:
在main循環(huán)中會重復調(diào)用
drain_action_queue();
restart_processes();
staticvoid restart_processes()
{
process_needs_restart = 0;
service_for_each_flags(SVC_RESTARTING,
restart_service_if_needed);
}
通過循環(huán)檢測服務列表service_list 中每個服務的svc->flags 標記,如果為 SVC_RESTARTING,
那么在滿足條件的情況下調(diào)用:restart_service_if_needed
通過 service_start 來再次啟動該服務。
ActivityManagerService.main
I/SystemServer( 45): Starting Power Manager.
I/ServiceManager( 26): service'SurfaceFlinger' died
D/Zygote ( 30): Process 45 terminated bysignal (11)
I/Zygote ( 30): Exit zygote because system server (45)has terminated
通過錯誤信息發(fā)現(xiàn)程序在調(diào)用 SurfaceFlinger服務的時候被中止。
Service_manager.c(frameworks\base\cmds\servicemanager):
LOGI("service '%s' died\n",str8(si->name));
Binder.c (frameworks\base\cmds\servicemanager):
death->func(bs,death->ptr);
Binder.c (kernel\drivers\misc)中的函數(shù)
binder_thread_read()
structbinder_work *w;
switch (w->type)
為 BINDER_WORK_DEAD_BINDER 的時候
binder_parse()中
當 cmd 為 BR_DEAD_BINDER的時候
執(zhí)行 death->func(bs, death->ptr)
因為函數(shù)
int do_add_service(struct binder_state *bs,
uint16_t *s, unsigned len,
void *ptr, unsigneduid)
的 si->death.func = svcinfo_death;
所以 death->func(bs,death->ptr) 實際上執(zhí)行的是
svcinfo_death()//Service_manager.c(frameworks\base\cmds\servicemanager)
所以會打印出:service 'SurfaceFlinger'died
I/ServiceManager( 26): service 'SurfaceFlinger' died
Thread::run
_threadLoop() // Threads.cpp (frameworks\base\libs\utils)
status_t SurfaceFlinger::readyToRun()
mBootAnimation = newBootAnimation(this);
資料:
http://feixf1974.javaeye.com/blog/187773