android系統的初始化過程是從那裡開始呢?它在載入linux基本核心後,就開始運行一個初始化進程,叫做init進程,那麼怎麼樣知道它是載入init進程的呢?難道上天就註定的嗎?呵呵,不是的,原來是從android載入linux核心時,就設定了下面的參數:
Kernel command line: noinitrd root=/dev/nfs console=ttySAC0 init=/init nfsroot=192.168.1.103:/nfsboot ip=192.168.1.20:192.168.1.103:192.168.1.1:255.255.255.0::eth0:on
在這行命令裡,就是告訴linux核心初始化完成後開始運行init進程,由於init進程就是放在系統根目錄下面。而這個進程的代碼,就是位於源碼的目錄system/core/init下面,現在就來仔細地分析這個進程到底做了什麼事情,以便理解整個系統運行情況。在分析過程中,會學習很多有用知識,甚至linux編程知識。這麼有用,還等什麼呢?現在就開始,找到目錄system/core/init/init.c代碼,先從main函數開始,如下:
#001 int main(int argc, char **argv)
#002 {
#003 int device_fd = -1;
#004 int property_set_fd = -1;
#005 int signal_recv_fd = -1;
#006 int keychord_fd = -1;
#007 int fd_count;
#008 int s[2];
#009 int fd;
#010 struct sigaction act;
#011 char tmp[PROP_VALUE_MAX];
#012 struct pollfd ufds[4];
#013 char *tmpdev;
#014 char* debuggable;
#015
#016
#017 act.sa_handler = sigchld_handler;
#018 act.sa_flags = SA_NOCLDSTOP;
#019 act.sa_mask = 0;
#020 act.sa_restorer = NULL;
#021 sigaction(SIGCHLD, &act, 0);
在上面這段代碼裡,調用函數sigaction來設定處理子進程發送回來的關閉訊號,其中SIGCHLD是設定子進程訊號處理,SA_NOCLDSTOP是表示子進程結束時不要向父進程發送SIGCHLD,sigchld_handler是訊號SIGCHLD的處理函數。這樣做的作用,就是如果父進程不等待子進程結束,子進程將成為殭屍進程(zombie)從而佔用系統資源。因此需要對SIGCHLD訊號做出處理,回收殭屍進程的資源,避免造成不必要的資源浪費。