init.rc是由一种被称为“Android初始化语言”(Android Init Language,这里简称为AIL)的脚本写成的文件,它位于/system/core/rootdir/init.rc,init.rc脚本是由Android中linux的第一个用户级进程init进行解析的。init.rc只是语法文件,并不是程序,真正的入口是system/core/init/init.cpp。
在/system/core/init/init.cpp中的main()函数中,
int main(int argc, char** argv) {
ActionManager& am = ActionManager::GetInstance();
ServiceList& sm = ServiceList::GetInstance();
LoadBootScripts(am, sm);
}
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
Parser parser = CreateParser(action_manager, service_list);
std::string bootscript = GetProperty("ro.boot.init_rc", "");
if (bootscript.empty()) {
parser.ParseConfig("/init.rc");
if (!parser.ParseConfig("/system/etc/init")) {
late_import_paths.emplace_back("/system/etc/init");
}
if (!parser.ParseConfig("/product/etc/init")) {
late_import_paths.emplace_back("/product/etc/init");
}
if (!parser.ParseConfig("/odm/etc/init")) {
late_import_paths.emplace_back("/odm/etc/init");
}
if (!parser.ParseConfig("/vendor/etc/init")) {
late_import_paths.emplace_back("/vendor/etc/init");
}
} else {
parser.ParseConfig(bootscript);
}
}
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
Parser parser;
parser.AddSectionParser("service", std::make_unique(&service_list, subcontexts));
parser.AddSectionParser("on", std::make_unique(&action_manager, subcontexts));
parser.AddSectionParser("import", std::make_unique(&parser));
return parser;
}
从上面的代码可以看出,在解析init.rc时,创建解析器时涉及到service,on,import等。在init.rc中,import是import其它的init.rc文件,init.rc中service都是native的service,此时还未到android启动的时候,首先能启动的是一些核心的native service,并且这里的service只是描述了service的构成,由on触发执行service。
(1) 在init.rc中,关于service有如下代码:
service ueventd /sbin/ueventd
class core
critical
seclabel u:r:ueventd:s0
shutdown critical
service console /system/bin/sh
class core
console
disabled
user shell
group shell log readproc
seclabel u:r:shell:s0
setenv HOSTNAME console
对上面的代码分析如下:
service ueventd /sbin/ueventd ##service ueventd /sbin/ueventd 声明了一个名为ueventd的服务,该服务对应的可执行文件位于/sbin/ueventd。ueventd是用户空间的事件守护进程,负责处理内核发送的uevent(用户空间事件),如设备添加、删除等。
class core #class core 表示这个服务是核心服务,对于系统的正常启动和运行至关重要。
critical #critical 标记该服务为关键服务,如果它启动失败,系统可能会进入安全模式或无法正常工作
seclabel u:r:ueventd:s0 #seclabel u:r:ueventd:s0 指定了该服务的SELinux安全上下文标签。SELinux是一种安全模块,用于增强操作系统的安全性。这里的标签u:r:ueventd:s0表示该服务以ueventd的SELinux类型运行,并属于s0(通常是系统默认的SELinux安全级别)。
service console /system/bin/sh
class core
console #console 标记这个服务与控制台(命令行界面)相关。
disabled #disabled 表示这个服务默认是禁用的,不会随着class一起启动。
user shell #user shell 指定了该服务以shell用户身份运行。shell用户通常具有访问系统资源的权限,但权限级别低于root用户。
group shell log readproc
seclabel u:r:shell:s0
setenv HOSTNAME console #设置环境变量HOSTNAME为console
(2) 在init.rc中,关于on的代码示例:
on early-init
start ueventd #这条命令启动了ueventd守护进程。ueventd是Android系统中负责处理内核事件(如设备添加、移除等)的守护进程。它会监听内核发送的uevent消息,并触发相应的操作,如创建或删除设备节点、设置权限等。
on late-init
trigger zygote-start ##触发zygote-start动作,这标志着zygote进程的启动。zygote是Android系统中用于孵化应用进程的守护进程,它的启动是系统能够运行应用的关键步骤。
on zygote-start && property:ro.crypto.state=unencrypted
# A/B update verifier that marks a successful boot.
exec_start update_verifier_nonencrypted ##使用exec_start命令启动update_verifier_nonencrypted服务。这是A/B分区更新验证器的一个变种,用于在未加密状态下标记成功的启动。
start netd ##启动netd服务,该服务负责网络管理,包括设置网络参数、路由等。
start zygote ##启动zygote服务,这是Android系统的核心服务之一,负责应用进程的创建和管理。
start zygote_secondary ##启动zygote_secondary服务,它是zygote的补充,用于在系统需要时分担启动新应用进程的任务。
on init
start servicemanager
(3) 在init.rc中,关于import的代码示例:
import /init.${ro.zygote}.rc
import /init.environ.rc #import 一个init配置文件,扩展当前配置。