init.zygote64.rc 有如下代码:
service zygote /system/bin/app_process64 -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 media
onrestart restart netd
app_process启动zygote , zygote启动system-server 。
int main(int argc, char* const argv[])
{
while (i < argc) {
const char* arg = argv[i++];
if (!parentDir) {
parentDir = arg;
} else if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = "zygote";
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName = arg + 12;
} else {
className = arg;
break;
}
}
if (niceName && *niceName) {
setArgv0(argv0, niceName);
set_process_name(niceName);
}
runtime.mParentDir = parentDir;
if (zygote) {
symlink_preload_apps(); //链接预置可卸载运用到data/app,这些应用恢复出厂设置可恢复
runtime.start("com.android.internal.os.ZygoteInit",
runtime.start("com.android.internal.os.ZygoteInit", args); //启动zygote
} else if (className) {
// Remainder of args get passed to startup class main()
runtime.mClassName = className;
runtime.mArgC = argc - i;
runtime.mArgV = argv + i;
runtime.start("com.android.internal.os.RuntimeInit",
application ? "application" : "tool");
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
return 10;
}
}
symlink_preload_apps实现如下:
void symlink_preload_apps() {
char linked[128] ={0};
property_get(PRELOAD_LINKED_PROPERTY, linked, "0");
if (atoi(linked) && access(PRELOAD_NEED_RESET_MARK, F_OK)!=0 ){
return;
}
for (size_t i = 0; i < sizeof(PRELOAD_DIRS)/sizeof(PRELOAD_DIRS[0]); i++) {
//const nsecs_t now = systemTime();
const char *dir = PRELOAD_DIRS[i];
DIR *preload = opendir(dir);
if (NULL == preload) {
ALOGE("fail to open %s", dir);
continue;
}
struct dirent *entry = NULL;
while (NULL != (entry = readdir(preload))) {
ALOGI("get entry: %s", entry->d_name);
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
symlink_app(dir, entry);
}
closedir(preload);
}
if( -1 == remove(PRELOAD_NEED_RESET_MARK) ){
ALOGE("fail to remove %s (%s)", PRELOAD_NEED_RESET_MARK,strerror(errno));
}
property_set(PRELOAD_LINKED_PROPERTY, "1");
}
void symlink_app(const char* dir, dirent *entry) {
if (NULL == entry) {
return;
}
char from[128] = {0};
char to[128] = {0};
sprintf(from, "%s/%s", dir , entry->d_name);
sprintf(to, "%s/%s", DATA_APP_DIR, entry->d_name);
if (access(to, F_OK) == 0) {
ALOGI("%s already exist", to);
return ;
}
if (symlink(from, to) != 0) {
ALOGE("link %s:%s error", from, to);
return ;
}
ALOGI("link %s:%s finished", from, to);
}