第一个启动的程序–init
不管Java还是C++运行一个程序都是以main方法作为入口。所以我们先看看init.cpp的main函数.
目录:/system/core/init/main.cpp
具体代码:
int main(int argc, char** argv) {
#if __has_feature(address_sanitizer)
__asan_set_error_report_callback(AsanReportCallback);
#endif
if (!strcmp(basename(argv[0]), "ueventd")) {
return ueventd_main(argc, argv);
}
if (argc > 1) {
if (!strcmp(argv[1], "subcontext")) {
android::base::InitLogging(argv, &android::base::KernelLogger);
const BuiltinFunctionMap function_map;
return SubcontextMain(argc, argv, &function_map);
}
if (!strcmp(argv[1], "selinux_setup")) {
return SetupSelinux(argv);
}
if (!strcmp(argv[1], "second_stage")) {
return SecondStageMain(argc, argv);//
}
}
return FirstStageMain(argc, argv);//在这里创建和挂载了启动所需要的目录信息包含tmpfs、devpts、proc、sysfs、selinuxfs文件系统。。
}
在Main函数,分了几个阶段,首先第一步是FirstStageMain
,我们看看他做了什么?
目录:/system/core/init/first_stage_init.cpp
具体代码:
int FirstStageMain(int argc, char** argv) {
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}
boot_clock::time_point start_time = boot_clock::now();
std::vector<std::pair<std::string, int>> errors;
#define CHECKCALL(x) \
if ((x) != 0) errors.emplace_back(#x " failed", errno);
// Clear the umask.
umask(0);
CHECKCALL(clearenv());
CHECKCALL(setenv("PATH", _PATH_DEFPATH, 1));
// Get the basic filesystem setup we need put together in the initramdisk
// on / and then we'll let the rc file figure out the rest.
CHECKCALL(mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"));//挂载了tmpfs
CHECKCALL(mkdir("/dev/pts", 0755));//创建pts目录并且赋予0755的权限
CHECKCALL(mkdir("/dev/socket", 0755));//创建socket目录并且赋予0755的权限
CHECKCALL(mkdir("/dev/dm-user", 0755));//创建dm-user目录并且赋予0755的权限
CHECKCALL(mount("devpts", "/dev/pts", "devpts", 0, NULL));//挂载devpts
#define MAKE_STR(x) __STRING(x)
CHECKCALL(mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC)));//挂载proc文件系统
#undef MAKE_STR
// Don't expose the raw commandline to unprivileged processes.
CHECKCALL(chmod("/proc/cmdline", 0440));
std::string cmdline;
android::base::ReadFileToString("/proc/cmdline", &cmdline);
// Don't expose the raw bootconfig to unprivileged processes.
chmod("/proc/bootconfig", 0440);
std::string bootconfig;
android::base::ReadFileToString("/proc/bootconfig", &bootconfig);
gid_t groups[] = {AID_READPROC};
CHECKCALL(setgroups(arraysize(groups), groups));
CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL));//挂载sysfs
CHECKCALL(mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL));//挂载selinxfs
CHECKCALL(mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11)));
if constexpr (WORLD_WRITABLE_KMSG) {
CHECKCALL(mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11)));
}
CHECKCALL(mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8)));
CHECKCALL(mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9)));
CHECKCALL(mknod("/dev/ptmx", S_IFCHR | 0666, makedev(5, 2)));
CHECKCALL(mknod("/dev/null", S_IFCHR | 0666, makedev(1, 3)));
CHECKCALL(mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
"mode=0755,uid=0,gid=1000"));
CHECKCALL(mkdir("/mnt/vendor", 0755));
CHECKCALL(mkdir("/mnt/product", 0755));
CHECKCALL(mount("tmpfs", "/debug_ramdisk", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
"mode=0755,uid=0,gid=0"));
CHECKCALL(mount("tmpfs", kSecondStageRes, "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
"mode=0755,uid=0,gid=0"))
#undef CHECKCALL
SetStdioToDevNull(argv);
InitKernelLogging(argv);
const char* path = "/system/bin/init";
const char* args[] = {path, "selinux_setup", nullptr};
auto fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
close(fd);
execv(path, const_cast<char**>(args));
// execv() only returns if an error happened, in which case we
// panic and never fall through this conditional.
PLOG(FATAL) << "execv(\"" << path << "\") failed";
return 1;
}
原来init进程的第一个阶段主要是挂载了tmpfs、devpts、proc、sysfs和selinux 文件系统,也就是说android系统启动就挂载了,关闭就消失了。
其中文件系统:
1.tmpfs:虚拟文件系统,他把所有的文件都存在虚拟内存中。tmpfs速度很快,毕竟他是驻留在RAM中。但是由于驻留在RAM中,所以断电之后文件内容不会被保存。
2.devpts:管理远程虚拟终端文件设备,挂接点是/dev/pts。pty的主复合设备/dev/ptmx被打开,就会在/dev/pts下创建pty设备文件。
3.proc:非常重要的虚拟文件系统,,通过它我们可以获得系统信息,同时也能够在运行时修改特定的内核参数。
4.sysfs:和proc类似,把连接在系统上的设备和总线组织成一个分级的文件,使得它们可以在用户空间存取。
5.selinux:对系统中每一个对象都生成一个安全上下文,每个对象访问系统资源都需要进行上下文审查。
再挂在完成之后,又返回了init 启动了selinux_setup。
int SetupSelinux(char** argv) {
SetStdioToDevNull(argv);
InitKernelLogging(argv);
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}
boot_clock::time_point start_time = boot_clock::now();
MountMissingSystemPartitions();
SelinuxSetupKernelLogging();
LOG(INFO) << "Opening SELinux policy";
PrepareApexSepolicy();
// Read the policy before potentially killing snapuserd.
std::string policy;
ReadPolicy(&policy);
CleanupApexSepolicy();
auto snapuserd_helper = SnapuserdSelinuxHelper::CreateIfNeeded();
if (snapuserd_helper) {
snapuserd_helper->StartTransition();
}
LoadSelinuxPolicy(policy);
if (snapuserd_helper) {
// Before enforcing, finish the pending snapuserd transition.
snapuserd_helper->FinishTransition();
snapuserd_helper = nullptr;
}
if (selinux_android_restorecon("/dev/selinux/", SELINUX_ANDROID_RESTORECON_RECURSE) == -1) {
PLOG(FATAL) << "restorecon failed of /dev/selinux failed";
}
SelinuxSetEnforcement();
if (selinux_android_restorecon("/system/bin/init", 0) == -1) {
PLOG(FATAL) << "restorecon failed of /system/bin/init failed";
}
setenv(kEnvSelinuxStartedAt, std::to_string(start_time.time_since_epoch().count()).c_str(), 1);
const char* path = "/system/bin/init";
const char* args[] = {path, "second_stage", nullptr};
execv(path, const_cast<char**>(args));//执行second_stage
PLOG(FATAL) << "execv(\"" << path << "\") failed";
return 1;
}
selinux是安全权限相关,感兴趣的大家可以自行学习研究。 在执行完成之后回到init 执行了second_stage。
文件目录:system/core/init/init.cpp 在线地址:
int SecondStageMain(int argc, char** argv) {
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}
SetStdioToDevNull(argv);
InitKernelLogging(argv);
LOG(INFO) << "init second stage started!";
if (auto result = WriteFile("/proc/1/oom_score_adj", "-1000"); !result) {
LOG(ERROR) << "Unable to write -1000 to /proc/1/oom_score_adj: " << result.error();
}
GlobalSeccomp();
keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1);
close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
property_init();//初始化属性服务
process_kernel_dt();
process_kernel_cmdline();
export_kernel_boot_props();
property_set("ro.boottime.init", getenv("INIT_STARTED_AT"));
property_set("ro.boottime.init.selinux", getenv("INIT_SELINUX_TOOK"));
const char* avb_version = getenv("INIT_AVB_VERSION");
if (avb_version) property_set("ro.boot.avb_version", avb_version);
const char* force_debuggable_env = getenv("INIT_FORCE_DEBUGGABLE");
if (force_debuggable_env && AvbHandle::IsDeviceUnlocked()) {
load_debug_prop = "true"s == force_debuggable_env;
}
unsetenv("INIT_STARTED_AT");
unsetenv("INIT_SELINUX_TOOK");
unsetenv("INIT_AVB_VERSION");
unsetenv("INIT_FORCE_DEBUGGABLE");
SelinuxSetupKernelLogging();
SelabelInitialize();
SelinuxRestoreContext();
//创建Epoll
Epoll epoll;
if (auto result = epoll.Open(); !result) {
PLOG(FATAL) << result.error();
}
//创建Handler,监听子进程的信号,如果子进程异常退出,init会调用对应的处理函数来进行处理。
InstallSignalFdHandler(&epoll);
property_load_boot_defaults(load_debug_prop);
UmountDebugRamdisk();
fs_mgr_vendor_overlay_mount_all();
export_oem_lock_status();
//开启属性服务
StartPropertyService(&epoll);
MountHandler mount_handler(&epoll);
set_usb_controller();
const BuiltinFunctionMap function_map;
Action::set_function_map(&function_map);
if (!SetupMountNamespaces()) {
PLOG(FATAL) << "SetupMountNamespaces failed";
}
subcontexts = InitializeSubcontexts();
ActionManager& am = ActionManager::GetInstance();
ServiceList& sm = ServiceList::GetInstance();
//加载配置脚本文件 init.rc
LoadBootScripts(am, sm);
if (false) DumpState();
// Make the GSI status available before scripts start running.
if (android::gsi::IsGsiRunning()) {
property_set("ro.gsid.image_running", "1");
} else {
property_set("ro.gsid.image_running", "0");
}
am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups");
am.QueueEventTrigger("early-init");
// Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...
am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
// ... so that we can start queuing up actions that require stuff from /dev.
am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits");
am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");
Keychords keychords;
am.QueueBuiltinAction(
[&epoll, &keychords](const BuiltinArguments& args) -> Result<Success> {
for (const auto& svc : ServiceList::GetInstance()) {
keychords.Register(svc->keycodes());
}
keychords.Start(&epoll, HandleKeychord);
return Success();
},
"KeychordInit");
am.QueueBuiltinAction(console_init_action, "console_init");
// Trigger all the boot actions to get us started.
am.QueueEventTrigger("init");
// Starting the BoringSSL self test, for NIAP certification compliance.
am.QueueBuiltinAction(StartBoringSslSelfTest, "StartBoringSslSelfTest");
// Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
// wasn't ready immediately after wait_for_coldboot_done
am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
// Initialize binder before bringing up other system services
am.QueueBuiltinAction(InitBinder, "InitBinder");
// 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.
auto epoll_timeout = std::optional<std::chrono::milliseconds>{};
if (do_shutdown && !shutting_down) {
do_shutdown = false;
if (HandlePowerctlMessage(shutdown_command)) {
shutting_down = true;
}
}
if (!(waiting_for_prop || Service::is_exec_service_running())) {
am.ExecuteOneCommand();
}
if (!(waiting_for_prop || Service::is_exec_service_running())) {
if (!shutting_down) {
auto next_process_action_time = HandleProcessActions();
// If there's a process that needs restarting, wake up in time for that.
if (next_process_action_time) {
epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>(
*next_process_action_time - boot_clock::now());
if (*epoll_timeout < 0ms) epoll_timeout = 0ms;
}
}
// If there's more work to do, wake up again immediately.
if (am.HasMoreCommands()) epoll_timeout = 0ms;
}
if (auto result = epoll.Wait(epoll_timeout); !result) {
LOG(ERROR) << result.error();
}
}
return 0;
}
代码比较多,我们只需要看关键的几点 我都加了注释: 1.property_init。属性服务类似于Windows平台上的注册表管理器,主要记录一些用户、软件的使用信息。当系统启动、重启 都是根据之前的记录进行对应的初始化。
2.创建Handler,监听子进程的信号,如果子进程异常退出,init会调用对应的处理函数来进行处理。
3.创建Epoll。
4.开启属性服务。
5.解析init.rc配置文件。
顺便提一下,Epoll面试大家遇见的也比较多。后边我会解释Epoll。
下面我们分别看一下 这几个函数都做了什么。
1.属性服务的初始化 ——> property_init
void property_init() {
mkdir("/dev/__properties__", S_IRWXU | S_IXGRP | S_IXOTH);
CreateSerializedPropertyInfo();//创建了配置的info
if (__system_property_area_init()) {//初始化property的内存区域。
LOG(FATAL) << "Failed to initialize property area";
}
if (!property_info_area.LoadDefaultPath()) {
LOG(FATAL) << "Failed to load serialized property info file";
}
}
总结:创建了Property的info信息。并且初始化了property的内存区域。
2.开启属性服务 -->StartPropertyService
文件目录:/system/core/init/property_service.cpp
void StartPropertyService(Epoll* epoll) {
selinux_callback cb;
cb.func_audit = SelinuxAuditCallback;
//设置selinux的callback
selinux_set_callback(SELINUX_CB_AUDIT, cb);
property_set("ro.property_service.version", "2");
//创建属性的非阻塞式socket
property_set_fd = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
false, 0666, 0, 0, nullptr);
if (property_set_fd == -1) {
PLOG(FATAL) << "start_property_service socket creation failed";
}
//listen对property_set_fd进行监听,最多可以同时为8个链接提供服务。
listen(property_set_fd, 8);
//epoll 注册Handler,监听property_set_fd,当有更新的时候会调用handle_property_set_fd来进行处理。
if (auto result = epoll->RegisterHandler(property_set_fd, handle_property_set_fd); !result) {
PLOG(FATAL) << result.error();
}
}
//属性事件处理器
static void handle_property_set_fd() {
static constexpr uint32_t kDefaultSocketTimeout = 2000; /* ms */ //设置超时时长
int s = accept4(property_set_fd, nullptr, nullptr, SOCK_CLOEXEC);
if (s == -1) {
return;
}
ucred cr;
socklen_t cr_size = sizeof(cr);
if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cr_size) < 0) {
close(s);
PLOG(ERROR) << "sys_prop: unable to get SO_PEERCRED";
return;
}
SocketConnection socket(s, cr);
uint32_t timeout_ms = kDefaultSocketTimeout;
uint32_t cmd = 0;
if (!socket.RecvUint32(&cmd, &timeout_ms)) {//接收数据
PLOG(ERROR) << "sys_prop: error while reading command from the socket";
socket.SendUint32(PROP_ERROR_READ_CMD);
return;
}
switch (cmd) {
case PROP_MSG_SETPROP: {//设置属性事件
char prop_name[PROP_NAME_MAX];
char prop_value[PROP_VALUE_MAX];
//从socket中读取name 和 value
if (!socket.RecvChars(prop_name, PROP_NAME_MAX, &timeout_ms) ||
!socket.RecvChars(prop_value, PROP_VALUE_MAX, &timeout_ms)) {
PLOG(ERROR) << "sys_prop(PROP_MSG_SETPROP): error while reading name/value from the socket";
return;
}
prop_name[PROP_NAME_MAX-1] = 0;
prop_value[PROP_VALUE_MAX-1] = 0;
const auto& cr = socket.cred();
std::string error;
uint32_t result =
HandlePropertySet(prop_name, prop_value, socket.source_context(), cr, &error);//设置属性
if (result != PROP_SUCCESS) {
LOG(ERROR) << "Unable to set property '" << prop_name << "' to '" << prop_value
<< "' from uid:" << cr.uid << " gid:" << cr.gid << " pid:" << cr.pid << ": "
<< error;
}
break;
}
case PROP_MSG_SETPROP2: {//同上
std::string name;
std::string value;
if (!socket.RecvString(&name, &timeout_ms) ||
!socket.RecvString(&value, &timeout_ms)) {
PLOG(ERROR) << "sys_prop(PROP_MSG_SETPROP2): error while reading name/value from the socket";
socket.SendUint32(PROP_ERROR_READ_DATA);
return;
}
const auto& cr = socket.cred();
std::string error;
uint32_t result = HandlePropertySet(name, value, socket.source_context(), cr, &error);
if (result != PROP_SUCCESS) {
LOG(ERROR) << "Unable to set property '" << name << "' to '" << value
<< "' from uid:" << cr.uid << " gid:" << cr.gid << " pid:" << cr.pid << ": "
<< error;
}
socket.SendUint32(result);
break;
}
default:
LOG(ERROR) << "sys_prop: invalid command " << cmd;
socket.SendUint32(PROP_ERROR_INVALID_CMD);
break;
}
}
//设置属性
uint32_t HandlePropertySet(const std::string& name, const std::string& value,
const std::string& source_context, const ucred& cr, std::string* error) {
if (auto ret = CheckPermissions(name, value, source_context, cr, error); ret != PROP_SUCCESS) {
return ret;
}
if (StartsWith(name, "ctl.")) {//控制属性的处理
HandleControlMessage(name.c_str() + 4, value, cr.pid);
return PROP_SUCCESS;
}
// sys.powerctl is a special property that is used to make the device reboot. We want to log
// any process that sets this property to be able to accurately blame the cause of a shutdown.
if (name == "sys.powerctl") {//记录重启设备原因的属性
std::string cmdline_path = StringPrintf("proc/%d/cmdline", cr.pid);
std::string process_cmdline;
std::string process_log_string;
if (ReadFileToString(cmdline_path, &process_cmdline)) {
// Since cmdline is null deliminated, .c_str() conveniently gives us just the process
// path.
process_log_string = StringPrintf(" (%s)", process_cmdline.c_str());
}
LOG(INFO) << "Received sys.powerctl='" << value << "' from pid: " << cr.pid
<< process_log_string;
}
if (name == "selinux.restorecon_recursive") {
return PropertySetAsync(name, value, RestoreconRecursiveAsync, error);
}
//设置普通属性
return PropertySet(name, value, error);
}
我们只看普通属性,因为控制属性需要客户端的权限。
static uint32_t PropertySet(const std::string& name, const std::string& value, std::string* error) {
size_t valuelen = value.size();
if (!IsLegalPropertyName(name)) {
*error = "Illegal property name";
return PROP_ERROR_INVALID_NAME;
}
if (valuelen >= PROP_VALUE_MAX && !StartsWith(name, "ro.")) {
*error = "Property value too long";
return PROP_ERROR_INVALID_VALUE;
}
if (mbstowcs(nullptr, value.data(), 0) == static_cast<std::size_t>(-1)) {
*error = "Value is not a UTF8 encoded string";
return PROP_ERROR_INVALID_VALUE;
}
//从属性内存空间查找,属性存在就更新属性值,否则创建并且添加进去。
prop_info* pi = (prop_info*) __system_property_find(name.c_str());
if (pi != nullptr) {
// ro.* properties are actually "write-once".
if (StartsWith(name, "ro.")) {
*error = "Read-only property was already set";
return PROP_ERROR_READ_ONLY_PROPERTY;
}
__system_property_update(pi, value.c_str(), valuelen);
} else {
int rc = __system_property_add(name.c_str(), name.size(), value.c_str(), valuelen);
if (rc < 0) {
*error = "__system_property_add failed";
return PROP_ERROR_SET_FAILED;
}
}
if (persistent_properties_loaded && StartsWith(name, "persist.")) {
WritePersistentProperty(name, value);
}
property_changed(name, value);
return PROP_SUCCESS;
}
总结:创建Android的注册表,将一些用户、应用的信息存储下来 系统会根据这些属性进行初始化工作。创建了property的socket 并且将socket注册到Epoll中,在handle_property_set_fd中将属性添加到内存空间中去。
3.加载init.rc配置文件 --> LoadBootScripts
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
Parser parser = CreateParser(action_manager, service_list);//创建解析器
std::string bootscript = GetProperty("ro.boot.init_rc", "");//根据ro.boot.init_rc的属性值来获取需要执行的脚本
if (bootscript.empty()) {
parser.ParseConfig("/init.rc");
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("/product_services/etc/init")) {
late_import_paths.emplace_back("/product_services/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);
}
}
//1.根据action on 和import类型的不同创建不同的解析器
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
Parser parser;
parser.AddSectionParser("service", std::make_unique<ServiceParser>(
&service_list, GetSubcontext(), std::nullopt));
parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, GetSubcontext()));
parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
return parser;
}
/*2.读取init.rc文件 在init.rc中根据系统导入对应的zygote.rc 在init进程中创建Zygote进程,该进程的可执行文件在/system/bin/app_process 并且传入参数 -Xzygote /system/bin --zygote --start-system-server 指定classname=main */
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
socket usap_pool_primary 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
3.解析器根据文件的格式来执行对应的动作。
文件目录:system/core/init/service.cpp
在线地址:https://cs.android.com/android/platform/superproject/+/android10-release:system/core/init/service.cpp
//开始解析
Result<Success> ServiceParser::ParseSection(std::vector<std::string>&& args,
const std::string& filename, int line) {
if (args.size() < 3) {//判断可执行参数 我们传递的参数大于3个的 所以不会到这里来。
return Error() << "services must have a name and a program";
}
const std::string& name = args[1];
if (!IsValidName(name)) {//校验Name
return Error() << "invalid service name '" << name << "'";
}
filename_ = filename;
Subcontext* restart_action_subcontext = nullptr;
if (subcontexts_) {
for (auto& subcontext : *subcontexts_) {
if (StartsWith(filename, subcontext.path_prefix())) {
restart_action_subcontext = &subcontext;
break;
}
}
}
std::vector<std::string> str_args(args.begin() + 2, args.end());
if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_P__) {
if (str_args[0] == "/sbin/watchdogd") {
str_args[0] = "/system/bin/watchdogd";
}
}
//创建service对象
service_ = std::make_unique<Service>(name, restart_action_subcontext, str_args);
return Success();
}
//解析完成
Result<Success> ServiceParser::EndSection() {
if (service_) {//如果service存在就将原来的service删除 再添加新的
Service* old_service = service_list_->FindService(service_->name());
if (old_service) {
if (!service_->is_override()) {
return Error() << "ignored duplicate definition of service '" << service_->name()
<< "'";
}
if (StartsWith(filename_, "/apex/") && !old_service->is_updatable()) {
return Error() << "cannot update a non-updatable service '" << service_->name()
<< "' with a config in APEX";
}
service_list_->RemoveService(*old_service);
old_service = nullptr;
}
//调用service_list->addService函数进行添加
service_list_->AddService(std::move(service_));
}
return Success();
}
解析完成后需要启动 在init.rc中我们找到对应的启动 之前说到的class = main 而class_start是一个command
on nonencrypted
class_start main
class_start late_start
文件目录: /android/system/core/init
static Result<Success> do_class_start(const BuiltinArguments& args) {
// Do not start a class if it has a property persist.dont_start_class.CLASS set to 1.
if (android::base::GetBoolProperty("persist.init.dont_start_class." + args[1], false))
return Success();
// Starting a class does not start services which are explicitly disabled.
// They must be started individually.
for (const auto& service : ServiceList::GetInstance()) {//遍历serviceList
if (service->classnames().count(args[1])) {
if (auto result = service->StartIfNotDisabled(); !result) {//执行startIfNotDisable函数
LOG(ERROR) << "Could not start service '" << service->name()
<< "' as part of class '" << args[1] << "': " << result.error();
}
}
}
return Success();
}
文件目录:/system/core/init/service.cpp
Result<Success> Service::StartIfNotDisabled() {
if (!(flags_ & SVC_DISABLED)) { //判断有没有在init.rc中配置disabled
return Start();//开启Zygote
} else {
flags_ |= SVC_DISABLED_START;
}
return Success();
}
//调用start 开启zygote服务
Result<Success> Service::Start() {
if (is_updatable() && !ServiceList::GetInstance().IsServicesUpdated()) {
ServiceList::GetInstance().DelayService(*this);
return Error() << "Cannot start an updatable service '" << name_
<< "' before configs from APEXes are all loaded. "
<< "Queued for execution.";
}
bool disabled = (flags_ & (SVC_DISABLED | SVC_RESET));
flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
if (flags_ & SVC_RUNNING) {//如果服务已经开启 就return Success
if ((flags_ & SVC_ONESHOT) && disabled) {
flags_ |= SVC_RESTART;
}
// It is not an error to try to start a service that is already running.
return Success();
}
bool needs_console = (flags_ & SVC_CONSOLE);
if (needs_console) {
if (console_.empty()) {
console_ = default_console;
}
int console_fd = open(console_.c_str(), O_RDWR | O_CLOEXEC);
if (console_fd < 0) {
flags_ |= SVC_DISABLED;
return ErrnoError() << "Couldn't open console '" << console_ << "'";
}
close(console_fd);
}
struct stat sb;
//判断对应的执行文件是否存在也就算zygote.rc中的/system/bin/app_process。手机中的/system/bin/app_process文件。
if (stat(args_[0].c_str(), &sb) == -1) {
flags_ |= SVC_DISABLED;
return ErrnoError() << "Cannot find '" << args_[0] << "'";
}
std::string scon;
if (!seclabel_.empty()) {
scon = seclabel_;
} else {
auto result = ComputeContextFromExecutable(args_[0]);
if (!result) {
return result.error();
}
scon = *result;
}
if (!IsRuntimeApexReady() && !pre_apexd_) {
pre_apexd_ = true;
}
post_data_ = ServiceList::GetInstance().IsPostData();
LOG(INFO) << "starting service '" << name_ << "'...";
//判断进程是否启动,没有启动就fork子进程。所以zygote是init的子进程。
pid_t pid = -1;
if (namespace_flags_) {
pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);
} else {
pid = fork();
}
if (pid == 0) {//子进程(zygote)中执行的函数
umask(077);
if (auto result = EnterNamespaces(); !result) {
LOG(FATAL) << "Service '" << name_ << "' could not enter namespaces: " << result.error();
}
if (namespace_flags_ & CLONE_NEWNS) {
if (auto result = SetUpMountNamespace(); !result) {
LOG(FATAL) << "Service '" << name_
<< "' could not set up mount namespace: " << result.error();
}
}
if (namespace_flags_ & CLONE_NEWPID) {
if (auto result = SetUpPidNamespace(); !result) {
LOG(FATAL) << "Service '" << name_
<< "' could not set up PID namespace: " << result.error();
}
}
for (const auto& [key, value] : environment_vars_) {
setenv(key.c_str(), value.c_str(), 1);
}
std::for_each(descriptors_.begin(), descriptors_.end(),
std::bind(&DescriptorInfo::CreateAndPublish, std::placeholders::_1, scon));
std::string cpuset_path;
if (CgroupGetControllerPath("cpuset", &cpuset_path)) {
auto cpuset_predicate = [&cpuset_path](const std::string& path) {
return StartsWith(path, cpuset_path + "/");
};
auto iter =
std::find_if(writepid_files_.begin(), writepid_files_.end(), cpuset_predicate);
if (iter == writepid_files_.end()) {
std::string default_cpuset = GetProperty("ro.cpuset.default", "");
if (!default_cpuset.empty()) {
if (default_cpuset.front() != '/') {
default_cpuset.insert(0, 1, '/');
}
if (default_cpuset.back() != '/') {
default_cpuset.push_back('/');
}
writepid_files_.push_back(
StringPrintf("%s%stasks", cpuset_path.c_str(), default_cpuset.c_str()));
}
}
} else {
LOG(ERROR) << "cpuset cgroup controller is not mounted!";
}
std::string pid_str = std::to_string(getpid());
for (const auto& file : writepid_files_) {
if (!WriteStringToFile(pid_str, file)) {
PLOG(ERROR) << "couldn't write " << pid_str << " to " << file;
}
}
if (ioprio_class_ != IoSchedClass_NONE) {
if (android_set_ioprio(getpid(), ioprio_class_, ioprio_pri_)) {
PLOG(ERROR) << "failed to set pid " << getpid()
<< " ioprio=" << ioprio_class_ << "," << ioprio_pri_;
}
}
if (needs_console) {
setsid();
OpenConsole();
} else {
ZapStdio();
}
SetProcessAttributes();
//调用execv函数,启动service子进程
if (!ExpandArgsAndExecv(args_, sigstop_)) {
PLOG(ERROR) << "cannot execve('" << args_[0] << "')";
}
_exit(127);
}
if (pid < 0) {
pid_ = 0;
return ErrnoError() << "Failed to fork";
}
if (oom_score_adjust_ != -1000) {
std::string oom_str = std::to_string(oom_score_adjust_);
std::string oom_file = StringPrintf("/proc/%d/oom_score_adj", pid);
if (!WriteStringToFile(oom_str, oom_file)) {
PLOG(ERROR) << "couldn't write oom_score_adj";
}
}
time_started_ = boot_clock::now();
pid_ = pid;
flags_ |= SVC_RUNNING;
start_order_ = next_start_order_++;
process_cgroup_empty_ = false;
bool use_memcg = swappiness_ != -1 || soft_limit_in_bytes_ != -1 || limit_in_bytes_ != -1 ||
limit_percent_ != -1 || !limit_property_.empty();
errno = -createProcessGroup(uid_, pid_, use_memcg);
if (errno != 0) {
PLOG(ERROR) << "createProcessGroup(" << uid_ << ", " << pid_ << ") failed for service '"
<< name_ << "'";
} else if (use_memcg) {
if (swappiness_ != -1) {
if (!setProcessGroupSwappiness(uid_, pid_, swappiness_)) {
PLOG(ERROR) << "setProcessGroupSwappiness failed";
}
}
if (soft_limit_in_bytes_ != -1) {
if (!setProcessGroupSoftLimit(uid_, pid_, soft_limit_in_bytes_)) {
PLOG(ERROR) << "setProcessGroupSoftLimit failed";
}
}
size_t computed_limit_in_bytes = limit_in_bytes_;
if (limit_percent_ != -1) {
long page_size = sysconf(_SC_PAGESIZE);
long num_pages = sysconf(_SC_PHYS_PAGES);
if (page_size > 0 && num_pages > 0) {
size_t max_mem = SIZE_MAX;
if (size_t(num_pages) < SIZE_MAX / size_t(page_size)) {
max_mem = size_t(num_pages) * size_t(page_size);
}
computed_limit_in_bytes =
std::min(computed_limit_in_bytes, max_mem / 100 * limit_percent_);
}
}
if (!limit_property_.empty()) {
computed_limit_in_bytes = android::base::GetUintProperty(
limit_property_, computed_limit_in_bytes, SIZE_MAX);
}
if (computed_limit_in_bytes != size_t(-1)) {
if (!setProcessGroupLimit(uid_, pid_, computed_limit_in_bytes)) {
PLOG(ERROR) << "setProcessGroupLimit failed";
}
}
}
NotifyStateChange("running");
return Success();
}
static bool ExpandArgsAndExecv(const std::vector<std::string>& args, bool sigstop) {
std::vector<std::string> expanded_args;
std::vector<char*> c_strings;
expanded_args.resize(args.size());
c_strings.push_back(const_cast<char*>(args[0].data()));
for (std::size_t i = 1; i < args.size(); ++i) {
if (!expand_props(args[i], &expanded_args[i])) {
LOG(FATAL) << args[0] << ": cannot expand '" << args[i] << "'";
}
c_strings.push_back(expanded_args[i].data());
}
c_strings.push_back(nullptr);
if (sigstop) {
kill(getpid(), SIGSTOP);
}
//执行app_process 也就是调用app_main.cpp的main函数 这样就进入到zygote了。
return execv(c_strings[0], c_strings.data()) == 0;
}
init.rc是一个配置文件,主要包含了5中类型语句:Action、Command、Service、Option和Import。具体的语法大家可以参考ReadMe 里面写的非常详细。
总结:加载并解析init.rc 根据rc文件创建Service对象,最终将service添加到service_List中,然后解析到on 执行 class_start的时候会开启服务调用Service::Start函数,fork子进程,并且执行app_process文件 开启了zygote,也就到了zygote的main函数中了。 zygote的main函数如下:
int main(int argc, char* const argv[])
{
if (!LOG_NDEBUG) {
String8 argv_String;
for (int i = 0; i < argc; ++i) {
argv_String.append("\"");
argv_String.append(argv[i]);
argv_String.append("\" ");
}
ALOGV("app_process main with argv: %s", argv_String.string());
}
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
argc--;
argv++;
const char* spaced_commands[] = { "-cp", "-classpath" };
// Allow "spaced commands" to be succeeded by exactly 1 argument (regardless of -s).
bool known_command = false;
int i;
for (i = 0; i < argc; i++) {
if (known_command == true) {
runtime.addOption(strdup(argv[i]));
ALOGV("app_process main add known option '%s'", argv[i]);
known_command = false;
continue;
}
for (int j = 0;
j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));
++j) {
if (strcmp(argv[i], spaced_commands[j]) == 0) {
known_command = true;
ALOGV("app_process main found known command '%s'", argv[i]);
}
}
if (argv[i][0] != '-') {
break;
}
if (argv[i][1] == '-' && argv[i][2] == 0) {
++i; // Skip --.
break;
}
runtime.addOption(strdup(argv[i]));
ALOGV("app_process main add option '%s'", argv[i]);
}
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;
} 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.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}
Vector<String8> args;
if (!className.isEmpty()) {
args.add(application ? String8("application") : String8("tool"));
runtime.setClassNameAndArgs(className, argc - i, argv + i);
if (!LOG_NDEBUG) {
String8 restOfArgs;
char* const* argv_new = argv + i;
int argc_new = argc - i;
for (int k = 0; k < argc_new; ++k) {
restOfArgs.append("\"");
restOfArgs.append(argv_new[k]);
restOfArgs.append("\" ");
}
ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
}
} else {
maybeCreateDalvikCache();
if (startSystemServer) {
args.add(String8("start-system-server"));
}
char prop[PROP_VALUE_MAX];
if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
ABI_LIST_PROPERTY);
return 11;
}
String8 abiFlag("--abi-list=");
abiFlag.append(prop);
args.add(abiFlag);
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
if (!niceName.isEmpty()) {
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.");
}
}
这样init的就唤起了Zygote了。
Zygote
1.Zygote的启动
在之前的init中有讲到,init解析init.rc的时候会解析service字段 并添加到serviceList中,并且执行fork对应的进程,执行程序。这些启动脚本都存放在 system/core/rootdir
目录中。
代码如下:
#解析服务 并且添加到serviceList中
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
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 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
#遍历serviceList 调用start函数 fork进程 execv执行app_process64
on nonencrypted class_start main class_start late_start
app_process64对应代码就在/frameworks/base/cmds/app_process
目录下。对应的源文件就是app_main.cpp。 init进程启动后通过调用execv(“/system/bin/app_process64”,“-Xzygote /system/bin --zygote --start-system-server”) 执行程序,并且将参数传递给main函数。
接下来我们看看zygote的main函数做了什么?
//init传递过来的参数如下 -Xzygote /system/bin --zygote --start-system-server
int main(int argc, char* const argv[])
{
//#ifndef LOG_NDEBUG
//#ifdef NDEBUG
//#define LOG_NDEBUG 1
//#else
//#define LOG_NDEBUG 0 所以这里是true 会把参数存放到argv_String中,然后打印出来
if (!LOG_NDEBUG) {
String8 argv_String;
for (int i = 0; i < argc; ++i) {
argv_String.append(""");
argv_String.append(argv[i]);
argv_String.append("" ");
}
ALOGV("app_process main with argv: %s", argv_String.string());
}
//创建开启AppRuntime,并将参数传递给AppRuntime
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
argc--;
argv++;
bool known_command = false;
int i;
for (i = 0; i < argc; i++) {
if (known_command == true) {
runtime.addOption(strdup(argv[i]));
ALOGV("app_process main add known option '%s'", argv[i]);
known_command = false;
continue;
}
for (int j = 0;
j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));
++j) {
if (strcmp(argv[i], spaced_commands[j]) == 0) {
known_command = true;
ALOGV("app_process main found known command '%s'", argv[i]);
}
}
if (argv[i][0] != '-') {//如果参数第一个字符是'-'跳出循环,Zygote传递的第一个参数是-Xzygote 所以执行到这里会跳出循环
break;
}
if (argv[i][1] == '-' && argv[i][2] == 0) {
++i; // Skip --.
break;
}
runtime.addOption(strdup(argv[i]));
ALOGV("app_process main add option '%s'", argv[i]);
}
// Parse runtime arguments. Stop at first unrecognized option.
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;
++i;
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {//传递的参数有--zygote的就把zygote赋值为true niceName = zygote
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) { //传递的参数有start--system-server 把startSystemServer 赋值为tue表示当前进程的main是需要开启system_server的
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {//如果传递的参数包含了--application 表示当前是应用程序
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {//指定进程名
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {//application程序传递过来的className 也就是需要启动的class
className.setTo(arg);
break;
} else {
--i;
break;
}
}
Vector<String8> args;
if (!className.isEmpty()) {//如果class不为空 说明是application,但是此时我们是空的,所以我们会走下面的分支
args.add(application ? String8("application") : String8("tool"));
runtime.setClassNameAndArgs(className, argc - i, argv + i);
if (!LOG_NDEBUG) {
String8 restOfArgs;
char* const* argv_new = argv + i;
int argc_new = argc - i;
for (int k = 0; k < argc_new; ++k) {
restOfArgs.append(""");
restOfArgs.append(argv_new[k]);
restOfArgs.append("" ");
}
ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
}
} else {//这里就是zygote启动模式
// We're in zygote mode.
maybeCreateDalvikCache();//创建Dalvik的缓存目录, data/dalvik-cache的目录
if (startSystemServer) {//如果需要运行system_server的 会添加这个参数
args.add(String8("start-system-server"));
}
char prop[PROP_VALUE_MAX];
if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
ABI_LIST_PROPERTY);
return 11;
}
String8 abiFlag("--abi-list=");
abiFlag.append(prop);
args.add(abiFlag);
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
if (!niceName.isEmpty()) {//设置进程别名
runtime.setArgv0(niceName.string(), true /* setProcName */);
}
if (zygote) {//注意这里之前传递的参数zygote 所以这里是true。他会调用runtime的start函数 传递com.android.internal.os.ZygoteInit 以及 init传递过来的参数 和true
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {//application模式
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.");
}
}
代码比较长,我总结下首先会打印日志把传递过来的参数打印出来。接着会创建AppRuntime
对象,将参数传递给AppRuntime并初始化。接着根据init传递过来的参数--zygote
把zygote
设置成true
表示是以zygote模式启动,如果需要开启system_server的会把start-system-server
也设置为true
。如果传递的是application就是以app模式启动,他就会查找对应的className,如果className部位空就会添加对应的参数。否则就是Zygote模式,在Zygote模式中会先创建Davik的缓存目录。最后调用runtime.start()
,看是以什么模式启动,如果是Zygote模式启动就会传递com.android.internal.os.ZygoteInit
和将整理的参数以及zygote 传递下去,如果是app模式就会传递com.android.internal.os.RuntimeInit
和 args以及 zygote;
2.AndroidRuntime
接下来我们需要接触两个非常重要的类AppRuntime和AndroidRuntime。这两个类是整个Android Runtime环境的接口类, 他们的关系是:
class AppRuntime : public AndroidRuntime
AppRuntime是AndroidRuntime的子类。
看看AppRuntime::start()
我们看到AppRuntime没有start函数,start函数的实现在父类AndroidRuntime
中。我们直接跳到AndroidRuntime中看看。 文件目录:/framework/base/core/jni/AndroidRuntime
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
ALOGD(">>>>>> START %s uid %d <<<<<<\n",
className != NULL ? className : "(unknown)", getuid());
static const String8 startSystemServer("start-system-server");
/*
* 'startSystemServer == true' means runtime is obsolete and not run from
* init.rc anymore, so we print out the boot start event here.
*/
for (size_t i = 0; i < options.size(); ++i) {
if (options[i] == startSystemServer) {
/* track our progress through the boot sequence */
const int LOG_BOOT_PROGRESS_START = 3000;
LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
}
}
//获取ANDROID_ROOT 目录
const char* rootDir = getenv("ANDROID_ROOT");
if (rootDir == NULL) {
rootDir = "/system";
if (!hasDir("/system")) {
LOG_FATAL("No root directory specified, and /system does not exist.");
return;
}
setenv("ANDROID_ROOT", rootDir, 1);
}
//获取ANDROID_RUNTIME_ROOT目录
const char* runtimeRootDir = getenv("ANDROID_RUNTIME_ROOT");
if (runtimeRootDir == NULL) {
LOG_FATAL("No runtime directory specified with ANDROID_RUNTIME_ROOT environment variable.");
return;
}
const char* tzdataRootDir = getenv("ANDROID_TZDATA_ROOT");
if (tzdataRootDir == NULL) {
LOG_FATAL("No tz data directory specified with ANDROID_TZDATA_ROOT environment variable.");
return;
}
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);//初始化JNI,加载libart.so
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {//创建虚拟机
return;
}
onVmCreated(env);//当VM创建成功后会把env传递给AppRuntime来进行处理。
if (startReg(env) < 0) {//开启注册函数 会注册很多关键的JNI函数 比如com/android/internal/os/ZygoteInit.nativeZygoteInit->com_android_internal_os_ZygoteInit_nativeZygoteInit等等函数的注册
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);
//创建对应的class 此时的className 就是main函数传递过来的com.android.internal.os.ZygoteInit 把他存入strArray
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);
}
char* slashClassName = toSlashClassName(className != NULL ? className : "");//把className的. 替换成/
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
//执行ZygoteInit的main方法 带着传递过来的参数 回调到java层
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 {
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");
}
首先校验一些目录,然后加载libart.so,创建VM虚拟机,创建成功之后会调用onVmCreated(env)
回到AppRuntime中,不过我们当前是Zygote 直接 return。函数如下
virtual void onVmCreated(JNIEnv* env)
{
if (mClassName.isEmpty()) {
return; // Zygote. Nothing to do here.
}
char* slashClassName = toSlashClassName(mClassName.string());
mClass = env->FindClass(slashClassName);
if (mClass == NULL) {
ALOGE("ERROR: could not find class '%s'\n", mClassName.string());
}
free(slashClassName);
mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
}
下来调用startReg(env);开启注册函数,在这里会注册非常多的JNI函数,例如com/android/internal/os/ZygoteInit.nativeZygoteInit->com_android_internal_os_ZygoteInit_nativeZygoteInit
等等。 接着调用toSlashClassName()把main函数传递过来的com.android.internal.os.ZygoteInit
,把.
替换成/
。通过env->findClass(“com/android/internal/os/ZygoteInit”)查找到对应的javaClass,再调用对应的Main函数。这样Zygote就进入了Java层。
我们看下Java层的代码: 文件目录:/frameworks/base/core/java/com/android/internal/os/ZygoteInit
public static void main(String argv[]) {
//zygoteServer服务端
ZygoteServer zygoteServer = null;
ZygoteHooks.startZygoteNoThreadCreation();
try {
Os.setpgid(0, 0);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to setpgid(0,0)", ex);
}
Runnable caller;
try {
// Report Zygote start time to tron unless it is a runtime restart
if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
MetricsLogger.histogram(null, "boot_zygote_init",
(int) SystemClock.elapsedRealtime());
}
String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Trace.TRACE_TAG_DALVIK);
bootTimingsTraceLog.traceBegin("ZygoteInit");
RuntimeInit.enableDdms();
boolean startSystemServer = false;
String zygoteSocketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {//此时我们传递的是有值的 所以会把startSystemServer 设置为true
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)) {
zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
//预加载资源
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
gcAndFinalize();//GC的初始化并启动
bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
bootTimingsTraceLog.traceEnd(); // ZygoteInit
// Disable tracing so that forked processes do not inherit stale tracing tags from
// Zygote.
Trace.setTracingEnabled(false, 0);
Zygote.initNativeState(isPrimaryZygote);
ZygoteHooks.stopZygoteNoThreadCreation();
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {//此时为True 调用forkSystemServer
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
Log.i(TAG, "Accepting command socket connections");
// The select loop returns early in the child process after a fork and
// loops forever in the zygote.
//服务端开启循环 等待客户端来请求
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
// We're in the child process and have exited the select loop. Proceed to execute the
// command.
if (caller != null) {
caller.run();
}
}
在ZygoteInit的Main函数中,首先创建了ZygoteServer服务端用于和客户端通信,因为Zygote是C/S架构的嘛。我们从init中带过来的参数start-system-server
所以当前的startSystemServer
是True。接着调用了preload()
static void preload(TimingsTraceLog bootTimingsTraceLog) {
Log.d(TAG, "begin preload");
bootTimingsTraceLog.traceBegin("BeginPreload");
beginPreload();
bootTimingsTraceLog.traceEnd(); // BeginPreload
bootTimingsTraceLog.traceBegin("PreloadClasses");
preloadClasses();//预加载class 比如我们用到的activity fragment service等等 文件目录在/framework/base/config/preloaded-classes
bootTimingsTraceLog.traceEnd(); // PreloadClasses
bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders");
cacheNonBootClasspathClassLoaders();
bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders
bootTimingsTraceLog.traceBegin("PreloadResources");
preloadResources();//预加载系统资源 比如主题 图片等等
bootTimingsTraceLog.traceEnd(); // PreloadResources
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
nativePreloadAppProcessHALs();//HAL 硬件抽象层
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadGraphicsDriver");
maybePreloadGraphicsDriver();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
preloadSharedLibraries();//预加载库资源
preloadTextResources();
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
//WebView相关
WebViewFactory.prepareWebViewInZygote();
endPreload();
warmUpJcaProviders();
Log.d(TAG, "end preload");
sPreloadComplete = true;
}
//预加载class
private static void preloadClasses() {
final VMRuntime runtime = VMRuntime.getRuntime();
InputStream is;
try {
is = new FileInputStream(PRELOADED_CLASSES);
} catch (FileNotFoundException e) {
Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
return;
}
Log.i(TAG, "Preloading classes...");
long startTime = SystemClock.uptimeMillis();
// Drop root perms while running static initializers.
final int reuid = Os.getuid();
final int regid = Os.getgid();
boolean droppedPriviliges = false;
if (reuid == ROOT_UID && regid == ROOT_GID) {
try {
Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to drop root", ex);
}
droppedPriviliges = true;
}
float defaultUtilization = runtime.getTargetHeapUtilization();
runtime.setTargetHeapUtilization(0.8f);
try {
BufferedReader br =
new BufferedReader(new InputStreamReader(is), Zygote.SOCKET_BUFFER_SIZE);//创建BufferReader读取文件
int count = 0;
String line;
while ((line = br.readLine()) != null) {
// Skip comments and blank lines.
line = line.trim();
if (line.startsWith("#") || line.equals("")) {
continue;
}
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
try {
if (false) {
Log.v(TAG, "Preloading " + line + "...");
}
//通过Class.forName来预加载Class
Class.forName(line, true, null);
count++;
} catch (ClassNotFoundException e) {
Log.w(TAG, "Class not found for preloading: " + line);
} catch (UnsatisfiedLinkError e) {
Log.w(TAG, "Problem preloading " + line + ": " + e);
} catch (Throwable t) {
Log.e(TAG, "Error preloading " + line + ".", t);
if (t instanceof Error) {
throw (Error) t;
}
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
throw new RuntimeException(t);
}
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
}
Log.i(TAG, "...preloaded " + count + " classes in "
+ (SystemClock.uptimeMillis() - startTime) + "ms.");
} catch (IOException e) {
Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
} finally {
IoUtils.closeQuietly(is);
// Restore default.
runtime.setTargetHeapUtilization(defaultUtilization);
// Fill in dex caches with classes, fields, and methods brought in by preloading.
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
runtime.preloadDexCaches();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
// Bring back root. We'll need it later if we're in the zygote.
if (droppedPriviliges) {
try {
Os.setreuid(ROOT_UID, ROOT_UID);
Os.setregid(ROOT_GID, ROOT_GID);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to restore root", ex);
}
}
}
}
在preload函数中,预加载了很多的资源比如class(我们常用的Activity Fragment android.app.ActivityManager…),也加载了一些系统资源 比如图片 颜色 主题等等。大家知道为什么要在这里加载这些资源吗? 之前有说过fork 会和父进程共享内存,写数据的时候会复制。所有的应用都是由于Zygote孵化,所以在这里进行预加载 所孵化的应用也默认拥有这些资源。
接着startSystemServer
为 True
所以会执行forkSystemServer,关于SystemServer我们留在下次讲。最后执行zygoteServer.runSelectLoop();
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
socketFDs.add(mZygoteSocket.getFileDescriptor());
peers.add(null);
while (true) {
fetchUsapPoolPolicyPropsWithMinInterval();
int[] usapPipeFDs = null;
StructPollfd[] pollFDs = null;//需要监听的fds
if (mUsapPoolEnabled) {
usapPipeFDs = Zygote.getUsapPipeFDs();
pollFDs = new StructPollfd[socketFDs.size() + 1 + usapPipeFDs.length];
} else {
pollFDs = new StructPollfd[socketFDs.size()];
}
int pollIndex = 0;
for (FileDescriptor socketFD : socketFDs) {
pollFDs[pollIndex] = new StructPollfd();
pollFDs[pollIndex].fd = socketFD;
pollFDs[pollIndex].events = (short) POLLIN;//对每一个socket需要关注POLLIN
++pollIndex;
}
final int usapPoolEventFDIndex = pollIndex;
if (mUsapPoolEnabled) {
pollFDs[pollIndex] = new StructPollfd();
pollFDs[pollIndex].fd = mUsapPoolEventFD;
pollFDs[pollIndex].events = (short) POLLIN;
++pollIndex;
for (int usapPipeFD : usapPipeFDs) {
FileDescriptor managedFd = new FileDescriptor();
managedFd.setInt$(usapPipeFD);
pollFDs[pollIndex] = new StructPollfd();
pollFDs[pollIndex].fd = managedFd;
pollFDs[pollIndex].events = (short) POLLIN;
++pollIndex;
}
}
try {//zygote阻塞在这里等待poll事件
Os.poll(pollFDs, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
boolean usapPoolFDRead = false;
//注意这里是采用的倒序方式的,也就是说优先处理已经建立连接的请求,后处理新建立链接的请求
while (--pollIndex >= 0) {
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}
if (pollIndex == 0) {//初始化的时候socketFDs中只有server socket。所以会创建新的通信连接调用acceptCommandPeer
// Zygote server socket
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
} else if (pollIndex < usapPoolEventFDIndex) {
// Session socket accepted from the Zygote server socket
try {//获取到客户端链接
ZygoteConnection connection = peers.get(pollIndex);
//客户端有请求进行处理
final Runnable command = connection.processOneCommand(this);
if (mIsForkChild) {
if (command == null) {
throw new IllegalStateException("command == null");
}
return command;
} else {
if (command != null) {
throw new IllegalStateException("command != null");
}
// We don't know whether the remote side of the socket was closed or
// not until we attempt to read from it from processOneCommand. This
// shows up as a regular POLLIN event in our regular processing loop.
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(pollIndex);
socketFDs.remove(pollIndex);
}
}
} catch (Exception e) {
if (!mIsForkChild) {
Slog.e(TAG, "Exception executing zygote command: ", e);
ZygoteConnection conn = peers.remove(pollIndex);
conn.closeSocket();
socketFDs.remove(pollIndex);
} else {
Log.e(TAG, "Caught post-fork exception in child process.", e);
throw e;
}
} finally {
mIsForkChild = false;
}
} else {
long messagePayload = -1;
try {
byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES];
int readBytes = Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length);
if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) {
DataInputStream inputStream =
new DataInputStream(new ByteArrayInputStream(buffer));
messagePayload = inputStream.readLong();
} else {
Log.e(TAG, "Incomplete read from USAP management FD of size "
+ readBytes);
continue;
}
} catch (Exception ex) {
if (pollIndex == usapPoolEventFDIndex) {
Log.e(TAG, "Failed to read from USAP pool event FD: "
+ ex.getMessage());
} else {
Log.e(TAG, "Failed to read from USAP reporting pipe: "
+ ex.getMessage());
}
continue;
}
if (pollIndex > usapPoolEventFDIndex) {
Zygote.removeUsapTableEntry((int) messagePayload);
}
usapPoolFDRead = true;
}
}
if (usapPoolFDRead) {
int[] sessionSocketRawFDs =
socketFDs.subList(1, socketFDs.size())
.stream()
.mapToInt(fd -> fd.getInt$())
.toArray();
final Runnable command = fillUsapPool(sessionSocketRawFDs);
if (command != null) {
return command;
}
}
}
}
首先注册poll的event 对POLLIN敏感,Os.poll(pollFDs),通过acceptCommandPeer
创建Socket服务端的连接对象ZygoteConnection,通过 processOneCommand
处理客户端的请求。
Runnable processOneCommand(ZygoteServer zygoteServer) {
String args[];
ZygoteArguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
args = Zygote.readArgumentList(mSocketReader);
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
}
if (args == null) {
isEof = true;
return null;
}
int pid = -1;
FileDescriptor childPipeFd = null;
FileDescriptor serverPipeFd = null;
parsedArgs = new ZygoteArguments(args);
if (parsedArgs.mAbiListQuery) {
handleAbiListQuery();
return null;
}
if (parsedArgs.mPidQuery) {
handlePidQuery();
return null;
}
if (parsedArgs.mUsapPoolStatusSpecified) {
return handleUsapPoolStatusChange(zygoteServer, parsedArgs.mUsapPoolEnabled);
}
if (parsedArgs.mPreloadDefault) {
handlePreload();
return null;
}
if (parsedArgs.mPreloadPackage != null) {
handlePreloadPackage(parsedArgs.mPreloadPackage, parsedArgs.mPreloadPackageLibs,
parsedArgs.mPreloadPackageLibFileName, parsedArgs.mPreloadPackageCacheKey);
return null;
}
if (canPreloadApp() && parsedArgs.mPreloadApp != null) {
byte[] rawParcelData = Base64.getDecoder().decode(parsedArgs.mPreloadApp);
Parcel appInfoParcel = Parcel.obtain();
appInfoParcel.unmarshall(rawParcelData, 0, rawParcelData.length);
appInfoParcel.setDataPosition(0);
ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(appInfoParcel);
appInfoParcel.recycle();
if (appInfo != null) {
handlePreloadApp(appInfo);
} else {
throw new IllegalArgumentException("Failed to deserialize --preload-app");
}
return null;
}
if (parsedArgs.mApiBlacklistExemptions != null) {
return handleApiBlacklistExemptions(zygoteServer, parsedArgs.mApiBlacklistExemptions);
}
if (parsedArgs.mHiddenApiAccessLogSampleRate != -1
|| parsedArgs.mHiddenApiAccessStatslogSampleRate != -1) {
return handleHiddenApiAccessLogSampleRate(zygoteServer,
parsedArgs.mHiddenApiAccessLogSampleRate,
parsedArgs.mHiddenApiAccessStatslogSampleRate);
}
if (parsedArgs.mPermittedCapabilities != 0 || parsedArgs.mEffectiveCapabilities != 0) {
throw new ZygoteSecurityException("Client may not specify capabilities: "
+ "permitted=0x" + Long.toHexString(parsedArgs.mPermittedCapabilities)
+ ", effective=0x" + Long.toHexString(parsedArgs.mEffectiveCapabilities));
}
Zygote.applyUidSecurityPolicy(parsedArgs, peer);
Zygote.applyInvokeWithSecurityPolicy(parsedArgs, peer);
Zygote.applyDebuggerSystemProperty(parsedArgs);
Zygote.applyInvokeWithSystemProperty(parsedArgs);
int[][] rlimits = null;
if (parsedArgs.mRLimits != null) {
rlimits = parsedArgs.mRLimits.toArray(Zygote.INT_ARRAY_2D);
}
int[] fdsToIgnore = null;
if (parsedArgs.mInvokeWith != null) {
try {
FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
childPipeFd = pipeFds[1];
serverPipeFd = pipeFds[0];
Os.fcntlInt(childPipeFd, F_SETFD, 0);
fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()};
} catch (ErrnoException errnoEx) {
throw new IllegalStateException("Unable to set up pipe for invoke-with", errnoEx);
}
}
int [] fdsToClose = { -1, -1 };
FileDescriptor fd = mSocket.getFileDescriptor();
if (fd != null) {
fdsToClose[0] = fd.getInt$();
}
fd = zygoteServer.getZygoteSocketFileDescriptor();
if (fd != null) {
fdsToClose[1] = fd.getInt$();
}
fd = null;
//调用native的fork
pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
try {
if (pid == 0) {
// 在子进程中 首先关闭掉ServerSocket,因为它是Zygote孵化出来的 所以socket 需要关闭掉。
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
//调用HandleChildProc mStartChildZygote = --start-child-zygote
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
// In the parent. A pid < 0 indicates a failure and will be handled in
// handleParentProc.
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
processOneCommand客户端请求的处理函数:通过Zygote.forkAndSpecialize
调用到native函数nativeForkAndSpecialize
来fork出来客户端进程。
文件目录:/frameworks/base/core/com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
jint runtime_flags, jobjectArray rlimits,
jint mount_external, jstring se_info, jstring nice_name,
jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
jstring instruction_set, jstring app_data_dir) {
……………………
pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore);
if (pid == 0) {
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
capabilities, capabilities,
mount_external, se_info, nice_name, false,
is_child_zygote == JNI_TRUE, instruction_set, app_data_dir);
}
return pid;
}
static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
const std::vector<int>& fds_to_close,
const std::vector<int>& fds_to_ignore) {
SetSignalHandlers();
……………………
pid_t pid = fork();//fork出来客户端请求的进程。
if (pid == 0) {
// The child process.
PreApplicationInit();
// Clean up any descriptors which must be closed immediately
DetachDescriptors(env, fds_to_close, fail_fn);
// Invalidate the entries in the USAP table.
ClearUsapTable();
// Re-open all remaining open file descriptors so that they aren't shared
// with the zygote across a fork.
gOpenFdTable->ReopenOrDetach(fail_fn);
// Turn fdsan back on.
android_fdsan_set_error_level(fdsan_error_level);
} else {
ALOGD("Forked child process %d", pid);
}
fork出来进程之后在子进程中 首先关闭掉ServerSocket,因为它是Zygote孵化出来的 所以socket 需要关闭掉。 调用handleParentProc
设置子进程.
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
closeSocket();//关闭socket
if (descriptors != null) {
try {
Os.dup2(descriptors[0], STDIN_FILENO);
Os.dup2(descriptors[1], STDOUT_FILENO);
Os.dup2(descriptors[2], STDERR_FILENO);
for (FileDescriptor fd: descriptors) {
IoUtils.closeQuietly(fd);
}
} catch (ErrnoException ex) {
Log.e(TAG, "Error reopening stdio", ex);
}
}
if (parsedArgs.mNiceName != null) {
Process.setArgV0(parsedArgs.mNiceName);
}
// End of the postFork event.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
if (parsedArgs.mInvokeWith != null) {
WrapperInit.execApplication(parsedArgs.mInvokeWith,
parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.mRemainingArgs);
// Should not get here.
throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
} else {
if (!isZygote) {//此时看客户端是否传递--start-child-zygote
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
}
}
}
关闭当前socket,然后根据客户端传递的参数来决定是走哪一个逻辑,如果不是child-zygote就会执行ZygoteInit.zygoteInit();
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
//调用了nativeZygoteInit
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
调用了native函数nativeZygoteInit 在AndroidRuntime中
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
调用到AppRuntime的onZygoteInit
virtual void onZygoteInit()
{
//这个可以看我之前写的binder文章。让当前进程支持IPC通讯,binder。
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
最后调用RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader)
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
nativeSetExitWithoutCleanup(true);
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args = new Arguments(argv);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
//根据客户端请求args 来找到需要启动的class 执行Main函数
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
return new MethodAndArgsCaller(m, argv);
}
最后返回MethodAndArgsCaller到ZygoteInit.java的Main函数中 执行对应的run 函数.也就是客户端请求的class的Main函数了。
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
以上整个Zygote的流程就结束了。