在Android系统的启动过程中,init进程通过解析init.rc文件启动zygote,其过程分析如下。
本文以Android 13代码为例。
1,init进程解析init.rc文件
在init.rc文件中
import /system/etc/init/hw/init.${ro.zygote}.rc //采用import来引入Zygote启动脚本,通过adb shell getprop | grep ro.zygot获取ro.zygote值
on late-init
trigger zygote-start
//在zygote-start事情被触发并且在property:ro.crypto.state不同值的情况下start zygoe
on zygote-start && property:ro.crypto.state=unencrypted //zygote-start事件被触发,并且系统属性ro.crypto.state的值为unencrypted
on zygote-start && property:ro.crypto.state=unsupported //设备不支持加密
on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file //设备启用了文件加密
exec_start update_verifier_nonencrypted
start statsd
start netd
start zygote
start zygote_secondary
在init.zygote64.rc文件中
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server //--zygote告诉app_process以zygote模式运行,--start-system-server则指示在zygote启动后,它将启动系统服务
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
socket usap_pool_primary stream 660 root system
onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart media.tuner
onrestart restart netd
onrestart restart wificond
task_profiles ProcessCapacityHigh
critical window=${zygote.critical_window.minute:-off} target=zygote-fatal
在解析完rc文件后,会向init的ActionManager添加内置动作和事件触发器,比如am.QueueEventTrigger("early-init")和am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers")等。上面的代码执行start zygote命令,会走到/system/core/init/builtins.cpp文件中,根据映射表执行do_start函数。
在builtins.cpp文件中
static const Map builtin_functions = {
{"start", {1, 1, {false, do_start}}}
}
static Result<Success> do_start(const BuiltinArguments& args) {
Service* svc = ServiceList::GetInstance().FindService(args[1]); //根据解析到的参数,从解析的服务列表中查询对应的服务。
if (!svc) return Error() << "service " << args[1] << " not found";
if (auto result = svc->Start(); !result) { //调用查询到的服务的 start函数启动对应的服务
return Error() << "Could not start service: " << result.error();
}
return Success();
}
do_start函数直接从保存的服务列表中,根据服务名称查询对应的服务,然后调用/system/core/init/service.cpp中的Start函数启动服务。
在service.cpp文件中
Result<Success> Service::Start() {
pid_t pid = -1;
if (namespaces_.flags) {
pid = clone(nullptr, nullptr, namespaces_.flags | SIGCHLD, nullptr);
} else {
pid = fork();
}
if (pid == 0) {
umask(077);
RunService(override_mount_namespace, descriptors, std::move(pipefd));
_exit(127);
}
}
void Service::RunService() {
if (!ExpandArgsAndExecv(args_, sigstop_)) {
PLOG(ERROR) << "cannot execv('" << args_[0]
<< "'). See the 'Debugging init' section of init's README.md for tips";
}
}
static bool ExpandArgsAndExecv(const std::vector<std::string>& args, bool sigstop) {
std::vector<char*> c_strings;
c_strings.push_back(const_cast<char*>(args[0].data()));
return execv(c_strings[0], c_strings.data()) == 0; //rong 执行c_string[0]对应的文件,比如启动zygote64
}
ExpandArgsAndExecv这个函数获取待执行文件的路径,然后调用execv执行待执行的具体文件,同时将参数传递过去。
从return execv(c_strings[0], c_strings.data()) == 0;起函数的流程就走到了/system/bin/app_process64这个可执行文件的main函数中,
app_process64这个可运行文件的源文件是frameworks/base/cmds/app_process/app_main.cpp
2,zygote的启动
c++代码 /frameworks/base/cmds/app_process/app_main.cpp
java代码 /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
在app_main.cpp文件中的main函数中
int main(int argc, char* const argv[]) {
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); //创建一个AppRuntime的实例runtime
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;
niceName = ZYGOTE_NICE_NAME; //zygote进程此时由app_process进程被改名为zygote进程,static const char ZYGOTE_NICE_NAME[] = "zygote";
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
}
}
if (zygote) { //zygote为true,表示正在启动的进程为zygote进程。
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);//执行AndroidRuntime::start函数
} else if (className) { //启动app
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
}
}
在AndroidRuntime.cpp文件中的main函数中
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) {
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) { //创建虚拟机
return;
}
onVmCreated(env);
if (startReg(env) < 0) { //注册android常用的jni
ALOGE("Unable to register all android natives\n");
return;
}
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);
}
//查找zygoteInit.main,将zygote带入java世界
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName); //查找ZygoteInit类
jmethodID startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V"); //获取main函数
env->CallStaticVoidMethod(startClass, startMeth, strArray); //调用ZygoteInit.java的main函数
free(slashClassName);
}
经过上面的代码就可以走到ZygoteInit.java类中的main函数。