Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> 詳細分析Android的init進程的啟動過程

詳細分析Android的init進程的啟動過程

編輯:關於android開發

一、Android Init.c執行流程

Android中的內核啟動後,kernel會啟動第一個用戶級別的進程:init,它是一個由內核啟動的用戶級進程。內核自行啟動(已經被載入內存,開始運行,並已初始化所有的設備驅動程序和數據結構等)之後,就通過啟動一個用戶級程序init的方式,完成引導進程。init始終是第一個進程。
PS:可以通過:ps aux | grep init命令來查看其Pid為1。
init進程對應的代碼在android源碼目錄中的:system/core/init/init.c中。
789 int main(int argc, char **argv)
790 {
# 創建一些linux根文件系統中的目錄
817     mkdir("/dev", 0755);
818     mkdir("/proc", 0755);
819     mkdir("/sys", 0755);
820
821     mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");
822     mkdir("/dev/pts", 0755);
823     mkdir("/dev/socket", 0755);
824     mount("devpts", "/dev/pts", "devpts", 0, NULL);
825     mount("proc", "/proc", "proc", 0, NULL);
826     mount("sysfs", "/sys", "sysfs", 0, NULL); 
# 打開標准輸入,標准輸出,標准錯誤文件描述符
834     open_devnull_stdio();
# 讀取並且解析init.rc文件
838     parse_config_file("/init.rc");
# 取得硬件名
844     get_hardware_name();
845     snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
# 讀取並且解析硬件相關的init腳本文件
846     parse_config_file(tmp);
# 觸發在init腳本文件中名字為early-init的action,並且執行其commands,其實是: on early-init
848     action_for_each_trigger("early-init", action_add_queue_tail);
849     drain_action_queue();
# 初始化動態設備管理,設備文件有變化時反應給內核,後面具體解釋
852     device_fd = device_init();
# 加載啟動動畫,如果動畫打開失敗,則在屏幕上打印: A N D R O I D字樣。
872     if( load_565rle_image(INIT_IMAGE_FILE) ) {
 873     fd = open("/dev/tty0", O_WRONLY);
 874     if (fd >= 0) {
 875         const char *msg;
 876             msg = "\n"
 877         "\n"
 878         "\n"
 879         "\n"
 880         "\n"
 881         "\n"
 882         "\n"  // console is 40 cols x 30 lines
 883         "\n"
 884         "\n"
 885         "\n"
 886         "\n"
 887         "\n"
 888         "\n"
 889         "\n"
 890         //"             A N D R O I D ";
 891         write(fd, msg, strlen(msg));
 892         close(fd);
 893     }
 894     }
 895
# 觸發在init腳本文件中名字為init的action,並且執行其commands,其實是:on init
919     action_for_each_trigger("init", action_add_queue_tail);
 920     drain_action_queue();
# 啟動系統屬性服務: system property service
927     property_set_fd = start_property_service();

# 創建socket用來處理孤兒進程信號
930     if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) {
 931         signal_fd = s[0];
 932         signal_recv_fd = s[1];
 933         fcntl(s[0], F_SETFD, FD_CLOEXEC);
 934         fcntl(s[0], F_SETFL, O_NONBLOCK);
 935         fcntl(s[1], F_SETFD, FD_CLOEXEC);
 936         fcntl(s[1], F_SETFL, O_NONBLOCK);
 937     }

# 觸發在init腳本文件中名字為early-boot和boot的action,並且執行其commands,其實是:on early-boot和on boot
948     action_for_each_trigger("early-boot", action_add_queue_tail);
 949     action_for_each_trigger("boot", action_add_queue_tail);
 950     drain_action_queue();
# 啟動所有屬性變化觸發命令,其實是: on property:ro.xx.xx=xx
953     queue_all_property_triggers();
 954     drain_action_queue();
# 進入死循環
987     for(;;) {

# 啟動所有init腳本中聲明的service,
# 如:266 service servicemanager /system/bin/servicemanager
#     user system
#     critical
#     onrestart restart zygote
#     onrestart restart media
994         restart_processes();
# 多路監聽設備管理,子進程運行狀態,屬性服務
1012         nr = poll(ufds, fd_count, timeout);
1013         if (nr <= 0)
1014             continue;
1016         if (ufds[2].revents == POLLIN) {
1017             /* we got a SIGCHLD - reap and restart as needed */
1018             read(signal_recv_fd, tmp, sizeof(tmp));
1019             while (!wait_for_one_process(0))
1020                 ;
1021             continue;
1022         }
1023
1024         if (ufds[0].revents == POLLIN)
1025             handle_device_fd(device_fd);
1026
1027         if (ufds[1].revents == POLLIN)
1028             handle_property_set_fd(property_set_fd);
1029         if (ufds[3].revents == POLLIN)
1030             handle_keychord(keychord_fd);
1031     }
1032
1033     return 0;
1034 }

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved