一、init 进程
init 进程,是 Andorid 系统中用户空间的第一个进程(pid=1),它是用户进程的鼻祖,负责孵化各种属性服务、守护进程、以及 Zygote 进程等。
Init 进程是由多个源文件共同组成的,这些源文件位于源码目录:system/core/init 。
1、init 进程分析
当内核完成系统设置,它首先在系统文件中寻找 “init” 文件,最后会调用 /system/core/init/init.cpp 的 mian() 方法(它是 init 的入口函数)。
主要完成如下两件事情:
(1)初始化和启动属性服务:property_init(); // 初始化属性相关资源
Andorid 提供的属性服务,类似于 Windows 平台上注册表管理器的机制,内容采用键值对的形式来记录用户、软件的一些使用信息。即使系统或软件重启,它还是能够根据之前在注册表中的记录,进行相应的初始化工作。应用程序可以通过这个属性机制,查询或设置相应的属性。我们可以使用 adb shell getprop
命令,来查看当前系统中都有哪些属性。
(2)解析 init.rc 配置文件,并启动 Zygote 进程:parser.ParseConfig("/init.rc"); // 解析 init.rc 配置文件
init.rc 配置文件,其内部由 Android 初始化语言(AIL:Android Init Language)编写的脚本。
[说明]:
AIL 主要包含四种类型的语言:Action、Commands、Services、Options,如下:
<1> Action(动作):通过 trigger(即:以 on 开头的语句),决定何时执行相应的 service。
// 例如:
on early-init:在初始化早期阶段触发;
on init:在初始化阶段触发;
on late-init:在初始化晚期阶段触发;
on boot/charger:在系统启动/充电时触发;
on property:<key>=<value>:当属性值满足条件时触发。
( 启动顺序:on early-init —> init —> late-init —> boot )
<2> Service(服务):是一个程序,它在初始化时启动,并在退出时重启,由 init 进程启动,一般运行于另外一个 init 的子进程,所以启动 service 前需要判断对应的可执行文件是否存在。init 生成的子进程,定义在 .rc 文件中,其中每一个 service,在启动时,会通过 frok 方式生成子进程。
// 例如:
service servicemanager(服务名) /system/bin/servicemanager(路径名)
<3> Command(命令):要执行的命令
// 常用的命令
class_start <service_class_name>:启动属于同一个class的所有服务;
start <service_name>:启动指定的服务,若已启动则跳过;
stop <service_name>:停止正在运行的服务;
setprop <name><value>:设置属性值;
mkdir <path>:创建指定目录;
symlink <target><sym_link>:创建连接到<target>的<sym_link>符号链接;
write <path> <string>:向文件<path>中写入字符串<string>;
exec:fork并执行,会阻塞init进程直到程序完毕;
exprot <name><name>:设定环境变量;
loglevel <level>:设置log级别。
<4> Option(选项):Options 是 Services 的可选项,与 service 配合使用
// 常用的选项
disabled:不随class自动启动,只有根据service名才启动;
oneshot:service退出后不再重启;
user/group:设置执行服务的用户/用户组,默认都是root;
class:设置所属的类名,当所属类启动/退出时,服务也启动/停止,默认为default
(default意味着:disabled=false,oneshot=false,critical=false);
onrestart:当服务重启时,执行相应的命令;
socket:创建名为 /dev/socket/<name> 的socket;
critical:在规定时间内,该service不断重启,则系统会重启并进入恢复模式。
上面 main() 函数中 parser 即:init_parse.cpp,通过它对 init.rc 配置文件进行解析(注:在 Android 中,对 init.rc 文件进行了拆分,每个服务对应一个 .rc 文件),其中 Zygote 服务启动的脚本在 system/core/rootdir/init.zygoteXX.rc 文件中进行定义,例如:64位处理器对应的 init.zygote64.rc 代码如下:
通过 init_parse.cpp 完成整个 service 的解析工作,该过程主要就是创建一个名为 “zygote” 的 service 结构体、一个 socketinfo 结构体(用于 socket 通信)、以及包含5个 onrestart 的 action 结构体。