Android是基于Linux系统的,而init进程是Linux系统的第一进程,因此,需要分析zygote的启动,首先就需要查看init进程的启动
/system/core/init/init.cpp文件
int main(int argc, char** argv) {
......
const BuiltinFunctionMap function_map;
Action::set_function_map(&function_map);
Parser& parser = Parser::GetInstance();
// Leo, 将ServiceParser/ActionParser/ImportParser加入到section_parsers_中,并且关键字分别设置为service/on/import
parser.AddSectionParser("service",std::make_unique());
parser.AddSectionParser("on", std::make_unique());
parser.AddSectionParser("import", std::make_unique());
// init_parser:; Parser::ParseConfig
// parse init.rc file
// Leo,解析init.rc配置文件
parser.ParseConfig("/init.rc");
......
while (true) {
if (!waiting_for_exec) {
am.ExecuteOneCommand();
// Leo, 启动所有的restart标志的进程
restart_processes();
}
......
}
return 0;
}
可以看到,在init进程的main函数中,主要做了以下的事
1. 解析init.rc文件
2. 启动所有restart标志的进程
下面,主要对这两点分别说明
1. 解析init.rc文件
首先,先查看parser的AddSectionParser方法
void Parser::AddSectionParser(const std::string& name,
std::unique_ptr parser) {
section_parsers_[name] = std::move(parser);
}
因此,此处定义了以service/on/import为关键字的Action,并且分别对应的是ServiceParser/ActionParser/ImportParser的解析器
查看init_parser.cpp文件中的ParseConfig方法
bool Parser::ParseConfig(const std::string& path) {
if (is_dir(path.c_str())) {
return ParseConfigDir(path);
}
return ParseConfigFile(path);
}
bool Parser::ParseConfigFile(const std::string& path) {
INFO("Parsing file %s...\n", path.c_str());
Timer t;
std::string data;
if (!read_file(path.c_str(), &data)) {
return false;
}
data.push_back('\n'); // TODO: fix parse_config.
// Leo, 解析init.rc文件
ParseData(path, data);
// Leo,解析文件结束后,调用section_parsers_的EndFile方法
for (const auto& sp : section_parsers_) {
sp.second->EndFile(path);
}
// 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();
NOTICE("(Parsing %s took %.2fs.)\n", path.c_str(), t.duration());
return true;
}
可以看到,此处先调用了ParseData方法,之前调用所有的section_parsers_的EndFile方法
void Parser::ParseData(const std::string& filename, const std::string& data) {
//TODO: Use a parser with const input and remove this copy
std::vector data_copy(data.begin(), data.end());
data_copy.push_back('\0');
parse_state state;
state.filename = filename.c_str();
state.line = 0;
state.ptr = &data_copy[0];
state.nexttoken = 0;
SectionParser* section_parser = nullptr;
std::vector args;
for (;;) {
switch (next_token(&state)) {
case T_EOF:
if (section_parser) {
section_parser->EndSection();
}
return;
case T_NEWLINE:
state.line++;
if (args.empty()) {
break;
}
// Leo,当Action为servoce/on/import的时候,走if分支
if (section_parsers_.count(args[0])) {
if (section_parser) {
section_parser->EndSection();
}
// Leo,设置section_parsers_的值
section_parser = section_parsers_[args[0]].get();
std::string ret_err;
if (!section_parser->ParseSection(args, &ret_err)) {
parse_error(&state, "%s\n", ret_err.c_str());
section_parser = nullptr;
}
// Leo, 当Action不是service/on/import的时候,走else分支
} else if (section_parser) {
std::string ret_err;
if (!section_parser->ParseLineSection(args, state.filename,
state.line, &ret_err)) {
parse_error(&state, "%s\n", ret_err.c_str());
}
}
args.clear();
break;
case T_TEXT:
args.emplace_back(state.text);
break;
}
}
}
因此,查看init.rc文件,启动zygote的代码为import /init.${ro.zygote}.rc,因此,需要调用的是ImportParser的ParseSection方法
import_parser.cpp文件
bool ImportParser::ParseSection(const std::vector& args,
std::string* err) {
if (args.size() != 2) {
*err = "single argument needed for import\n";
return false;
}
std::string conf_file;
// Leo,将args[1],即init.zygote32.rc文件(此处只分析zygote32的配置文件)内容写入到conf_file
bool ret = expand_props(args[1], &conf_file);
if (!ret) {
*err = "error while expanding import";
return false;
}
INFO("Added '%s' to import list\n", conf_file.c_str());
// Leo,将conf_file的数据,直接保存到import_中
imports_.emplace_back(std::move(conf_file));
return true;
}
可以看到,此处是将init.zygote32.rc文件中的数据写入到imports_中
接下来,我们看到init_parser.cpp文件中的ParseConfigFile中,是先调用的ParseData方法,后调用section_parser_的EndFile方法,因此,查看ImportParser中的EndFile方法
import_parser.cpp文件
void ImportParser::EndFile(const std::string& filename) {
auto current_imports = std::move(imports_);
imports_.clear();
for (const auto& s : current_imports) {
// Leo,重新调用ParseConfig来解析import_中的数据,即init.zygote32.rc中的数据
if (!Parser::GetInstance().ParseConfig(s)) {
ERROR("could not import file '%s' from '%s': %s\n",
s.c_str(), filename.c_str(), strerror(errno));
}
}
}
可以看到,此处又走到了Parser的ParseConfig方法,而此时,解析的数据为init.zygote32.rc文件中的数据,查看init.zygote32.rc文件中的内容
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
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
writepid /dev/cpuset/foreground/tasks
因此,首先解析第一行,action为service,此时关键字为service对应的为ServiceParser解析器,因此
service.cpp文件
bool ServiceParser::ParseSection(const std::vector& args,
std::string* err) {
// Leo, 参数小于3,service不合格,返回false
if (args.size() < 3) {
*err = "services must have a name and a program";
return false;
}
// Leo, name为args[1],第二个参数,即zygote
const std::string& name = args[1];
// Leo, 名称是否合法
if (!IsValidName(name)) {
*err = StringPrintf("invalid service name '%s'", name.c_str());
return false;
}
// Leo,设置args参数值
std::vector str_args(args.begin() + 2, args.end());
// Leo,创建service_对象
service_ = std::make_unique(name, "default", str_args);
return true;
}
此时,创建service_对象,看Service的构造函数
Service::Service(const std::string& name, const std::string& classname,
const std::vector& args)
: name_(name), classname_(classname), flags_(0), pid_(0), time_started_(0),
time_crashed_(0), nr_crashed_(0), uid_(0), gid_(0), seclabel_(""),
ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), args_(args) {
onrestart_.InitSingleTrigger("onrestart");
}
可以看到,此时将service_对象的name_参数默认设置为zygote,classname为android,args_为args参数,即后面四个参数,请注意此地关键字为onrestart
OK,init.zygote32.rc文件的第一行解析完成,接下来第二行
class main
由于关键字class,并不在service/on/import中,因此,走的是ParseConfigFile下面的else分支,因此调用的是ParseLineSection方法
service.cpp文件
bool ServiceParser::ParseLineSection(const std::vector& args,
const std::string& filename, int line,
std::string* err) const {
return service_ ? service_->HandleLine(args, err) : false;
}
service_刚刚我们已经创建,因此其并不为空,因此走的是service->HandleLine方法
bool Service::HandleLine(const std::vector& args, std::string* err) {
if (args.empty()) {
*err = "option needed, but not provided";
return false;
}
static const OptionHandlerMap handler_map;
// Leo,查找需要调用的function
auto handler = handler_map.FindFunction(args[0], args.size() - 1, err);
// Leo,确认是否包含此方法
if (!handler) {
return false;
}
// Leo,直接调用该方法
return (this->*handler)(args, err);
}
OptionHandlerMap是啥?
Service::OptionHandlerMap::Map& Service::OptionHandlerMap::map() const {
constexpr std::size_t kMax = std::numeric_limits::max();
static const Map option_handlers = {
{"class", {1, 1, &Service::HandleClass}},
{"console", {0, 0, &Service::HandleConsole}},
{"critical", {0, 0, &Service::HandleCritical}},
{"disabled", {0, 0, &Service::HandleDisabled}},
{"group", {1, NR_SVC_SUPP_GIDS + 1, &Service::HandleGroup}},
{"ioprio", {2, 2, &Service::HandleIoprio}},
{"keycodes", {1, kMax, &Service::HandleKeycodes}},
{"oneshot", {0, 0, &Service::HandleOneshot}},
{"onrestart", {1, kMax, &Service::HandleOnrestart}},
{"seclabel", {1, 1, &Service::HandleSeclabel}},
{"setenv", {2, 2, &Service::HandleSetenv}},
{"socket", {3, 6, &Service::HandleSocket}},
{"user", {1, 1, &Service::HandleUser}},
{"writepid", {1, kMax, &Service::HandleWritepid}},
};
return option_handlers;
}
通过OptionHandlerMap,class关键字对应的是Service的HandleClass方法,因此,此时,HandleLine方法实际上是调用的HandleClass方法
bool Service::HandleClass(const std::vector& args, std::string* err) {
classname_ = args[1];
return true;
}
OK,设置此service_的classname为args[1],即main
依次类推,其他的行,分别调用的是对应的方法,对service_数据进行完善,需要注意的是onrestart关键字对应的service_
那么,解析init.rc文件,就到此结束,我们得到了一个Service的对象,service_,name为zygote,classname为main
那么,此zygote是如何来启动的呢?
2.启动所有restart标志的进程
在init.cpp文件中,做了两件事,第一就是解析init.rc文件,另一个就是启动所有restart标志的进程,那么
static void restart_processes()
{
process_needs_restart = 0;
ServiceManager::GetInstance().
ForEachServiceWithFlags(SVC_RESTARTING, [] (Service* s) {
s->RestartIfNeeded(process_needs_restart);
});
}
调用了ServiceManager的ForEachServiceWithFlags方法,并且调用了Service对象s的RestrtIfNeeded方法
service.cpp文件
void ServiceManager::ForEachServiceWithFlags(unsigned matchflags,
void (*func)(Service* svc)) const {
// Leo,启动所有的services_
for (const auto& s : services_) {
if (s->flags() & matchflags) {
func(s.get());
}
}
}
刚刚在第一步中,创建了一个service_,它的flags为0,此时必定会启动,因此,会调用该service_的RestartIfNeeded
void Service::RestartIfNeeded(time_t& process_needs_restart) {
time_t next_start_time = time_started_ + 5;
if (next_start_time <= gettime()) {
flags_ &= (~SVC_RESTARTING);
// Leo, 调用service_的Start方法
Start();
return;
}
if ((next_start_time < process_needs_restart) ||
(process_needs_restart == 0)) {
process_needs_restart = next_start_time;
}
}
调用service_的Start方法
bool Service::Start() {
......
// Leo, 创建一个子进程
pid_t pid = fork();
if (pid == 0) {
umask(077);
for (const auto& ei : envvars_) {
add_environment(ei.name.c_str(), ei.value.c_str());
}
// Leo,创建socket连接
for (const auto& si : sockets_) {
int socket_type = ((si.type == "stream" ? SOCK_STREAM :
(si.type == "dgram" ? SOCK_DGRAM :
SOCK_SEQPACKET)));
const char* socketcon =
!si.socketcon.empty() ? si.socketcon.c_str() : scon.c_str();
int s = create_socket(si.name.c_str(), socket_type, si.perm,
si.uid, si.gid, socketcon);
if (s >= 0) {
PublishSocket(si.name, s);
}
}
......
// Leo,strs[0]为/system/bin/app_process,即启动/system/bin/app_process
if (execve(strs[0], (char**) &strs[0], (char**) ENV) < 0) {
ERROR("cannot execve('%s'): %s\n", strs[0], strerror(errno));
}
_exit(127);
}
if (pid < 0) {
ERROR("failed to start '%s'\n", name_.c_str());
pid_ = 0;
return false;
}
// Leo,记录启动时间
time_started_ = gettime();
// Leo,设置进程的pid
pid_ = pid;
// Leo, 修改service_的flags值
flags_ |= SVC_RUNNING;
if ((flags_ & SVC_EXEC) != 0) {
INFO("SVC_EXEC pid %d (uid %d gid %d+%zu context %s) started; waiting...\n",
pid_, uid_, gid_, supp_gids_.size(),
!seclabel_.empty() ? seclabel_.c_str() : "default");
}
NotifyStateChange("running");
return true;
}
在Start方法中启动service_的socket,为其设定uid,pid,设置状态等
自此,天字第一号进程zygote启动