Android启动篇 — init原理(一)中讲解分init进程分析init创建系统目录并挂在相应系统文件、初始化属性域、设置系统属性、启动配置属性服务端等一系列复杂工作,很多工作和知识点跟Linux关系很大,所以没有作过多介绍,而本此对于init.rc的解析则是重中之重,所以单独拿出来进行详细分析。

Java代码
  1. int?main(int?argc,?char**?argv)?{??
  2. ????/*?01.?创建文件系统目录并挂载相关的文件系统?*/??
  3. ????/*?02.?屏蔽标准的输入输出/初始化内核log系统?*/??
  4. ????/*?03.?初始化属性域?*/??
  5. ????/*?04.?完成SELinux相关工作?*/???
  6. ????/*?05.?重新设置属性?*/??
  7. ????/*?06.?创建epoll句柄?*/??
  8. ????/*?07.?装载子进程信号处理器?*/??
  9. ????/*?08.?设置默认系统属性?*/??
  10. ????/*?09.?启动配置属性的服务端?*/??
  11. ????/*?10.?匹配命令和函数之间的对应关系?*/??
  12. -------------------------------------------------------------------------------------------???//?Android启动篇?—?init原理(一)中讲解??
  13. ????/*?11.?解析init.rc?*/??
  14. ????Parser&?parser?=?Parser::GetInstance();???????//?构造解析文件用的parser对象??
  15. ????//?增加ServiceParser为一个section,对应name为service??
  16. ????parser.AddSectionParser("service",std::make_unique());??
  17. ????//?增加ActionParser为一个section,对应name为action??
  18. ????parser.AddSectionParser("on",?std::make_unique());??
  19. ????//?增加ImportParser为一个section,对应name为service??
  20. ????parser.AddSectionParser("import",?std::make_unique());??
  21. ????parser.ParseConfig("/init.rc");??????//?开始实际的解析过程??

  【正文】

  init.rc是一个配置文件,内部由Android初始化语言编写(Android Init Language)编写的脚本,主要包含五种类型语句:Action、Command、Service、Option和Import,在分析代码的过程中我们会详细介绍。

  init.rc的配置代码在:system/core/rootdir/init.rc 中

  init.rc文件是在init进程启动后执行的启动脚本,文件中记录着init进程需执行的操作。

  init.rc文件大致分为两大部分,一部分是以“on”关键字开头的动作列表(action list):

XML/HTML代码
  1. on?early-init??????//?Action类型语句??
  2. ????#?Set?init?and?its?forked?children's?oom_adj.?????//?#:注释符号??
  3. ????write?/proc/1/oom_score_adj?-1000??
  4. ????...?...??
  5. ????start?ueventd??

  Action类型语句格式:

XML/HTML代码
  1. on?<trigger>?[&&?<trigger>]*?????//?设置触发器????
  2. ???<command>????
  3. ???<command>??????//?动作触发之后要执行的命令??

  另一部分是以“service”关键字开头的服务列表(service list): ?如 Zygote

XML/HTML代码
  1. service?ueventd?/sbin/ueventd??
  2. ????class?core??
  3. ????critical??
  4. ????seclabel?u:r:ueventd:s0??

  Service类型语句格式:

XML/HTML代码
  1. service?<name>?<pathname>?[?<argument>?]*???//?<service的名字><执行程序路径><传递参数>????
  2. ???<option>???????//?option是service的修饰词,影响什么时候、如何启动services????
  3. ???<option>????
  4. ???...??

  借助系统环境变量或Linux命令,动作列表用于创建所需目录,以及为某些特定文件指定权限,而服务列表用来记录init进程需要启动的一些子进程。如上面代码所示,service关键字后的第一个字符串表示服务(子进程)的名称,第二个字符串表示服务的执行路径。

  值得一提的是在Android 7.0中对init.rc文件进行了拆分,每个服务一个rc文件。我们要分析的zygote服务的启动脚本则在init.zygoteXX.rc中定义。

  在init.rc的import段我们看到如下代码:

XML/HTML代码
  1. import?/init.${ro.zygote}.rc?????//?可以看出init.rc不再直接引入一个固定的文件,而是根据属性ro.zygote的内容来引入不同的文件??

  说明:

  从android5.0开始,android开始支持64位的编译,zygote本身也就有了32位和64位的区别,所以在这里用ro.zygote属性来控制启动不同版本的zygote进程。

  init.rc位于/system/core/rootdir下。在这个路径下还包括四个关于zygote的rc文件。分别是Init.zygote32.rc,Init.zygote32_64.rc,Init.zygote64.rc,Init.zygote64_32.rc,由硬件决定调用哪个文件。

  这里拿32位处理器为例,init.zygote32.rc的代码如下所示:

XML/HTML代码
  1. service?zygote?/system/bin/app_process?-Xzygote?/system/bin?--zygote?--start-system-server??
  2. ????class?main?????????#?class是一个option,指定zygote服务的类型为main??
  3. ????socket?zygote?stream?660?root?system??????????#?socket关键字表示一个option,创建一个名为dev/socket/zygote,类型为stream,权限为660的socket??
  4. ????onrestart?write?/sys/android_power/request_state?wake??????????#?onrestart是一个option,说明在zygote重启时需要执行的command??
  5. ????onrestart?write?/sys/power/state?on??
  6. ????onrestart?restart?audioserver??
  7. ????onrestart?restart?cameraserver??
  8. ????onrestart?restart?media??
  9. ????onrestart?restart?netd??
  10. ????writepid?/dev/cpuset/foreground/tasks??

  “service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server”

  在Init.zygote32.rc中,定义了一个zygote服务:zygote,由关键字service告诉init进程创建一个名为zygote的进程,这个进程要执行的程序是:/system/bin/app_process,给这个进程四个参数:

  · -Xzygote:该参数将作为虚拟机启动时所需的参数

  · /system/bin:代表虚拟机程序所在目录

  · --zygote:指明以ZygoteInit.java类中的main函数作为虚拟机执行入口

  · --start-system-server:告诉Zygote进程启动SystemServer进程

  接下来,我们回到源码当中,继续分析main函数:

Java代码
  1. /*?11.?解析init.rc?*/??
  2. Parser&?parser?=?Parser::GetInstance();???????//?构造解析文件用的parser对象??
  3. //?增加ServiceParser为一个section,对应name为service??
  4. parser.AddSectionParser("service",std::make_unique());??
  5. //?增加ActionParser为一个section,对应name为action??
  6. parser.AddSectionParser("on",?std::make_unique());??
  7. //?增加ImportParser为一个section,对应name为service??
  8. parser.AddSectionParser("import",?std::make_unique());??
  9. parser.ParseConfig("/init.rc");??????//?开始实际的解析过程

  说明:

  上面在解析init.rc文件时使用了Parser类(在init目录下的init_parser.h中定义), 初始化ServiceParser用来解析 “service”块,ActionParser用来解析"on"块,ImportParser用来解析“import”块,“import”是用来引入一个init配置文件,来扩展当前配置的。

  /system/core/init/readme.txt 中对init文件中的所有关键字做了介绍,主要包含了Actions, Commands, Services, Options, and Imports等,可自行学习解读。

  分析init.rc的解析过程:函数定义于system/core/init/ init_parser.cpp中

Java代码
  1. bool?Parser::ParseConfig(const?std::string&?path)?{??
  2. ????if?(is_dir(path.c_str()))?{???????????//?判断传入参数是否为目录地址??
  3. ????????return?ParseConfigDir(path);??????//?递归目录,最终还是靠ParseConfigFile来解析实际的文件??
  4. ????}??
  5. ????return?ParseConfigFile(path);?????????//?传入传输为文件地址??
  6. }??

  继续分析ParseConfigFile():

Java代码
  1. bool?Parser::ParseConfigFile(const?std::string&?path)?{??
  2. ????...?...??
  3. ????Timer?t;??
  4. ????std::string?data;??
  5. ????if?(!read_file(path.c_str(),?&data))?{???????//?读取路径指定文件中的内容,保存为字符串形式??
  6. ????????return?false;??
  7. }??
  8. ...?...??
  9. ????ParseData(path,?data);????????//?解析获取的字符串??
  10. ????...?...??
  11. }??

  跟踪ParseData():

Java代码
  1. void?Parser::ParseData(const?std::string&?filename,?const?std::string&?data)?{??
  2. ????...?...??
  3. ????parse_state?state;??
  4. ????...?...??
  5. ????std::vector?args;??
  6. ??
  7. ????for?(;;)?{??
  8. ????????switch?(next_token(&state))?{????//?next_token以行为单位分割参数传递过来的字符串,最先走到T_TEXT分支??
  9. ????????case?T_EOF:??
  10. ????????????if?(section_parser)?{??
  11. ????????????????section_parser->EndSection();????//?解析结束??
  12. ????????????}??
  13. ????????????return;??
  14. ????????case?T_NEWLINE:??
  15. ????????????state.line++;??
  16. ????????????if?(args.empty())?{??
  17. ????????????????break;??
  18. ????????????}??
  19. ????????????//?在前文创建parser时,我们为service,on,import定义了对应的parser???
  20. ????????????//?这里就是根据第一个参数,判断是否有对应的parser??
  21. ????????????if?(section_parsers_.count(args[0]))?{??
  22. ????????????????if?(section_parser)?{??
  23. ????????????????????//?结束上一个parser的工作,将构造出的对象加入到对应的service_list与action_list中??
  24. ????????????????????section_parser->EndSection();??
  25. ????????????????}??
  26. ????????????????//?获取参数对应的parser??
  27. ????????????????section_parser?=?section_parsers_[args[0]].get();??
  28. ????????????????std::string?ret_err;??
  29. ????????????????//?调用实际parser的ParseSection函数??
  30. ????????????????if?(!section_parser->ParseSection(args,?&ret_err))?{??
  31. ????????????????????parse_error(&state,?"%s\n",?ret_err.c_str());??
  32. ????????????????????section_parser?=?nullptr;??
  33. ????????????????}??
  34. ????????????}?else?if?(section_parser)?{??
  35. ????????????????std::string?ret_err;??
  36. ????????????????//?如果第一个参数不是service,on,import??
  37. ????????????????//?则调用前一个parser的ParseLineSection函数??
  38. ????????????????//?这里相当于解析一个参数块的子项??
  39. ????????????????if?(!section_parser->ParseLineSection(args,?state.filename,???
  40. ?????????????????????????????????????????????????????????????state.line,?&ret_err))?{??
  41. ????????????????????parse_error(&state,?"%s\n",?ret_err.c_str());??
  42. ????????????????}??
  43. ????????????}??
  44. ????????????args.clear();???????//?清空本次解析的数据??
  45. ????????????break;??
  46. ????????case?T_TEXT:??
  47. ????????????args.emplace_back(state.text);?????//将本次解析的内容写入到args中??
  48. ????????????break;??
  49. ????????}??
  50. ????}??
  51. }??

  至此,init.rc解析完,接下来init会执行几个重要的阶段:

Java代码
  1. int?main(int?argc,?char**?argv)?{??
  2. ????/*?01.?创建文件系统目录并挂载相关的文件系统?*/??
  3. ????/*?02.?屏蔽标准的输入输出/初始化内核log系统?*/??
  4. ????/*?03.?初始化属性域?*/??
  5. ????/*?04.?完成SELinux相关工作?*/???
  6. ????/*?05.?重新设置属性?*/??
  7. ????/*?06.?创建epoll句柄?*/??
  8. ????/*?07.?装载子进程信号处理器?*/??
  9. ????/*?08.?设置默认系统属性?*/??
  10. ????/*?09.?启动配置属性的服务端?*/??
  11. ????/*?10.?匹配命令和函数之间的对应关系?*/??
  12. ????/*?11.?解析init.rc*/??
  13. ----------------------------------------------------------------------------??
  14.   /*?12.??向执行队列中添加其他action?*/??
  15. ????//?获取ActionManager对象,需要通过am对命令执行顺序进行控制??
  16. ????ActionManager&?am?=?ActionManager::GetInstance();??
  17. ????//?init执行命令触发器主要分为early-init,init,late-init,boot等??
  18. ????am.QueueEventTrigger("early-init");????//?添加触发器early-init,执行on?early-init内容??
  19. ??
  20. ????//?Queue?an?action?that?waits?for?coldboot?done?so?we?know?ueventd?has?set?up?all?of?/dev...??
  21. ????am.QueueBuiltinAction(wait_for_coldboot_done_action,?"wait_for_coldboot_done");??
  22. ????//?...?so?that?we?can?start?queuing?up?actions?that?require?stuff?from?/dev.??
  23. ????am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action,?"mix_hwrng_into_linux_rng");??
  24. ????am.QueueBuiltinAction(keychord_init_action,?"keychord_init");??
  25. ????am.QueueBuiltinAction(console_init_action,?"console_init");??
  26. ??
  27. ????//?Trigger?all?the?boot?actions?to?get?us?started.??
  28. ????am.QueueEventTrigger("init");????????//?添加触发器init,执行on?init内容,主要包括创建/挂在一些目录,以及symlink等??
  29. ??
  30. ????//?Repeat?mix_hwrng_into_linux_rng?in?case?/dev/hw_random?or?/dev/random??
  31. ????//?wasn't?ready?immediately?after?wait_for_coldboot_done??
  32. ????am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action,?"mix_hwrng_into_linux_rng");??
  33. ??
  34. ????//?Don't?mount?filesystems?or?start?core?system?services?in?charger?mode.??
  35. ????if?(bootmode?==?"charger")?{??
  36. ????am.QueueEventTrigger("charger");?????//?on?charger阶段??
  37. ????}?else?if?(strncmp(bootmode.c_str(),?"ffbm",?4)?==?0)?{??
  38. ????NOTICE("Booting?into?ffbm?mode\n");??
  39. ????am.QueueEventTrigger("ffbm");??
  40. ????}?else?{??
  41. ????am.QueueEventTrigger("late-init");??????????//?非充电模式添加触发器last-init??
  42. ????}??
  43. ??
  44. ????//?Run?all?property?triggers?based?on?current?state?of?the?properties.??
  45. ????am.QueueBuiltinAction(queue_property_triggers_action,?"queue_property_triggers");??

  在last-init最后阶段有如下代码:

