前段时间在看Android9.0的PackageManagerService的源码,看着看着就在想PackageManagerService是如何被启动的,发现它是被SystemServer启动的,然后就又想SystemServer又是怎么被创建的呢,就一步步跟代码,发现SystemServer是从zygote进程fork出来的,想把最近了解的内容总结下,于是就有了这篇文章(如果再跟下去你会发现zygote又是从init进程fork出来的)
zygote 是什么
简单地说,它是一个进程。如果稍微再详细点的话,它是孵化其他Android应用进程的进程。
zygote进程如何被创建的
前面我们知道zygote进程能孵化其他Android进程,那么zygote进程又是由谁孵化的呢?我们知道Android是基于Linux内核,而Linux的第一个用户级进程为init进程(PID等于1),所以很容易联想到zygote进程很有可能就是init进程孵化出来的,实际上也确实如此。下面我们就看下zygote孵化的过程,过程主要包括:
- init 进程解析init.rc文件
- zygote孵化
init进程解析
system/core/init/init.cpp
system/core/init/init.h
system/core/init/action_manager.h
system/core/init/action_manager.cpp
system/core/init/service.h
system/core/init/service.cpp
system/core/init/parser.h
system/core/init/parser.cpp
下面就是init进程解析init.rc文件时与zygote相关的过程:
//system/core/init/init.cpp
int main(int argc, char** argv) {
//省略部分无关代码......
const BuiltinFunctionMap function_map;
Action::set_function_map(&function_map);
subcontexts = InitializeSubcontexts();
ActionManager& am = ActionManager::GetInstance();
ServiceList& sm = ServiceList::GetInstance();
//开始解析初始化脚本文件
LoadBootScripts(am, sm);
// Turning this on and letting the INFO logging be discarded adds 0.2s to
// Nexus 9 boot time, so it's disabled by default.
if (false) DumpState();
//省略部分无关代码......
return 0;
}
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
//创建不通的解析器,包括ActionParser、ImportParser和ServiceParser
Parser parser = CreateParser(action_manager, service_list);
//判断是否有配置ro.boot.init_rc属性
std::string bootscript = GetProperty("ro.boot.init_rc", "");
if (bootscript.empty()) {
//如果没有配置ro.boot.init_rc属性,则解析init.rc
parser.ParseConfig("/init.rc");
//后面的几个if语句判断对应的路径是否有配置文件,如果有则把路径加入容器
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);
}
}
我们看下init.rc文件内容,由于篇幅原因,还是省略了部分内容;
#system/core/rootdir/init.rc
import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /init.usb.configfs.rc
import /init.${ro.zygote}.rc
on early-init
# Set init and its forked children's oom_adj.
write /proc/1/oom_score_adj -1000
# Disable sysrq from keyboard
write /proc/sys/kernel/sysrq 0
# Set the security context of /adb_keys if present.
restorecon /adb_keys
# Set the security context of /postinstall if present.
restorecon /postinstall
# Mount cgroup mount point for cpu accounting
mount cgroup none /acct nodev noexec nosuid cpuacct
mkdir /acct/uid
# root memory control cgroup, used by lmkd
mkdir /dev/memcg 0700 root system
mount cgroup none /dev/memcg nodev noexec nosuid memory
# app mem cgroups, used by activity manager, lmkd and zygote
mkdir /dev/memcg/apps/ 0755 system system
# cgroup for system_server and surfaceflinger
mkdir /dev/memcg/system 0550 system system
start ueventd
.......
文件开头import了其他的rc文件,init.${ro.zygote}.rc就是zygote的有关的初始化脚本,ro.zygote属性可以通过getprop ro.zygote
查看机型对应的属性,比如下面就是32位的机型初始化脚本文件。
#system/core/rootdir/init.zygote32.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
service的格式如下:
service <name> <pathname> [ <argument> ]*
<option>
<option>
...
zygote进程的启动就是通过service命令“/system/bin/app_process -Xzygote /system/bin --zygote --start-system-server”。有关rc文件的更多内容可以参考system/core/init/README.md文件
在前面的时序图中,我们了解到解析过程会调用Parser::ParseData函数,在这个过程中就是根据不同类型采用对应的parser来解析
//system/core/init/parse.cpp
void Parser::ParseData(const std::string& filename, const std::string& data, size_t* parse_errors) {
// TODO: Use a parser with const input and remove this copy
std::vector<char> data_copy(data.begin(), data.end());
data_copy.push_back('\0');
parse_state state;
state.line = 0;
state.ptr = &data_copy[0];
state.nexttoken = 0;
SectionParser* section_parser = nullptr;
int section_start_line = -1;
std::vector<std::string> args;
auto end_section = [&] {
if (section_parser == nullptr) return;
if (auto result = section_parser->EndSection(); !result) {
(*parse_errors)++;
LOG(ERROR) << filename << ": " << section_start_line << ": " << result.error();
}
section_parser = nullptr;
section_start_line = -1;
};
for (;;) {
switch (next_token(&state)) {
case T_EOF:
end_section();
return;
case T_NEWLINE:
state.line++;
if (args.empty()) break;
// If we have a line matching a prefix we recognize, call its callback and unset any
// current section parsers. This is meant for /sys/ and /dev/ line entries for
// uevent.
for (const auto& [prefix, callback] : line_callbacks_) {
if (android::base::StartsWith(args[0], prefix)) {
end_section();
if (auto result = callback(std::move(args)); !result) {
(*parse_errors)++;
LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
}
break;
}
}
//section_parsers_是个map集合,数据初始化在init.cpp的CreateParser()函数中
if (section_parsers_.count(args[0])) {
end_section();
section_parser = section_parsers_[args[0]].get();
section_start_line = state.line;
if (auto result =
section_parser->ParseSection(std::move(args), filename, state.line);
!result) {
(*parse_errors)++;
LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
section_parser = nullptr;
}
} else if (section_parser) {
if (auto result = section_parser->ParseLineSection(std::move(args), state.line);
!result) {
(*parse_errors)++;
LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
}
}
args.clear();
break;
case T_TEXT:
args.emplace_back(state.text);
break;
}
}
}
//system/core/init/service.cpp
Result<Success> ServiceParser::ParseLineSection(std::vector<std::string>&& args, int line) {
return service_ ? service_->ParseLine(std::move(args)) : Success();
}
Result<Success> Service::ParseLine(const std::vector<std::string>& args) {
static const OptionParserMap parser_map;
auto parser = parser_map.FindFunction(args);
if (!parser) return parser.error();
//执行真正的命令,比如zygote.rc的“/system/bin/app_process -Xzygote /system/bin --zygote --start-system-server”
return std::invoke(*parser, this, args);
}
最后附上解析器相关的类关系图
zygote启动
在了解init.rc解析后,我们再看下zygote进程对应的app_main.cpp文件的main函数执行过程