Android 系统启动之init进程篇

https://rainmonth.github.io/posts/42f2ba4c.html

Android 系统启动之init进程篇

摘要

init进程是Linux系统中用户空间的第一个进程,进程号(pid)固定为1。在Linux内核启动后,会在用户控件启动init进程,并调用init中的main方法。init进程主要做了以下工作:

  • 负责创建系统中的几个关键进程,如Android世界的zygote进程;
  • 属性服务的创建初始化和启动;

Android 关心的比较核心的问题:

  • zygote进程如何被创建的;
  • init 进程的属性服务这块具体是如何工作的;

在分析init进程之前,先得知道init进程是如何启动的,参考文章

Android 8.1开机流程分析

init 分析

涉及到的文件(基于Android 6.0.0_r1)

  • /system/core/init/init.h
  • /system/core/init/init.cpp
  • /system/core/init/parser.h
  • /system/core/init/parser.cpp
  • /system/core/rootdir/init.rc(/system/core/rootdir/init.*.rc)
  • /system/core/init/keywords.h

在了解init 之前,可以先看看system/core/init/readme.txt,这个文件有init的一些详细说明。

源码中每个功能都是以一个目录的形式来存放的,通常目录下面会有readme.txt说明文件和*.rc配置文件,详细了解之前,先读一下这两个文件是个不错的选择

init进程是Linux用户空间的第一个进程,进程号固定为1,内核启动后,在用户控件启动init进程,并调用init进程的main方法,开始工作,履行其作为第一个用户控件进程的职责。主要包括以下几个内容:

解析配置文件

什么配置文件

这个配置文件就是init.rc,位于/system/core/rootdir/init.rc,这个文件的内容比较多,先节选部分来进行分析

1
2
3
4
5
import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /init.${ro.zygote}.rc
import /init.trace.rc

init进程要解析的配置文件有两个:

  • init.rc
  • init.%s.rc,%s表示的是机器的hardware名

为什么要解析配置文件

init的工作是大体上市按配置文件定义的流程步骤来完成的,解析完配置文件会得到一些列的Action,这些Action最终会交给action_for_each_trigger函数处理。Action的执行时间大致分为以下几个阶段:

  • early-init
  • init
  • early-boot
  • boot

如何解析配置文件

1
2
3
4
5
6
7
8
9
10
11
12
init.cpp->main
init_parser.cpp->init_parse_config_file("/init.rc")
init_parser.cpp->parse_config
init_parser.cpp->parse_new_section

//init.rc文件中有三个关键字对应为section,分别是service、on、import,所以
//parse_new_section中会根据关键字区分
init_parser.cpp->parse_service
->parse_line_service
init_parser.cpp->parse_action
->parse_line_action
init_parser.cpp->parse_import

解析service

init控制service

属性服务

小结