XML/HTML代码
  1. #?Mount?filesystems?and?start?core?system?services.??
  2. on?late-init??
  3. ????trigger?early-fs??
  4. ??
  5. ????#?Mount?fstab?in?init.{$device}.rc?by?mount_all?command.?Optional?parameter??
  6. ????#?'--early'?can?be?specified?to?skip?entries?with?'latemount'.??
  7. ????#?/system?and?/vendor?must?be?mounted?by?the?end?of?the?fs?stage,??
  8. ????#?while?/data?is?optional.??
  9. ????trigger?fs??
  10. ????trigger?post-fs??
  11. ??
  12. ????#?Load?properties?from?/system/?+?/factory?after?fs?mount.?Place??
  13. ????#?this?in?another?action?so?that?the?load?will?be?scheduled?after?the?prior??
  14. ????#?issued?fs?triggers?have?completed.??
  15. ????trigger?load_system_props_action??
  16. ??
  17. ????#?Mount?fstab?in?init.{$device}.rc?by?mount_all?with?'--late'?parameter??
  18. ????#?to?only?mount?entries?with?'latemount'.?This?is?needed?if?'--early'?is??
  19. ????#?specified?in?the?previous?mount_all?command?on?the?fs?stage.??
  20. ????#?With?/system?mounted?and?properties?form?/system?+?/factory?available,??
  21. ????#?some?services?can?be?started.??
  22. ????trigger?late-fs??
  23. ??
  24. ????#?Now?we?can?mount?/data.?File?encryption?requires?keymaster?to?decrypt??
  25. ????#?/data,?which?in?turn?can?only?be?loaded?when?system?properties?are?present.??
  26. ????trigger?post-fs-data??
  27. ??
  28. ????#?Load?persist?properties?and?override?properties?(if?enabled)?from?/data.??
  29. ????trigger?load_persist_props_action??
  30. ??
  31. ????#?Remove?a?file?to?wake?up?anything?waiting?for?firmware.??
  32. ????trigger?firmware_mounts_complete??
  33. ??
  34. ????trigger?early-boot??
  35.   ?trigger?boot??

  可见出发了on early-boot和on boot两个Action。

  我们看一下on boot:

