init 进程是Android系统中用户进程空间的第一个进程,进程号为一,创建Zygote和服务属性等,init进程由多个源文件共同组成,源码放在system/core/init 中。Android系统底层基于Linux Kernel, 当Kernel启动过程会创建init进程, 该进程是所有用户空间的鼻祖, init进程会启动servicemanager(binder服务管家), Zygote进程(Java进程的鼻祖). Zygote进程会创建 system_server进程以及各种app进程。
init是Linux系统中用户空间的第一个进程, Kerner启动后会调用/system/core/init/Init.cpp的main()方法.
int main(int argc, char** argv) { ... klog_init(); //初始化kernel log property_init(); //创建一块共享的内存空间,用于属性服务 signal_handler_init(); //初始化子进程退出的信号处理过程 property_load_boot_defaults(); //加载/default.prop文件 start_property_service(); //启动属性服务器(通过socket通信) init_parse_config_file("/init.rc"); //解析init.rc文件 //执行rc文件中触发器为 on early-init的语句 action_for_each_trigger("early-init", action_add_queue_tail); //执行rc文件中触发器为 on init的语句 action_for_each_trigger("init", action_add_queue_tail); //执行rc文件中触发器为 on late-init的语句 action_for_each_trigger("late-init", action_add_queue_tail); while (true) { if (!waiting_for_exec) { execute_one_command(); restart_processes(); } int timeout = -1; if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000; if (timeout < 0) timeout = 0; } if (!action_queue_empty() || cur_action) { timeout = 0; } epoll_event ev; //循环 等待事件发生 int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout)); if (nr == -1) { ERROR("epoll_wait failed: %s ", strerror(errno)); } else if (nr == 1) { ((void (*)()) ev.data.ptr)(); } } return 0; }
init进程的主要功能点:
- 分析和运行所有的init.rc文件;
- 生成设备驱动节点; (通过rc文件创建,一个服务一个rc文件)
- 处理子进程的终止(signal方式);
- 提供属性服务property service。
init.rc
当init解析到下面这条语句,便会启动Zygote进程
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main //伴随着main class的启动而启动 socket zygote stream 660 root system //创建socket onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart media //当zygote重启时,则会重启media onrestart restart netd // 当zygote重启时,则会重启netd
当init子进程(Zygote)退出时,会产生SIGCHLD信号,并发送给init进程,通过socket套接字传递数据,调用到wait_for_one_process()方法,根据是否是oneshot,来决定是重启子进程,还是放弃启动。由于缺省模式oneshot=false,因此Zygote一旦被杀便会再次由init进程拉起。