Android Init进程详解

来源:互联网 发布:java求1到100的乘积 编辑:程序博客网 时间:2024/05/22 00:52

init进程

init是一个由内核启动的用户级进程
init是Linux系统中用户空间的第一个进程。由于Android是基于Linux内核的,所以init也是Android系统中用户空间的第一个进程。
adb shell ps中init的PID为1,PPID为0
  • init进程主要作用
1.解析脚本init.rc2.根据init.rc配置信息,触发Action及启动Service3.解析系统property文件并初始化property信息4.提供系统property服务管理及完成对应的触发事件5.维护系统级Service


解析脚本init.rc

  • init.rc介绍
  • init解析init.rc过程
init进程从system/core/init/init.c中的int main(int argc, char **argv)方法开始执行解析init.rc是在main函数中的init_parse_config_file("/init.rc");中进行的,依次会执行如下操作:1.扫描init.rc中的token,找到其中的文件结束EOF/文本TEXT/新行NEWLINE,  其中的空格‘ ’、‘\t’、‘\r’会被忽略,#开头的行也被忽略掉;  而对于TEXT,空格‘ ’、‘\t’、‘\r’、‘\n’都是TEXT的结束标志。2.对每一个TEXT token,都加入到args[]数组中3.当遇到新一行(‘\n’)的时候,用lookup_keyword(args[0]);检索匹配关键字  1) 对Section(on和service),调用parse_new_section() 解析;     - 对on section,调用parse_action(),并设置解析函数parse_line为parse_line_action()     - 对service section,调用parse_service(),并设置解析函数parse_line为parse_line_service()  2) 对其他关键字的行(非on或service开头的地方,也就是没有切换section)调用parse_line()4.将解析出的action command添加到action_list中,将service添加到service_list5.执行action_for_each_trigger时,会把队列action_list里所匹配的action,追加到action_queue的队尾;
  • 解析init.rc涉及到的三个关键链表:
static list_declare(service_list);static list_declare(action_list);static list_declare(action_queue);
  • init动作的四个阶段:
init动作四个阶段包括early-init,init,early-boot,boot;//action_for_each_trigger方法会根据这四个阶段来将action_list里所匹配的action,添加到action_queue中;例如:action_for_each_trigger("early-init", action_add_queue_tail);1.early-init  wait_for_coldboot_done  keychord_init  console_init2.init  early-fs  fs  post-fs  post-fs-data  property_service_init  signal_init  check_startup3.early-boot4.boot


根据init.rc配置信息,触发Action及启动Service

init.c(system/core/init/init.c)中的int main(int argc, char **argv)

  • 在解析init.rc后,会调用action_for_each_trigger,queue_builtin_action会将action和一些初始化操作加到action_list中
  • 调用以下无限for循环,就开始触发action及启动service
for(;;) {   ......   execute_one_command();//触发action & 启动service   restart_processes();//处理重启的函数   ......} 
  • execute_one_command方法关键逻辑:
1.action_remove_queue_head函数获取action_queue链表中的第一个action节点2.通过action节点调用get_next_command函数获取它的下一个Command3.执行Commandvoid execute_one_command(void){   int ret;    if (!cur_action || !cur_command || is_last_command(cur_action, cur_command)) {       cur_action = action_remove_queue_head(); //获取action_queue链表中的第一个action节点       cur_command = NULL;       if (!cur_action)           return;       INFO("processing action %p (%s)\n", cur_action, cur_action->name);       cur_command = get_first_command(cur_action);   } else {       cur_command = get_next_command(cur_action, cur_command); //通过action节点调用get_next_command函数获取它的下一个Command   }       if (!cur_command)       return;   ret = cur_command->func(cur_command->nargs, cur_command->args); //执行Command   INFO("command '%s' r=%d\n", cur_command->args[0], ret);}
  • restart_processes中关键逻辑:
1.循环获取service_list中的Service节点2.调用service_for_each_flags函数,通过Service节点中的flags、 time_started判断是否启动该Service3.调用service_start函数,fork子进程,创建Socket、执行启动Service等操作  service_start函数来解释init.rc文件中的service命令static void restart_processes(){   process_needs_restart = 0;   service_for_each_flags(SVC_RESTARTING,restart_service_if_needed);    //调用service_for_each_flags函数,通过Service节点中的flags、 time_started判断是否启动该Service}


解析系统property文件并初始化property信息

  • 安卓中的属性服务类似于windows上的注册表机制;
  • 通过adb shell getprop获取系统当前属性
  • 属性服务是怎么启动的?
1.首先,属性服务也会有对于的action:property_service_init,queue_builtin_action会根据action去调用相应的处理方法:property_service_init_action2.初始化调用过程:property_service_init_action-> start_property_service-> load_properties_from_file(如build prop,system prop文件)& create_socket & listen & set property_set_fd(等待应用发送请求3.多路切换监听过程for(;;) {    ......    if (!property_set_fd_init && get_property_set_fd() > 0) {        ufds[fd_count].fd = get_property_set_fd();        ufds[fd_count].events = POLLIN;        ufds[fd_count].revents = 0;        fd_count++;        property_set_fd_init = 1;    }    ......    nr = poll(ufds, fd_count, timeout);}


提供系统property服务管理及完成对应的触发事件

  • setprop怎么工作的?
当执行setprop时就会执行Toolbox中的main函数toolbox是一个工具
  • 你是不是在想,setprop与init进程有什么关系呢?
init进程将属性服务启动后,属性服务运行在init进程里,并管理属性服务,当setprop时,toolbox就会与init进程进行交互;(个人理解)

Android System Train Note Android Init Setprop.jpg

维护系统级Service

  • init进程是如何维护系统级Service的?
1.在init.c的main函数中,会调用handle_signal方法,用于等待接收子进程退出时发送的signal信号;2.当子进程退出时,会调用sigchld_handler方法,发送一个signal信号(往socket中写数据)3.handle_signal中的wait_for_one_process方法接收到该信号后,会根据传过来的pid找到相应的service,并根据该service的flags执行相应操作(如,重启等),完成进程的维护。

Android System Train Note Android Init progress d.jpg

0 0
原创粉丝点击