XML/HTML代码
  1. on?boot??
  2. ????#?basic?network?init??
  3. ????ifup?lo??
  4. ????hostname?localhost??
  5. ????domainname?localdomain??
  6. ????...?...??
  7. ????class_start?core??

  在on boot 的最后class_start core 会启动class为core的服务,这些服务包括ueventd、logd、healthd、adbd(disabled)、lmkd(LowMemoryKiller)、servicemanager、vold、debuggerd、surfaceflinger、bootanim(disabled)等。

  回到主题,分析trigger触发器的代码,QueueEventTrigger():位于system/core/init/action.cpp

Java代码
  1. void?ActionManager::QueueEventTrigger(const?std::string&?trigger)?{??
  2. ????trigger_queue_.push(std::make_unique(trigger));??
  3. }??

  此处QueueEventTrigger函数就是利用参数构造EventTrigger,然后加入到trigger_queue_中。后续init进程处理trigger事件时,将会触发相应的操作。

  再看一下QueueBuiltinAction()函数:同样位于system/core/init/action.cpp

Java代码
  1. void?ActionManager::QueueBuiltinAction(BuiltinFunction?func,??
  2. ???????????????????????????????????const?std::string&?name)?{??
  3. ????//?创建action??
  4. ????auto?action?=?std::make_unique(true);??
  5. ????std::vector?name_vector{name};??
  6. ??
  7. ????//?保证唯一性??
  8. ????if?(!action->InitSingleTrigger(name))?{??
  9. ????????return;??
  10. ????}??
  11. ??
  12. ????//?创建action的cmd,指定执行函数和参数??
  13. ????action->AddCommand(func,?name_vector);??
  14. ??
  15. ????trigger_queue_.push(std::make_unique(action.get()));??
  16. ????actions_.emplace_back(std::move(action));??
  17. }??

  QueueBuiltinAction函数中构造新的action加入到actions_中,第一个参数作为新建action携带cmd的执行函数;第二个参数既作为action的trigger name,也作为action携带cmd的参数。

  接下来继续分析main函数:

