目录
1、Init进程概述
1.1 Android启动流程
1.2 直观感受
1.3 Init进程职责
2、解析init.rc
2.1 Android Init language
2.2 解析init.rc
2.3 循环触发Action
2.4 解析、启动service(zygote)
3、属性服务
3.1 获取属性(属性相当于Windows下的注册表)
3.2 属性服务启动
3.3 设置属性过程
4、服务守护进程
4.0 守护进程
4.1 init.c 无限循环遍历service_list进行守护
1、Init进程概述
- 1.1 Android启动流程
- 1.2 直观感受
- Init是Linux系统用户空间的第一个进程。也就是基于Linux内核的Android系统用户空间的第一个进程。
- 代码路径:system/core/init/init.c
- 1.3 Init进程职责
- 解析property文件并初始化property。
- 解析脚本init.rc,触发Action及启动Service。
- 提供系统property服务管理及完成对应的触发事件。
- 维护系统级Service。
2、解析init.rc
- 2.1 Android Init language
-
The Android Init Language consists of four broad classes of statements:
Action
Commands
Services
Options
-
Init Language的关键字及相关关键字处理函数定义:
system/core/init/keywords.h
例如:
KEYWORD(on, SECTION, 0, 0)
KEYWORD(service, SECTION, 0, 0)
-
on <trigger>
<command>
<command>
<command> ...
service <name> <pathname> [ <argument> ]*
<option>
<option> ...
-
- 2.2 解析init.rc
- 2.3 循环触发Action
-
for(;;) {
execute_one_command();
restart_processes();
......
}
execute_one_command的关键逻辑:
1.action_remove_queue_head函数获取action_queue链表中的第一个action节点2.通过action节点调用get_next_command函数获取它的下一个Command3.执行Command关键点,通过函数上层的for循环,首先获取Action节点,其次循环获取并执行Action节点下的Command,Command循环完成后,再获取下一个Action节点
-
- 2.4 解析、启动service(zygote)
-
service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
-
3、属性服务
- 3.1 获取属性(属性相当于Windows下的注册表)
- 使用 adb shell getprop
- 3.2 属性服务启动
-
Property服务启动入口:
action_queue中的Action:property_service_init,对应的函数指针: property_service_init_action
-
初始化调用过程:
property_service_init_action-> start_property_service-> load_properties_from_file& create_socket& listen&set property_set_fd
- 多路切换监听过程
1 for(;;) { 2 3 ...... 4 5 if (!property_set_fd_init && get_property_set_fd() > 0) { 6 7 ufds[fd_count].fd = get_property_set_fd(); 8 9 ufds[fd_count].events = POLLIN; 10 11 ufds[fd_count].revents = 0; 12 13 fd_count++; 14 15 property_set_fd_init = 1; 16 17 } 18 19 ...... 20 21 nr = poll(ufds, fd_count, timeout); 22 23 }
-
- 3.3 设置属性过程
- 有些Action有属性条件的:
on property:persist.service.adb.enable=1
start adbdqueue_property_triggers
action_add_queue_tail
4、服务守护进程
- 4.0 守护进程
守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程常常在系统引导装入时启动,在系统关闭时终止。Linux系统有很多守护进程,大多数服务都是通过守护进程实现的,同时,守护进程还能完成许多系统任务,例如,作业规划进程crond、打印进程lqd等(这里的结尾字母d就是Daemon的意思)。由于在Linux中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。但是守护进程却能够突破这种限制,它从被执行开始运转,直到整个系统关闭时才退出。如果想让某个进程不因为用户或终端或其他地变化而受到影响,那么就必须把这个进程变成一个守护进程。(摘自百度百科)
- 4.1 init.c 无限循环遍历service_list进行守护
-
1 for(;;) { 2 3 ... 4 //restart_processes作用 5 //循环获取service_list中的Service节点 6 //调用service_for_each_flags函数,通过Service节点中的flags、 time_started判断是否启动该Service 7 //调用service_start函数,fork子进程,创建Socket、执行启动Service等操作 8 9 restart_processes(); 10 11 ... 12 13 nr = poll(ufds, fd_count, timeout); 14 15 if (nr <= 0) 16 17 continue; 18 19 20 21 for (i = 0; i < fd_count; i++) { 22 23 if (ufds[i].revents & POLLIN) { 24 25 if (ufds[i].fd == get_property_set_fd()) 26 27 handle_property_set_fd(); 28 29 else if (ufds[i].fd == get_keychord_fd()) 30 31 handle_keychord(); 32 33 else if (ufds[i].fd == get_signal_fd()) 34 35 handle_signal(); 36 37 } 38 39 } 40 41 }
-