备注:以下代码均是基于Android8.0分析的,大部分都是精简过的代码,便于理解
先上个流程图和时序图
流程图如下
zygote进程启动过程.png
时序图如下
zygote启动时序图.png
一. init进程以及init.rc解析
init进程是Android的的第一个进程,进程id是1,启动时执行入口main函数,解析init.rc文件,并执行相关的指令
1. init.rc语法和规则
init.rc:是由一种被称为“Android初始化语言”(Android Init Language,这里简称为AIL)的脚本写成的文件,它有自己语法和解析规则init.rc解析
下面看下init.rc的内容,为了方便阅读,给出一个精简版的关键内容
## Copyright (C) 2012 The Android Open Source Project
##
## IMPORTANT: Do not create world writable files or directories.
## This is a common source of Android security bugs.
##
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
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main //option
priority -20 //option
user root //option
group root readproc
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、
on early-init //监听事件
*************
on init //监听事件
*************
on property:sys.boot_from_charger_mode=1 //监听事件
class_stop charger
trigger late-init
## Mount filesystems and start core system services.
on late-init //监听事件
## Now we can start zygote for devices with file based encryption
trigger zygote-start //command
on zygote-start && property:ro.crypto.state=unsupported
## A/B update verifier that marks a successful boot.
exec_start update_verifier_nonencrypted //command
start netd //command
start zygote //command
start zygote_secondary //command
说明
service关键字表示创建一个服务,
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
表示创建一个名为zygote的服务,其实就是进程,执行文件是/system/bin/app_process64,后面的就是执行时携带参数,这个后续再解析中再讲,注意这只是创建服务,但是还没启动
on是表示监听某些事件,当事件发生触发时,执行下面的指令
比如
on late-init
## Now we can start zygote for devices with file based encryption
trigger zygote-start
表示late-init触发时,触发zygote-start事件
trigger:顾名思义,表示触发某个事件
这样的话
其实大概可以理清zygote在init.rc的启动过程
late-init->zygote-start->start zygote
其中late-init可能是property:sys.boot_from_charger_mode=1触发的,也可能是其他地方触发的,下面的讲解会提到
2. init.rc的解析
下面再看看具体是怎么解析和执行init.rc
精简的关键代码如下
代码路径:system/core/init/init.cpp
int main(int argc, char** argv) {
//省略代码
Parser& parser = Parser::GetInstance();
parser.AddSectionParser("service",std::make_unique<ServiceParser>());
parser.AddSectionParser("on", std::make_unique<ActionParser>());
parser.AddSectionParser("import", std::make_unique<ImportParser>());
//省略代码
parser.ParseConfig("/init.rc");
ActionManager& am = ActionManager::GetInstance();
am.QueueEventTrigger("early-init");
//省略代码
// Trigger all the boot actions to get us started.
am.QueueEventTrigger("init");
//省略代码
// Don't mount filesystems or start core system services in charger mode.
std::string bootmode = GetProperty("ro.bootmode", "");
if (bootmode == "charger") {
am.QueueEventTrigger("charger");
} else {
am.QueueEventTrigger("late-init");
}
// Run all property triggers based on current state of the properties.
am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");
while (true) {
// By default, sleep until something happens.
int epoll_timeout_ms = -1;
if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
am.ExecuteOneCommand();
}
//省略代码
}
return 0;
}
从代码上看,主要分为两部分
2.1 解析
可以看出有三个解析器分别是seriver,on和import,分为解析相关的关键字,这个跟init.rc的结构大体一致
将事件放到队列中,然后按顺序执行,这里面都是执行的初始化相关的事件,包括上面说的late-init这样的话,它就按照init.rc的规则,链式触发相关事件或者执行相关动作
再来看一看parse部分,这里主要看service的parser
先看parse解析器
代码路径:system/core/init/init_parser.cpp
void Parser::ParseData(const std::string& filename, const std::string& data) {
//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.filename = filename.c_str();
state.line = 0;
state.ptr = &data_copy[0];
state.nexttoken = 0;
SectionParser* section_parser = nullptr;
std::vector<std::string> 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;
}
if (section_parsers_.count(args[0])) {
if (section_parser)
//遇到下一个关键字,即该关键字对应的分段解析结束
section_parser->EndSection();
}
//获取对应关键字的解析器。比如service/on/import
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;
}
} else if (section_parser) {
std::string ret_err;
//解析关键字下面的内容,也就是init.rc中的option和Commands内容
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里面的内容,遇到关键字是就转给关键字相关的解析器解析
再来看下service的解析器
代码路径:system/core/init/service.cpp
//解析service中option的解析规则,精简代码
Service::OptionParserMap::Map& Service::OptionParserMap::map() const {
constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
// clang-format off
static const Map option_parsers = {
{"capabilities",
{1, kMax, &Service::ParseCapabilities}},
{"class", {1, kMax, &Service::ParseClass}},
{"oneshot", {0, 0, &Service::ParseOneshot}},
{"onrestart", {1, kMax, &Service::ParseOnrestart}},
};
// clang-format on
return option_parsers;
}
//解析service开头部分,主要是创建个Service
bool ServiceParser::ParseSection(const std::vector<std::string>& args,
std::string* err) {
if (args.size() < 3) {
*err = "services must have a name and a program";
return false;
}
const std::string& name = args[1];
if (!IsValidName(name)) {
*err = StringPrintf("invalid service name '%s'", name.c_str());
return false;
}
std::vector<std::string> str_args(args.begin() + 2, args.end());
//init.rc的service语法
//service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
//构造一个service,构造参数
//name:zygote
//str_args:/system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
service_ = std::make_unique<Service>(name, str_args);
return true;
}
//解析option或者comond的内容
/**栗子
class main
onrestart write /sys/power/state on
writepid /dev/cpuset/foreground/tasks
**/
bool ServiceParser::ParseLineSection(const std::vector<std::string>& args,
const std::string& filename, int line,
std::string* err) const {
return service_ ? service_->ParseLine(args, err) : false;
}
//解析onrestart,就是把option内容分为放在service中对应的数据中,其他的option就不一一列举了
bool Service::ParseOnrestart(const std::vector<std::string>& args, std::string* err) {
std::vector<std::string> str_args(args.begin() + 1, args.end());
onrestart_.AddCommand(str_args, "", 0, err);
return true;
}
//service关键字解析结束,将service加到vector容器中
void ServiceParser::EndSection() {
if (service_) {
ServiceManager::GetInstance().AddService(std::move(service_));
}
}
至此service的部分解析结束
2.2 触发事件
am.QueueEventTrigger("early-init");
am.QueueEventTrigger("init");
am.QueueEventTrigger("late-init");
am.ExecuteOneCommand();
二. zygote服务(进程)的启动
1. 相关数据结构
从第一章节的2.2小节可以看到,解析完成之后触发一些事件,对于zygote而言,init.rc里面有如下指令
on late-init
## Now we can start zygote for devices with file based encryption
trigger zygote-start
on zygote-start && property:ro.crypto.state=unsupported
start zygote
start zygote_secondary
也就是说late-init事件发生时,会再触发一个zygote-start事件,继续触发start zygote指令
先看下相关的数据结构,精简代码
代码路径:system/core/init/action.cpp
class Action
class Action {
private:
std::string event_trigger_;
std::vector<Command> commands_;
static const KeywordMap<BuiltinFunction>* function_map_;
};
class Command {
private:
BuiltinFunction func_;
std::vector<std::string> args_;
std::string filename_;
int line_;
};
class action中
event_trigger_:该action监听的触发器
Command:触发器触发后要做的指令
function_map_:维护一个指令与具体调用方法的映射关系
class Command中
func_:具体的方法指针,通过解析on关键字,将指令取出(比如start指令),然后通过function_map_拿到具体的方法指针
args_:数据
如下是具体指令与具体调用方法的映射关系的精简代码,我们只需关注start指令就行
代码路径:system/core/init/builtins.cpp
BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
// clang-format off
static const Map builtin_functions = {
{"bootchart", {1, 1, do_bootchart}},
{"chmod", {2, 2, do_chmod}},
{"chown", {2, 3, do_chown}},
{"class_reset", {1, 1, do_class_reset}},
{"class_restart", {1, 1, do_class_restart}},
{"class_start", {1, 1, do_class_start}},
{"class_stop", {1, 1, do_class_stop}},
{"start", {1, 1, do_start}},
};
// clang-format on
return builtin_functions;
}
2. init进程触发事件过程
代码路径:system/core/init/action.cpp
精简代码
void ActionManager::ExecuteOneCommand() {
// Loop through the trigger queue until we have an action to execute
//遍历trigger队列与action中的监听trigger对比
while (current_executing_actions_.empty() && !trigger_queue_.empty()) {
for (const auto& action : actions_) {
if (trigger_queue_.front()->CheckTriggers(*action)) {
current_executing_actions_.emplace(action.get());
}
}
trigger_queue_.pop();
}
//命中的话,执行相关指令
action->ExecuteOneCommand(current_command_);
}
void Action::ExecuteOneCommand(std::size_t command) const {
// We need a copy here since some Command execution may result in
// changing commands_ vector by importing .rc files through parser
Command cmd = commands_[command];
ExecuteCommand(cmd);
}
void Action::ExecuteCommand(const Command& command) const {
Timer t;
int result = command.InvokeFunc();
}
//执行指令对应的函数
int Command::InvokeFunc() const {
expanded_args[0] = args_[0];
return func_(expanded_args);
}
3.开始启动zygote 服务
3.1 do_start()
上面func_(expanded_args)其实就是执行do_start
代码路径:system/core/init/builtins.cpp
static int do_start(const std::vector<std::string>& args) {
//args是init.rc对应的start zygote指令
//args[1]就是zygote了,根据上面2.1章节解析service时会把结果放在vector容器中,而且service里面有name的成员变量
//由此还可以根据name拿到对应的service
Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
if (!svc) {
LOG(ERROR) << "do_start: Service " << args[1] << " not found";
return -1;
}
//调用service的start方法
if (!svc->Start())
return -1;
return 0;
}
3.2 Start()
代码路径:system/core/init/service.cpp
bool Service::Start() {
pid_t pid = -1;
if (namespace_flags_) {
pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);
} else {
//熟悉的fork代码
pid = fork();
}
if (pid == 0) {
std::vector<char*> strs;
ExpandArgs(args_, &strs);
//strs[0]就是/system/bin/app_process64
//将fork出来的子进程也就是zygote进程变身到一个新的进程,pid和进程名保持不变,其他的数据被新的进程覆盖
if (execve(strs[0], (char**) &strs[0], (char**) ENV) < 0) {
PLOG(ERROR) << "cannot execve('" << strs[0] << "')";
}
_exit(127);
}
if (pid < 0) {
PLOG(ERROR) << "failed to fork for '" << name_ << "'";
pid_ = 0;
return false;
}
return true;
}
说明:
1./system/bin/app_process6是有app_main.cpp编译的可执行文件
2.execve() 调用 成功 后 不会 返回, 其 进程 的 正文(text), 数据(data), bss 和 堆栈(stack) 段
被 调入程序 覆盖. 调入程序 继承了 调用程序 的 PID 和 所有 打开的 文件描述符, 他们 不会
因为 exec 过程 而 关闭. 父进程 的 未决 信号 被 清除. 所有 被 调用进程 设置过 的 信号
重置为 缺省行为
也就是说execve如果调用成功,其后面的代码不会被执行
3.3 app_main的main()
代码路径:frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
//AppRuntime是继承AndroidRuntime的,这里创建一个runtime,下文会提及到 //todo_1
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
// Parse runtime arguments. Stop at first unrecognized option.
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;
++i; // Skip unused "parent dir" argument.
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
//zygote的进程名zygote64
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
//启动system_server进程,也就是说zygote启动后就去fork出system_server进程
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}
if (!niceName.isEmpty()) {
//设置zygote的进程名
runtime.setArgv0(niceName.string(), true /* setProcName */);
}
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}
3.4 AndroidRuntime.start()
代码路径:frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
//启动虚拟机
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
onVmCreated(env);
/*
* Register android functions.注册native方法
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
/*
* We want to call main() with a String array with arguments in it.
* At present we have two arguments, the class name and an option string.
* Create an array to hold them.
*/
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);
for (size_t i = 0; i < options.size(); ++i) {
jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
assert(optionsStr != NULL);
env->SetObjectArrayElement(strArray, i + 1, optionsStr);
}
/*
* Start VM. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
//调用ZygoteInit的入口函数main
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
free(slashClassName);
ALOGD("Shutting down VM\n");
if (mJavaVM->DetachCurrentThread() != JNI_OK)
ALOGW("Warning: unable to detach main thread\n");
if (mJavaVM->DestroyJavaVM() != 0)
ALOGW("Warning: VM did not shut down cleanly\n");
}
说明:AndroidRuntime.start()主要做了三件事
1.注册framework层的native方法以便jni调用,比如com_android_internal_os_ZygoteInit_nativeZygoteInit
2.启动虚拟机
3.调用ZygoteInit.java 的main函数,这个main一直会执行或者阻塞,不会退出,这样的话VM也不会退出
3.5 ZygoteInit.main()
代码路径ZygoteInit.java
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
//标识启动system_server进程
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
//注册一个socket server
zygoteServer.registerServerSocket(socketName);
// In some configurations, we avoid preloading resources and classes eagerly.
// In such cases, we will preload things prior to our first fork.
preload(bootTimingsTraceLog);
// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot();
// Do an initial gc to clean up after startup
bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
gcAndFinalize();
bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
if (startSystemServer) {
//启动system_server进程
startSystemServer(abiList, socketName, zygoteServer);
}
Log.i(TAG, "Accepting command socket connections");
//开始在while循环中监听来自AMS的fork子进程的请求,避免main退出
zygoteServer.runSelectLoop(abiList);
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
说明:main主要做了三件事
1.preload 预加载
预加载framework中的类(/system/etc/
preloaded-classes)
预加载framework中的资源/system/framework/framework-res.apk
预加载动态库libandroid.so,libjnigraphics.so等等
预加载动态库libandroid.so,libjnigraphics.so等等
预加载默认字体
2.启动system_server进程
3.注册socket server并在循环中监听来自system_server的fork子进程的请求,
三 system_server进程的启动
1.1 startSystemServer
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller, RuntimeException {
String args[] = {
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
//fork成功,处理system_server
handleSystemServerProcess(parsedArgs);
}
return true;
}
/**
* Finish remaining work for the newly forked system server process.
*/
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws Zygote.MethodAndArgsCaller {
if (parsedArgs.niceName != null) {
//设置进程名
Process.setArgV0(parsedArgs.niceName);
}
/*
* Pass the remaining arguments to SystemServer.
*/
//这里是被zygote进程fork出来的子进程做的一些初始化工作(主要是System_server进程和普通的app进程)
ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
/* should never reach here */
}
1.2 ZygoteInit.zygoteInit
代码路径:ZygoteInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
//通过jni调用native的方法,在5.4 AndroidRuntime.start()中提过的,注册了jni相关函数以便java端的调用,这里正好用到了
ZygoteInit.nativeZygoteInit();
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
说明:zygoteInit主要做了三件事
1.RuntimeInit.commonInit() 设置UncaughtExceptionhandler和UA,具体代码比较简单这里不列举了
2.ZygoteInit.nativeZygoteInit() 调用native端的ZygoteInit(),这稍后再说
3.RuntimeInit.applicationInit 根据argv找到启动类,并执行入口main函数,具体代码比较简单这里不列举了(其实就是反射调用啦)
1.3 ZygoteInit.nativeZygoteInit()
代码路径frameworks/base/core/jni/AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
这个gCurRuntime实际就是5.3 app_main.cpp main中创建的appruntime ,可以查看todo_1标签与之呼应
1.4 onZygoteInit()
代码路径frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
说明:ProcessState是进程的状态,在构造函数时,会打开binder驱动做内存映射,startThreadPool会启动一个binder主线程,这样system_server具备binder的能力也就是跨进程通信的能力,app进程也是这样的,在创建成功后也会构造一个ProcessState,
另外我们可以看到zygote进程在启动的过程中并没有去创建ProcessState,所以zygote并没有binder的能力,所以zygote与system_server通信时用的是socket,至于zygote为什么不用binder
待下回分解。
至此所有的流程分析完毕。
网友评论