Java代码
  1. int?main(int?argc,?char**?argv)?{??
  2. ????/*?01.?创建文件系统目录并挂载相关的文件系统?*/??
  3. ????/*?02.?屏蔽标准的输入输出/初始化内核log系统?*/??
  4. ????/*?03.?初始化属性域?*/??
  5. ????/*?04.?完成SELinux相关工作?*/???
  6. ????/*?05.?重新设置属性?*/??
  7. ????/*?06.?创建epoll句柄?*/??
  8. ????/*?07.?装载子进程信号处理器?*/??
  9. ????/*?08.?设置默认系统属性?*/??
  10. ????/*?09.?启动配置属性的服务端?*/??
  11. ????/*?10.?匹配命令和函数之间的对应关系?*/??
  12. ????/*?11.?解析init.rc*/??
  13. ????/*?12.?向执行队列中添加其他action?*/??
  14. -------------------------------------------------------------------??
  15. ????/*?13.?处理添加到运行队列的事件?*/??
  16. ????while?(true)?{??
  17. ????//?判断是否有事件需要处理??
  18. ????????if?(!waiting_for_exec)?{??
  19. ????????????//?依次执行每个action中携带command对应的执行函数??
  20. ?    am.ExecuteOneCommand();??
  21. ????????//?重启一些挂掉的进程??
  22. ????????????restart_processes();??
  23. ????????}??
  24. ??
  25. ????????//?以下决定timeout的时间,将影响while循环的间隔??
  26. ????????int?timeout?=?-1;??
  27. ????????//?有进程需要重启时,等待该进程重启??
  28. ????????if?(process_needs_restart)?{??
  29. ????????????timeout?=?(process_needs_restart?-?gettime())?*?1000;??
  30. ????????????if?(timeout?0)??
  31. ????????????????timeout?=?0;??
  32. ????????}??
  33. ??
  34. ????????//?有action待处理,不等待??
  35. ????????if?(am.HasMoreCommands())?{??
  36. ????????????timeout?=?0;??
  37. ????????}??
  38. ??
  39. ????????//?bootchart_sample应该是进行性能数据采样??
  40. ????????bootchart_sample(&timeout);??
  41. ??
  42. ????????epoll_event?ev;??
  43. ????????//?没有事件到来的话,最多阻塞timeout时间??
  44. ????????int?nr?=?TEMP_FAILURE_RETRY(epoll_wait(epoll_fd,?&ev,?1,?timeout));??
  45. ????????if?(nr?==?-1)?{??
  46. ????????????ERROR("epoll_wait?failed:?%s\n",?strerror(errno));??
  47. ????????}?else?if?(nr?==?1)?{??
  48. ????????????//有事件到来,执行对应处理函数??
  49. ????????????//根据上文知道,epoll句柄(即epoll_fd)主要监听子进程结束,及其它进程设置系统属性的请求??
  50. ????????????((void?(*)())?ev.data.ptr)();??
  51. ????????}??
  52. ????}??
  53. ????return?0;??
  54. }?//?end?main??

  看一下ExecuteOneComand()函数:同样位于system/core/init/action.cpp

Java代码
  1. void?ActionManager::ExecuteOneCommand()?{??
  2. ????//?Loop?through?the?trigger?queue?until?we?have?an?action?to?execute??
  3. ????//?当前的可执行action队列为空,?trigger_queue_队列不为空??
  4. ????while?(current_executing_actions_.empty()?&&?!trigger_queue_.empty())?{??
  5. ????//?循环遍历action_队列,包含了所有需要执行的命令,解析init.rc获得??
  6. ????????for?(const?auto&?action?:?actions_)?{??
  7. ????????????//?获取队头的trigger,?检查actions_列表中的action的trigger,对比是否相同??
  8. ????????????if?(trigger_queue_.front()->CheckTriggers(*action))?{??
  9. ????????????????//?将所有具有同一trigger的action加入当前可执行action队列??
  10. ????????????????current_executing_actions_.emplace(action.get());??
  11. ????????????}??
  12. ????????}??
  13. ????????//?将队头trigger出栈??
  14. ????????trigger_queue_.pop();??
  15. ????}??
  16. ??
  17. ????if?(current_executing_actions_.empty())?{???//?当前可执行的actions队列为空就返回??
  18. ????????return;??
  19. ????}??
  20. ??
  21. ????auto?action?=?current_executing_actions_.front();?//?获取当前可执行actions队列的首个action??
  22. ??
  23. ????if?(current_command_?==?0)?{??
  24. ????????std::string?trigger_name?=?action->BuildTriggersString();??
  25. ????????INFO("processing?action?(%s)\n",?trigger_name.c_str());??
  26. ????}??
  27. ??
  28. ????action->ExecuteOneCommand(current_command_);?????//?执行当前的命令??
  29. ??
  30. ????//?If?this?was?the?last?command?in?the?current?action,?then?remove??
  31. ????//?the?action?from?the?executing?list.??
  32. ????//?If?this?action?was?oneshot,?then?also?remove?it?from?actions_.??
  33. ????++current_command_;??????//?不断叠加,将action_中的所有命令取出??
  34. ????if?(current_command_?==?action->NumCommands())?{??
  35. ????????current_executing_actions_.pop();??
  36. ????????current_command_?=?0;??
  37. ????????if?(action->oneshot())?{??
  38. ????????????auto?eraser?=?[&action]?(std::unique_ptr&?a)?{??
  39. ????????????????return?a.get()?==?action;??
  40. ????????????};??
  41. ????????????actions_.erase(std::remove_if(actions_.begin(),?actions_.end(),?eraser));??
  42. ????????}??
  43. ????}??
  44. }??

  我们来观察一下init.rc的开头部分:

Java代码
  1. import?/init.environ.rc??
  2. import?/init.usb.rc??
  3. import?/init.${ro.hardware}.rc??
  4. import?/init.usb.configfs.rc??
  5. import?/init.${ro.zygote}.rc??????//?后面我们即将重点分析zygote进程??

  通过ro.zygote的属性import对应的zygote的rc文件。

Android启动篇 — init原理(二)

  我们查看init.zygote64_32.rc:

XML/HTML代码
  1. service?zygote?/system/bin/app_process64?-Xzygote?/system/bin?--zygote?--start-system-server?--socket-name=zygote??
  2. ????class?main??
  3. ????socket?zygote?stream?660?root?system??
  4. ????onrestart?write?/sys/android_power/request_state?wake??
  5. ????onrestart?write?/sys/power/state?on??
  6. ????onrestart?restart?audioserver??
  7. ????onrestart?restart?cameraserver??
  8. ????onrestart?restart?media??
  9. ????onrestart?restart?netd??
  10. ????writepid?/dev/cpuset/foreground/tasks??
  11. ??
  12. service?zygote_secondary?/system/bin/app_process32?-Xzygote?/system/bin?--zygote?--socket-name=zygote_secondary??
  13. ????class?main??
  14. ????socket?zygote_secondary?stream?660?root?system??
  15. ????onrestart?restart?zygote??
  16. ????writepid?/dev/cpuset/foreground/tasks??

  可以看到zygote的class是main, 它是在on nonencrypted时被启动的,如下:

XML/HTML代码
  1. on?boot??
  2. ????#?basic?network?init??
  3. ????ifup?lo??
  4. ????hostname?localhost??
  5. ????domainname?localdomain??
  6. ????...?...??
  7. ????class_start?core??
  8. ??
  9. on?nonencrypted??
  10. ????#?A/B?update?verifier?that?marks?a?successful?boot.??
  11. ????exec?-?root?cache?--?/system/bin/update_verifier?nonencrypted??
  12. ????class_start?main??
  13. ????class_start?late_start??

  至此,Init.cpp的main函数分析完毕!init进程已经启动完成,一些重要的服务如core服务和main服务也都启动起来,并启动了zygote(/system/bin/app_process64)进程,zygote初始化时会创建虚拟机,启动systemserver等。

本文发布:Android开发网
本文地址:http://www.jizhuomi.com/android/course/712.html
2017年9月11日
发布:鸡皇冠现金官网hg6388|首页 分类:Android开发教程 浏览: 评论:0