0%

Android系统启动-综述

前言

本文是介绍Android系统启动流程。

目录

Android系统架构

为了更好理解 Android 系统启动流程,我们需要先了解 Android 系统架构。它分为五层,从下往上依次分为Linux内核HAL硬件抽象层系统Native库和Android运行时环境Java Framework框架层应用层。如下图所示:

启动流程概述

Android系统的启动,主要是指Android手机长按电源键后,Android手机开机的过程。可分为四步:启动电源->执行引导程序BootLoader->启动内核->启动Init进程。Init进程启动过程中会启动ServiceManager和Zygote进程,Zygote进程启动过程中通过fork启动SystemServer进程,SystemServer进程启动过程中会开启AMS(ActivityManagerService)等各种系统服务,通过AMS启动系统桌面即Launcher。

Init进程启动过程:

  • 启动ServiceManager—— Binder服务的总管
  • 启动Zygote——Android系统的第一个Java进程(即虚拟机进程),所有App进程的父进程
    • 启动SystemServer——Android系统服务的载体,承载framework层核心业务
      • 启动Launcher——Android系统的“桌面”

系统启动架构图

图解: Android系统启动过程由上图从下往上的一个过程是由BootLoader引导开机,然后依次进入 -> Kernel -> Native -> Framework -> App

启动电源

当电源按下,引导芯片从 ROM(一般指 Flash ROM,即闪存)中预定义的位置开始执行,加载引导程序 BootLoader 到 RAM,然后执行。

执行引导程序BootLoader

Boot Loader是在系统内核运行之前运行的引导程序,也是系统运行的第一个程序。

主要作用是:初始化 RAM、初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。

启动内核Kernel

Linux系统启动主要分为三个阶段:第一个阶段是自解压过程,第二个是设置ARM处理器的工作模式、设置一级页表等,第三个阶段主要是C代码,包括Android的初始化的全部工作。

内核解压缩完成后,通过执行文件head.Shead-common.S 的汇编代码,查找处理器类型和机器码类型来调用相应的初始化函数,然后进入内核入口函数 start_kernel() 开始之后的内核初始化工作,主要是与硬件平台的相关初始化工作。在完成一系列的与内核相关的初始后,调用 rest_init() 函数来进行最后的初始化并创建第一个用户进程 init 进程,由此进入用户态进程。Linux内核启动的最后一个阶段就是挂载根文件系统,因为启动第一个init进程,必须以根文件系统为载体。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//kernel的入口函数start_kernel
asmlinkage __visible void __init start_kernel(void)
{
...
rest_init();
...
}

//开启init进程
static noinline void __init_refok rest_init(void)
{
...
//kernel_init函数在kernel线程中运行
kernel_thread(kernel_init, NULL, CLONE_FS);
...
}

//内核初始化
static int __ref kernel_init(void *unused)
{
...
//从下面的路径中找到init进程的可执行文件,
//并开启用户态的init进程,由内核态进程跳转到用户态进程
if (!try_to_run_init_process("/sbin/init") ||
!try_to_run_init_process("/etc/init") ||
!try_to_run_init_process("/bin/init") ||
!try_to_run_init_process("/bin/sh"))
return 0;

panic("No working init found. Try passing init= option to kernel. "
"See Linux Documentation/init.txt for guidance.");
}

内核启动时,会设置缓存、被保护存储器、计划列表,加载驱动。当内核完成系统设置,它首先在系统文件中寻找”init”文件,然后启动第一个用户空间进程init进程。

  • 启动 Kernel 的 swapper 进程(pid=0):该进程又称为 idle 进程,系统初始化过程 Kernel 由无到有开创的第一个进程, 用于初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作;
  • 启动 kthreadd 进程(pid=2):是 Linux 系统的内核进程,会创建内核工作线程 kworkder,软中断线程ksoftirqd,thermal 等内核守护进程。kthreadd 进程是所有内核进程的鼻祖。

启动init进程

Kernel 启动过程会创建 init 进程(pid=1),是用户空间的第一个进程。内核启动后调用init进程的入口函数main()方法,在system/core/init/main.cpp(注:基于Android 10.0的源码)

init/main.cpp.main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using namespace android::init;
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);//对SELinux安全机制进行初始化
}

if (!strcmp(argv[1], "second_stage")) {
return SecondStageMain(argc, argv);//第二阶段
}
}

return FirstStageMain(argc, argv); //第一阶段
}
FirstStageMain
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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"));
CHECKCALL(mkdir("/dev/pts", 0755));
CHECKCALL(mkdir("/dev/socket", 0755));
CHECKCALL(mount("devpts", "/dev/pts", "devpts", 0, NULL));
#define MAKE_STR(x) __STRING(x)
CHECKCALL(mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC)));
#undef MAKE_STR
// Don't expose the raw commandline to unprivileged processes.
CHECKCALL(chmod("/proc/cmdline", 0440));
gid_t groups[] = {AID_READPROC};
CHECKCALL(setgroups(arraysize(groups), groups));
CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL));
CHECKCALL(mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL));

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)));

// This is needed for log wrapper, which gets called before ueventd runs.
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"));
// /mnt/vendor is used to mount vendor-specific partitions that can not be
// part of the vendor partition, e.g. because they are mounted read-write.
CHECKCALL(mkdir("/mnt/vendor", 0755));
// /mnt/product is used to mount product-specific partitions that can not be
// part of the product partition, e.g. because they are mounted read-write.
CHECKCALL(mkdir("/mnt/product", 0755));

// /apex is used to mount APEXes
CHECKCALL(mount("tmpfs", "/apex", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
"mode=0755,uid=0,gid=0"));

// /debug_ramdisk is used to preserve additional files from the debug ramdisk
CHECKCALL(mount("tmpfs", "/debug_ramdisk", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
"mode=0755,uid=0,gid=0"));
#undef CHECKCALL

SetStdioToDevNull(argv);
// Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
// talk to the outside world...
InitKernelLogging(argv);

if (!errors.empty()) {
for (const auto& [error_string, error_errno] : errors) {
LOG(ERROR) << error_string << " " << strerror(error_errno);
}
LOG(FATAL) << "Init encountered errors starting first stage, aborting";
}

LOG(INFO) << "init first stage started!";

auto old_root_dir = std::unique_ptr<DIR, decltype(&closedir)>{opendir("/"), closedir};
if (!old_root_dir) {
PLOG(ERROR) << "Could not opendir(\"/\"), not freeing ramdisk";
}

struct stat old_root_info;
if (stat("/", &old_root_info) != 0) {
PLOG(ERROR) << "Could not stat(\"/\"), not freeing ramdisk";
old_root_dir.reset();
}

if (ForceNormalBoot()) {
mkdir("/first_stage_ramdisk", 0755);
// SwitchRoot() must be called with a mount point as the target, so we bind mount the
// target directory to itself here.
if (mount("/first_stage_ramdisk", "/first_stage_ramdisk", nullptr, MS_BIND, nullptr) != 0) {
LOG(FATAL) << "Could not bind mount /first_stage_ramdisk to itself";
}
SwitchRoot("/first_stage_ramdisk");
}

// If this file is present, the second-stage init will use a userdebug sepolicy
// and load adb_debug.prop to allow adb root, if the device is unlocked.
if (access("/force_debuggable", F_OK) == 0) {
std::error_code ec; // to invoke the overloaded copy_file() that won't throw.
if (!fs::copy_file("/adb_debug.prop", kDebugRamdiskProp, ec) ||
!fs::copy_file("/userdebug_plat_sepolicy.cil", kDebugRamdiskSEPolicy, ec)) {
LOG(ERROR) << "Failed to setup debug ramdisk";
} else {
// setenv for second-stage init to read above kDebugRamdisk* files.
setenv("INIT_FORCE_DEBUGGABLE", "true", 1);
}
}

if (!DoFirstStageMount()) {
LOG(FATAL) << "Failed to mount required partitions early ...";
}

struct stat new_root_info;
if (stat("/", &new_root_info) != 0) {
PLOG(ERROR) << "Could not stat(\"/\"), not freeing ramdisk";
old_root_dir.reset();
}

if (old_root_dir && old_root_info.st_dev != new_root_info.st_dev) {
FreeRamdisk(old_root_dir.get(), old_root_info.st_dev);
}

SetInitAvbVersionInRecovery();

static constexpr uint32_t kNanosecondsPerMillisecond = 1e6;
uint64_t start_ms = start_time.time_since_epoch().count() / kNanosecondsPerMillisecond;
setenv("INIT_STARTED_AT", std::to_string(start_ms).c_str(), 1);

const char* path = "/system/bin/init";
const char* args[] = {path, "selinux_setup", nullptr};
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;
}
SetupSelinux
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// This function initializes SELinux then execs init to run in the init SELinux context.
int SetupSelinux(char** argv) {
InitKernelLogging(argv);

if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}

// Set up SELinux, loading the SELinux policy.
SelinuxSetupKernelLogging();
SelinuxInitialize();

// We're in the kernel domain and want to transition to the init domain. File systems that
// store SELabels in their xattrs, such as ext4 do not need an explicit restorecon here,
// but other file systems do. In particular, this is needed for ramdisks such as the
// recovery image for A/B devices.
if (selinux_android_restorecon("/system/bin/init", 0) == -1) {
PLOG(FATAL) << "restorecon failed of /system/bin/init failed";
}

const char* path = "/system/bin/init";
const char* args[] = {path, "second_stage", nullptr};
execv(path, const_cast<char**>(args));

// execv() only returns if an error happened, in which case we
// panic and never return from this function.
PLOG(FATAL) << "execv(\"" << path << "\") failed";
return 1;
}
SecondStageMain
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
int SecondStageMain(int argc, char** argv) {
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}

SetStdioToDevNull(argv);
InitKernelLogging(argv);
LOG(INFO) << "init second stage started!";

// Set init and its forked children's oom_adj.
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();
}

// Enable seccomp if global boot option was passed (otherwise it is enabled in zygote).
GlobalSeccomp();

// Set up a session keyring that all processes will have access to. It
// will hold things like FBE encryption keys. No process should override
// its session keyring.
keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1);

// Indicate that booting is in progress to background fw loaders, etc.
close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));

// 初始化属性相关资源
property_init();

// If arguments are passed both on the command line and in DT,
// properties set in DT always have priority over the command-line ones.
process_kernel_dt();
process_kernel_cmdline();

// Propagate the kernel variables to internal variables
// used by init as well as the current required properties.
export_kernel_boot_props();

// Make the time that init started available for bootstat to log.
property_set("ro.boottime.init", getenv("INIT_STARTED_AT"));
property_set("ro.boottime.init.selinux", getenv("INIT_SELINUX_TOOK"));

// Set libavb version for Framework-only OTA match in Treble build.
const char* avb_version = getenv("INIT_AVB_VERSION");
if (avb_version) property_set("ro.boot.avb_version", avb_version);

// See if need to load debug props to allow adb root, when the device is unlocked.
const char* force_debuggable_env = getenv("INIT_FORCE_DEBUGGABLE");
if (force_debuggable_env && AvbHandle::IsDeviceUnlocked()) {
load_debug_prop = "true"s == force_debuggable_env;
}

// Clean up our environment.
unsetenv("INIT_STARTED_AT");
unsetenv("INIT_SELINUX_TOOK");
unsetenv("INIT_AVB_VERSION");
unsetenv("INIT_FORCE_DEBUGGABLE");

// Now set up SELinux for second stage.
SelinuxSetupKernelLogging();
SelabelInitialize();
SelinuxRestoreContext();

Epoll epoll;
if (auto result = epoll.Open(); !result) {
PLOG(FATAL) << result.error();
}

// 设置子信号处理函数
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();
//加载引导脚本
LoadBootScripts(am, sm);

// 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();

// 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())) {
//内部会执行每个action中携带的command对应的执行函数
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;
}
LoadBootScripts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//加载引导脚本
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
Parser parser = CreateParser(action_manager, service_list);

std::string bootscript = GetProperty("ro.boot.init_rc", "");
if (bootscript.empty()) {
//解析init.rc配置文件
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);
}
}

init进程的执行过程,调用init.main()方法:

  1. 创建和挂载启动所需的文件目录
  2. 处理子进程的终止(signal信号量方式)
  3. 初始化和启动属性服务
  4. 解析init.rc配置文件并启动Zygote进程

注:init.rc 是Android初始化语言编写的一个非常重要的配置脚本文件。它主要包含五种类型语句:Action、Commands、Services、Options和Import。 ServiceManager进程和Zygote进程都是由init进程解析init.rc中特定的语句启动的。

ServiceManager

servicemanager 进程是由 init 进程通过解析 init.rc 文件(位于system/core/rootdir/)来启动的。从Android 5.0开始中对 init.rc 文件进行了拆分,每个服务一个rc文件。ServiceManager的启动脚本文件frameworks/native/cmds/servicemanager/servicemanager.rc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
service servicemanager /system/bin/servicemanager
class core animation
user system //1
group system readproc
critical //2
onrestart restart healthd
onrestart restart zygote
onrestart restart audioserver
onrestart restart media
onrestart restart surfaceflinger
onrestart restart inputflinger
onrestart restart drm
onrestart restart cameraserver
onrestart restart keystore
onrestart restart gatekeeperd
onrestart restart thermalservice
writepid /dev/cpuset/system-background/tasks
shutdown critical

service用于通知init进程创建名为servicemanager的进程,这个servicemanager进程执行程序的路径为/system/bin/servicemanager

注释1的关键字user说明servicemanager是以用户system的身份运行的,注释2处的critical说明servicemanager是系统中的关键服务,关键服务是不会退出的,如果退出了,系统就会重启,当系统重启时就会启动用onrestart关键字修饰的进程,比如zygote、media、surfaceflinger等。

ServiceManager.main

servicemanager 入口函数在 framework/native/cmds/servicemanager/service_manager.c,简化后的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main(int argc, char **argv) {
struct binder_state *bs;
// 打开binder驱动,申请 128k 字节大小的内存空间
bs = binder_open(128*1024);
...

// 成为上下文管理者
if (binder_become_context_manager(bs)) {
return -1;
}

// 验证 selinux 权限,判断进程是否有权注册或查看指定服务
selinux_enabled = is_selinux_enabled();
...
// 进入无限循环,处理 client 端发来的请求
binder_loop(bs, svcmgr_handler);
return 0;
}

这里重点关注两点,首先,在申请了一块大小为 128k 的内存空间并验证 selinux 权限后,接着调用 framework/native/cmds/servicemanager/binder.c 中的 binder_become_context_manager 方法:

1
2
3
4
int binder_become_context_manager(struct binder_state *bs) {
// 通过ioctl,发送 BINDER_SET_CONTEXT_MGR 指令
return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}

然后,调用 binder_loop 方法进入循环来处理 client 发来的请求,注意第二个参数是一个方法体,用于处理各种状态回调:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int svcmgr_handler(...){

switch(txn->code) {
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
// 获取服务名
s = bio_get_string16(msg, &len);
// 根据名称查找相应服务
handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
bio_put_ref(reply, handle);
return 0;

case SVC_MGR_ADD_SERVICE:
// 获取服务名
s = bio_get_string16(msg, &len);
handle = bio_get_ref(msg);
allow_isolated = bio_get_uint32(msg) ? 1 : 0;
// 注册指定服务
if (do_add_service(bs, s, len, handle, txn->sender_euid,
allow_isolated, txn->sender_pid))
return -1;
break;
}
}

总结一下ServiceManager 进程启动过程:

  1. 调用 binder_open 方法打开 Binder 驱动,并申请分配一块 128k 的内存空间
  2. 调用 binder_become_context_manager 方法发送 BINDER_SET_CONTEXT_MGR 给 Binder 驱动,使自己成为上下文管理者
  3. 验证 selinux 权限,判断进程是否有注册或查看指定服务的权限
  4. 调用 binder_loop 方法进入循环状态,等待 Client 请求
  5. 根据服务名称注册服务·
  6. 接收 Binder 死亡通知

Zygote

Zygote进程在init进程中以service的方式启动的,由 init 进程通过解析 init.rc 文件来启动的。init.rc 并不是直接引入某个固定的文件,而是根据属性ro.zygote的内容来引入不同的文件。这是因为从Android 5.0开始,Android系统开始支持64位的编译,Zygote进程本身也会有32位和64位版本的区别。所以在init.rc的同级目录system/core/rootdir/下一共有4个和zygote相关的rc文件:

  • init.zygote32
  • init.zygote64
  • init.zygote32_64
  • init.zygote64_32

init.zygote32.rc:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

init.zygote32_64.rc:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=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 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

service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
class main
priority -20
user root
group root readproc reserved_disk
socket zygote_secondary stream 660 root system
socket usap_pool_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks

从init.zygote32_64.rc 文件可以看到,这种情况下系统定义了两个zygote 服务:zygotezygote_secodary。这两个服务最大的区别是启动的可执行文件不同,一个是app_process32,一个是app_process64。所以从这里我们可以知道,Andorid系统支持4种运行模式:

纯32位模式:属性ro.zygote的值为zygote32

混32位模式(即32位为主,64位为辅)模式:属性ro.zygote的值为zygote32_64

纯64位模式:属性ro.zygote的值为zygote64

混64位模式(即 64位为主,32位为辅)模式:属性ro.zygote值为zygote64_32

init进程启动Zygote流程

先看到init.rc的这部分配置代码:

1
2
3
4
5
6
7
...
on nonencrypted
exec - root -- /system/bin/update_verifier nonencrypted
// 1
class_start main
class_start late_start
...

1.使用class_start这个COMMAND去启动Zygote。其中class_start对应do_class_start()函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
static Result<Success> do_class_start(const BuiltinArguments& args) {
// Starting a class does not start services which are explicitly disabled.
// They must be started individually.
for (const auto& service : ServiceList::GetInstance()) {
if (service->classnames().count(args[1])) {
// 2
if (auto result = service->StartIfNotDisabled(); !result) {
LOG(ERROR) << "Could not start service'" << service->name()
<< "' as part of class '" << args[1] << "': " << result.error();
}
}
}
return Success();
}

2.在system/core/init/builtins.cpp的do_class_start()函数中会遍历前面的Vector类型的Service链表,找到classname为main的Zygote,并调用system/core/init/service.cpp中的startIfNotDisabled()函数。

1
2
3
4
5
6
7
8
bool Service::StartIfNotDisabled() {
if (!(flags_ & SVC_DISABLED)) {
return Start();
} else {
flags_ |= SVC_DISABLED_START;
}
return Success();
}

3.如果Service没有再其对应的rc文件中设置disabled选项,则会调用Start()启动该Service。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
bool Service::Start() {

...

if (flags_ & SVC_RUNNING) {
if ((flags_ & SVC_ONESHOT) && disabled) {
flags_ |= SVC_RESTART;
}
// 如果不是一个错误,尝试去启动一个已经启动的服务
return Success();
}

...

// 判断需要启动的Service的对应的执行文件是否存在,不存在则不启动该Service
struct stat sb;
if (stat(args_[0].c_str(), &sb) == -1) {
flags_ |= SVC_DISABLED;
return ErrnoError() << "Cannot find '" << args_[0] << "'";
}

...

// fork函数创建子进程
pid_t pid = fork();
// 运行在子进程中
if (pid == 0) {
umask(077);
...

// 在ExpandArgsAndExecv函数里进行了参数装配并使用了execv()执行程序
if (!ExpandArgsAndExecv(args_)) {
PLOG(ERROR) << "cannot execve('" << args_[0] << "')";
}

_exit(127);
}
...
return true;
}

static bool ExpandArgsAndExecv(cons std::vector<std::string>& args) {
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);

// 最终通过execv执行程序
return execv(c_strings[0], c_strings.data()) == 0;
}

4.在Start()函数中,如果Service已经运行,则不再启动。如果没有,则使用fork()函数创建子进程,并返回pid值。当pid为0时,则说明当前代码逻辑在子进程中运行,最然后会调用execv()函数去启动子进程,并进入该Service的main函数中,如果该Service是Zygote,则会执行Zygote的main函数。

app_process/app_main.cpp.main

Zygote 进程入口函数在frameworks/base/cmds/app_process/app_main.cpp,它的 main 方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
int main(int argc, char* const argv[])
{
...
//创建了AppRuntime对象,AppRuntime类继承自AndroidRuntime
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
// Process command line arguments
// ignore argv[0]
argc--;
argv++;
//从命令行参数中找到虚拟机相关的参数,添加到runtime对象
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]));
// The static analyzer gets upset that we don't ever free the above
// string. Since the allocation is from main, leaking it doesn't seem
// problematic. NOLINTNEXTLINE
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]));
// The static analyzer gets upset that we don't ever free the above
// string. Since the allocation is from main, leaking it doesn't seem
// problematic. NOLINTNEXTLINE
ALOGV("app_process main add option '%s'", argv[i]);
}
// Parse runtime arguments. Stop at first unrecognized option.
// 解析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;
} 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;
}
}
//准备启动ZygoteInit类或者RuntimeInit类,根据类名是否存在为空,来区别是非zyoget模式和zyoget模式.
Vector<String8> args;
if (!className.isEmpty()) {
// We're not in zygote mode, the only argument we need to pass
// to RuntimeInit is the application argument.
// The Remainder of args get passed to startup class main(). Make
// copies of them before we overwrite them with the process name.
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 {
// We're in zygote mode.
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);

// In zygote mode, pass all remaining arguments to the zygote
// main() method.
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
//如果niceName不为空,则将本进程的名称修改为参数** --nice-name** 指定的字符串。缺省的情况下,niceName 的值为"zygote"或者"zygote64"
if (!niceName.isEmpty()) {
runtime.setArgv0(niceName.string(), true /* setProcName */);
}

// 调用 AppRuntime 父类 AndroidRuntime 的 start 方法创建 zygote 进程
if (zygote) {
//zygote 模式,即启动ZygoteInit.java
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
//非zygote 模式,即启动RuntimeInit.java
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.");
return 10;
}
}

5.调用runtime.start()方法初始化Android运行环境并进入ZygoteInit的main方法进入Java层。AppRuntime继承自AndroidRuntime类,并且重载了onVmCreated 、onStarted、onZygoteInit和onExit函数。我们发现并没有重载start函数,而在app_main.cpp的main()函数的最后runtime.start函数,所以具体执行在AndroidRuntime类的start函数。

AndroidRuntime类是安卓底层系统超级重要的一个类,它负责启动虚拟机以及Java线程。AndroidRuntime类是在一个进程中只有一个实例对象,并将其保存在全局变量gCurRuntime中。

AndroidRuntime.cpp.start

AndroidRuntime 类frameworks/base/core/jni/AndroidRuntime.cpp 的 start 方法:

该方法注释说明:

启动Android运行时环境,包括启动虚拟机并调用以”className”命名的类的静态main()方法。
这个mian方法的两个入参一个是类名,一个是特定选项的字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
* named by "className".
*/
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
...

//获取系统目录
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);
}

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;
}

//const char* kernelHack = getenv("LD_ASSUME_KERNEL");
//ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);


/* start the virtual machine */
JniInvocation jni_invocation;
//完成jni接口的初始化
jni_invocation.Init(NULL);
JNIEnv* env;
//启动虚拟机
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
//调用继承类的AppRuntime中的重载函数
//如果是Zygote的启动,则onVmCreated实际上什么也不做,如果是非Zygote模式,则根据类名获取类,并释放了类名
onVmCreated(env);

/*
* Register android functions.
*/
//注册系统的JNI函数
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.
*/
//为启动Java类的main函数做准备
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.
*/
//调用Zygoteinit类或RuntimeInit类的main()函数
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 {
// 找到 ZygoteInit/RuntimeInit 的 main 函数
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 {
// 通过 JNI 调用 ZygoteInit/RuntimeInit 的 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. startVm(),创建虚拟机
  2. startReg(),注册JNI方法
  3. env->CallStaticVoidMethod(),调用 Java 层指定的class的静态main方法

至此,总结一下 Zygote 进程启动过程:

  1. 由init进程解析init.rc文件,通过解析命令调用Service.cpp.Start()fork出Zygote进程,最后执行execv()调用进入Zygote的main方法app_process/app_main.cpp.main()
  2. 调用AndroidRuntime.start()方法开始创建Android运行时环境
  3. 调用AndroidRuntime.startVM()方法初始化创建和启动Dalvik虚拟机
  4. 调用AndroidRuntime.startReg()为DVM注册系统JNI方法
  5. 调用 JNI方法CallStaticVoidMethod() 反射调用ZygoteInit类静态main()方法执行Zygote进程,第一次进入Java的世界
ZygoteInit.main

通过 JNI 的方式进入Java FrameWork层frameworks/base/core/java/com/android/internal/os/ZygoteInit.java 的main方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
public static void main(String argv[]) {
ZygoteServer zygoteServer = null;

// Mark zygote start. This ensures that thread creation will throw
// an error.
//这里其实只是设置一个标志位,为创建Java线程时做判断处理,如果是zygote进程,则不需要开启线程
ZygoteHooks.startZygoteNoThreadCreation();

// Zygote goes into its own process group.
try {
//设置进程组ID
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());
}
//判断当前进程是64位程序还是32位程序,并设置标记
String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Trace.TRACE_TAG_DALVIK);
bootTimingsTraceLog.traceBegin("ZygoteInit");
RuntimeInit.enableDdms();// 启用 DDMS

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;
} 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.");
}

// In some configurations, we avoid preloading resources and classes eagerly.
// In such cases, we will preload things prior to our first fork.
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();
}

// Do an initial gc to clean up after startup
bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
gcAndFinalize();//调用ZygoteHooks.gcAndFinalize()进行垃圾回收
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,为其他进程初始化创建时与mZygoteSocket通信做准备
zygoteServer = new ZygoteServer(isPrimaryZygote);

if (startSystemServer) {
//启动SystemServer进程,通过fork的方式开启zygote的子进程systemServer,并返回一个Runnale对象
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();// 关闭并释放 socket 连接
}
}

// We're in the child process and have exited the select loop. Proceed to execute the
// command.
if (caller != null) {
caller.run();
}
}

Zygote 进程执行过程,调用ZygoteInit.main()方法:

  1. 解析调用参数argv,初始化startSystemServer、zygoteSocketName等变量
  2. 调用ZygoteInit.preload(),进行一些系统类、资源、共享库的预加载工作,以提升运行时效率
  3. 调用ZygoteInit.gcAndFinalize(),在 forkSystemServer 之前主动进行一次GC操作
  4. 调用ZygoteServer构造方法,创建zygoteServer对象,用来管理和子进程通信的socket服务端,内部会创建和子进程通信的mZygoteSocket对象
  5. 调用ZygoteInit.forkSystemServer(), fork 出 SystemServer 系统服务进程
  6. 调用ZygoteServer.runSelectLoop(),循环等待处理客户端发送的创建新的应用进程请求
ZygoteInit.preload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
> ZygoteInit.java

static void preload(TimingsTraceLog bootTimingsTraceLog) {
......
preloadClasses(); // 预加载并初始化 /system/etc/preloaded-classes 中的类
......
preloadResources(); // 预加载系统资源
......
nativePreloadAppProcessHALs(); // HAL
......
preloadOpenGL(); // 预加载 OpenGL
......
preloadSharedLibraries(); // 预加载 共享库,包括 android、compiler_rt、jnigraphics 这三个库
preloadTextResources(); // 预加载文字资源
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
// WebViewFactory 中一些必须在 zygote 进程中进行的初始化工作,用于共享内存
WebViewFactory.prepareWebViewInZygote();
warmUpJcaProviders();

sPreloadComplete = true;
}
ZygoteInit.gcAndFinalize
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> ZygoteInit.java
private static void gcAndFinalize() {
ZygoteHooks.gcAndFinalize();
}

> ZygoteHooks.java
public static void gcAndFinalize() {
final VMRuntime runtime = VMRuntime.getRuntime();

/* runFinalizationSync() lets finalizers be called in Zygote,
* which doesn't have a HeapWorker thread.
*/
System.gc();
runtime.runFinalizationSync();
System.gc();
}
ZygoteInit.zygoteServer
1
2
3
...
zygoteServer = new ZygoteServer(isPrimaryZygote);
...

ZygoteServer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ZygoteServer {   
...

ZygoteServer(boolean isPrimaryZygote) {
mUsapPoolEventFD = Zygote.getUsapPoolEventFD();
if (isPrimaryZygote) {
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
} else {
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME);
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);
}

fetchUsapPoolPolicyProps();
mUsapPoolSupported = true;
}
}
ZygoteInit.forkSystemServer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//准备参数并 fork 系统进程
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_IPC_LOCK,
...
);
/* Containers run without some capabilities, so drop any caps that are not available. */
StructCapUserHeader header = new StructCapUserHeader(
OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
StructCapUserData[] data;
try {
data = Os.capget(header);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to capget()", ex);
}
capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);

/* Hardcoded command line to start the system server */
// 启动参数
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
+ "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",// 进程名
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",// 加载类名
};
ZygoteArguments parsedArgs = null;

int pid;

try {
parsedArgs = new ZygoteArguments(args);
Zygote.applyDebuggerSystemProperty(parsedArgs);
Zygote.applyInvokeWithSystemProperty(parsedArgs);

boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer) {
parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}

/* Request to fork the system server process */
//fork system_server 进程
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}

/* For child process */
//pid == 0 表示子进程即system_server进程,继续剩余工作
if (pid == 0) {
if (hasSecondZygote(abiList)) {
// 如果有第二个 Zygote,需要等待2个zygote创建完成
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket(); // 关闭并释放从 Zygote 复制过来的 socket
return handleSystemServerProcess(parsedArgs);//完成新创建的 system_server 进程的剩余工作
}
return null;//如果是父进程就返回null
}

从上面的启动参数可以看到,SystemServer 进程的 uidgid 都是 1000,进程名是 system_server ,其最后要加载的类名是 com.android.server.SystemServer 。准备好一系列参数之后通过 ZygoteConnection.Arguments()拼接,接着调用 Zygote.forkSystemServer() 方法,然后如果是子进程执行剩余工作,如果是父进程返回null。

ZygoteInit.forkSystemServer方法:

  1. 为fork准备参数parsedArgs
  2. 调用Zygote.forkSystemServer()方法来创建system_server
  3. fork之后,是子进程调用handleSystemServerProcess()方法执行system_server的剩余工作,父进程返回null
ZygoteServer.runSelectLoop

处理启动应用的请求,位于frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//执行zygote进程的循环。当来一个新的连接请求时,则建立接受并建立连接,并在连接中读取请求的命令
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
//mZygoteSocket是zygote进程中的socket服务端
socketFDs.add(mZygoteSocket.getFileDescriptor());
peers.add(null);

while (true) {
fetchUsapPoolPolicyPropsWithMinInterval();

int[] usapPipeFDs = null;
StructPollfd[] pollFDs = null;

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;
++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 {
// 查询轮询状态,当pollFDs有事件到来则往下执行,否则阻塞在这里
Os.poll(pollFDs, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}

boolean usapPoolFDRead = false;

while (--pollIndex >= 0) {
// 采用I/O 多路复用机制,当接受到客户端发出的连接请求,或者处理事件时,则往下执行
// 否则进入continue,跳出本次循环
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}

if (pollIndex == 0) {
// Zygote server socket
// 有新客户端连接,服务端调用accept与客户端建立连接
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
ZygoteConnection connection = peers.get(pollIndex);
//读取一个sokcet命令,并fork出子进程,执行子进程的main函数
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");
}
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(pollIndex);
socketFDs.remove(pollIndex);
}
}
}
...
}

ZygoteServer.runSelectLoop 方法:

  1. 监听socket事件, Os.poll(pollFDs, -1)查询轮询状态,有事件执行否则阻塞
  2. 接受连接请求,调用acceptCommandPeer创建客户端连接 ZygoteConnection 对象
  3. 处理客户端请求,获取一个 ZygoteConnection 对象并执行其processOneCommand()函数,读取一个sokcet命令,并fork出子进程,执行子进程的main函数
ZygoteConnection.processOneCommand

processOneCommand() 方法调用创建子进程的方法,这里就贴一下关键部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//从套接字读取一个启动命令,如果成功的话,
//在子进程中返回调用子进程main方法的Runnable
//父进程则返回null。
Runnable processOneCommand(ZygoteServer zygoteServer) {
String args[];
ZygoteArguments parsedArgs = null;
FileDescriptor[] descriptors;

try {
args = Zygote.readArgumentList(mSocketReader); //从sokcet中读取参数

// TODO (chriswailes): Remove this and add an assert.
descriptors = mSocket.getAncillaryFileDescriptors(); //获取其附带的文件描述符
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
}
...
int pid = -1;
FileDescriptor childPipeFd = null;//子进程,使用管道进行进程间通信,
FileDescriptor serverPipeFd = null;

parsedArgs = new ZygoteArguments(args); //创建Zygote参数对象
...
// 分裂出新进程
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);
//Forks a new VM instance
//创建一个新的VM实例对象,也就是我们平时说的沙盒隔离机制(sandbox)

try {
if (pid == 0) {
// in child
//当pid=0则说明是新创建的子进程中执行的,
//这时候ZygoteConnection类就会调用handleChildProc来启动这个子进程
zygoteServer.setForkChild();//设置标志位mIsForkChild为true
...
//处理子进程的创建
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
// 父进程流程
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
//处理父进程fork后清理工作,
handleParentProc(pid, descriptors, serverPipeFd);//如果pid>0,则为子进程设置进程号,否则就是创建失败
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}

ZygoteConnection.processOneCommand 方法:

  1. 为 fork 准备参数 parsedArgs
  2. 调用Zygote.forkAndSpecialize()方法来创建子进程
  3. fork之后,是子进程调用handleChildProc()方法执行的剩余工作,父进程返回null

这一块的逻辑和 ZygoteInit. forkSystemServer() 很相似,只是这里 fork 的是普通应用进程,调用的是 forkAndSpecialize() 方法。这里根据传递过来的参数创建zygoteArgs对象,并创建出VM虚拟机对象,最终调用handleChildProc()来创建子进程。

Zygote.forkAndSpecialize

fork 普通应用进程方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
int targetSdkVersion) {
//在fork新进程之前,停止Zygote的4个Daemon子线程的运行
ZygoteHooks.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
//调用native方法fork子进程
int pid = nativeForkAndSpecialize(
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
fdsToIgnore, startChildZygote, instructionSet, appDataDir);
// Enable tracing as soon as possible for the child process.
if (pid == 0) {
Zygote.disableExecuteOnly(targetSdkVersion);
Trace.setTracingEnabled(true, runtimeFlags);

// Note that this event ends at the end of handleChildProc,
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
}
//fork之后启动4个Deamon子线程
ZygoteHooks.postForkCommon();
return pid;
}

private static native int nativeForkAndSpecialize(int uid, int gid, int[] gids,
int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet,
String appDataDir);

Zygote.forkAndSpecialize方法:

  1. ZygoteHooks.preFork(),fork 之前停止Zyote的4个Daemon子线程的运行,初始化gc堆
  2. 调用native层方法nativeForkAndSpecialize 内部会调用fork()方法 fork 子进程,设置新进程的主线程id,重置gc堆性能数据,设置信号处理函数等功能
  3. ZygoteHooks.postForkCommon(),fork 之后启动4个Deamon子线程

Zygote.forkAndSpecialize方法执行完后,如果返回的pid等于0,表示处于子进程中,执行handleChildProc(),如果pid不等于0,则表示在zygote进程中,则调用handleParentProc()方法继续处理。

ZygoteConnection.handleChildProc

handleChildProc()方法:处理子进程fork以后的初始化设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
...
// 关闭Zygote的socket两端的连接
closeSocket();
...
if (parsedArgs.mNiceName != null) { //判断mNiceName不为空
Process.setArgV0(parsedArgs.mNiceName); //设置mNiceName为进程名
}

// End of the postFork event.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
if (parsedArgs.mInvokeWith != null) { //判断参数中mInvokeWith为空时,使用exec的系统调用开启进程
...
} else {
if (!isZygote) { //非zygote模式
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else { //zygote模式
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */); //zygoteInit的备选函数,同时初始化Zygote进程
}
}
}

其实这个方法内部实现很简单,就是子进程继承父进程,所以子进程里面有zygote的socket,所以首先要将其关闭,然后调用ZygoteInit.zygoteInit()方法进行相应的初始化,后面的逻辑和ZygoteInit.handleSystemServerProcess()方法后面逻辑类似。

ZygoteConnection.handleParentProc

handleChildProc()这一系列代码执行完毕后,会调用handleParentProc()对子进程创建状态进行判断,如果pid>0则说明创建成功,到此处我们子进程以及其相关线程就准备完毕了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//处理父进程fork后的清理工作
private void handleParentProc(int pid, FileDescriptor[] descriptors, FileDescriptor pipeFd) {
if (pid > 0) {
setChildPgid(pid);//为子进程设置进程号
}

if (descriptors != null) {
for (FileDescriptor fd: descriptors) {
IoUtils.closeQuietly(fd);
}
}

boolean usingWrapper = false;
if (pipeFd != null && pid > 0) {
int innerPid = -1;
try {

final int BYTES_REQUIRED = 4; // Bytes in an int.
StructPollfd fds[] = new StructPollfd[] {
new StructPollfd()
};

byte data[] = new byte[BYTES_REQUIRED];

int remainingSleepTime = WRAPPED_PID_TIMEOUT_MILLIS;
int dataIndex = 0;
long startTime = System.nanoTime();

while (dataIndex < data.length && remainingSleepTime > 0) {
fds[0].fd = pipeFd;
fds[0].events = (short) POLLIN;
fds[0].revents = 0;
fds[0].userData = null;

int res = android.system.Os.poll(fds, remainingSleepTime);
long endTime = System.nanoTime();
int elapsedTimeMs = (int)((endTime - startTime) / 1000000l);
remainingSleepTime = WRAPPED_PID_TIMEOUT_MILLIS - elapsedTimeMs;
...
if (dataIndex == data.length) {
DataInputStream is = new DataInputStream(new ByteArrayInputStream(data));
innerPid = is.readInt();
}
} catch (Exception ex) {
Log.w(TAG, "Error reading pid from wrapped process, child may have died", ex);
}

// Ensure that the pid reported by the wrapped process is either the
// child process that we forked, or a descendant of it.
if (innerPid > 0) {
int parentPid = innerPid;
while (parentPid > 0 && parentPid != pid) {
parentPid = Process.getParentPid(parentPid);
}
if (parentPid > 0) {
Log.i(TAG, "Wrapped process has pid " + innerPid);
pid = innerPid;
usingWrapper = true;
} else {
Log.w(TAG, "Wrapped process reported a pid that is not a child of "
+ "the process that we forked: childPid=" + pid
+ " innerPid=" + innerPid);
}
}
}
// 将创建的应用进程id返回给system_server进程
try {
mSocketOutStream.writeInt(pid);
mSocketOutStream.writeBoolean(usingWrapper);
} catch (IOException ex) {
throw new IllegalStateException("Error writing to command socket", ex);
}
}

至此,总结一下Zyogte进程在处理客户端请求创建普通进程消息,fork普通进程的流程:

  1. 调用runSelectLoop,循环读取消息
  2. 调用acceptCommandPeer()接收客户端连接请求,创建客户端连接对象ZygoteConnection
  3. 调用ZygoteConnection.processOneCommand()处理客户端请求,解析参数开始fork子进程
  4. 调用Zygote.forkAndSpecialize() fork子进程,创建虚拟机实例对象
  5. 调用handleChildProc() 处理子进程fork之后的初始化设置工作
  6. 调用ZygoteInit.zyogteInit()对子进程通用和native层的初始化,开启Binder线程池,使子进程可与其他进程通信
  7. 调用RuntimeInit.applicationInit()进行应用的初始化,
  8. 调用RuntimeInit.findStaticMain反射调用子进程静态main()方法

SystemServer

SystemServer是Android系统的核心之一,是Android基本服务的提供者,是Android系统运行的最基本需求,大部分Android提供的服务都运行在这个进程里。

Zygote通过fork后创建system_server进程,通过执行ZygoteInit.forkSystemServer()方法开始 fork,然后进入到ZygoteInithandleSystemServerProcess()方法完成fork之后的工作。

ZygoteInit.forkSystemServer

在Zygote进程执行过程ZygoteInit.main()方法中,会调用ZygoteInit.forkSystemServer()开始 fork,该方法会调用Zygote.forkSystemServer方法。

Zygote.forkSystemServer

真正的 fork 出子进程 system_server。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
//在fork新进程之前,停止Zygote的4个Daemon子线程的运行,等待并确保Zygote的单线程(用于fork效率)
//并等待这些线程的停止,初始化gc堆的工作
ZygoteHooks.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits,
permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true, runtimeFlags);
}
//在fork新进程之后,启动Zygote的4个Deamon线程,Java堆整理,引用队列,以及析构线程。
ZygoteHooks.postForkCommon();
return pid;
}

private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);

最后的 fork() 操作是通过 JNI 调用 native 层方法 nativeForkSystemServer() 完成的。

Zygote进程的4个Daemon子线程分别是ReferenceQueueDaemonFinalizerDaemonFinalizerWatchdogDaemonHeapTaskDaemon,此处称为Zygote的4个Daemon子线程。

Zygote.nativeForkSystemServer

文件位于 frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
jlong effective_capabilities) {
std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()),
fds_to_ignore(fds_to_close);

fds_to_close.push_back(gUsapPoolSocketFD);

if (gUsapPoolEventFD != -1) {
fds_to_close.push_back(gUsapPoolEventFD);
fds_to_ignore.push_back(gUsapPoolEventFD);
}
//fork 子进程
pid_t pid = ForkCommon(env, true,
fds_to_close,
fds_to_ignore);
if (pid == 0) {
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
permitted_capabilities, effective_capabilities,
MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
false, nullptr, nullptr);
} else if (pid > 0) {
// The zygote process checks whether the child process has died or not.
ALOGI("System server process %d has been created", pid);
gSystemServerPid = pid;
// There is a slight window that the system server process has crashed
// but it went unnoticed because we haven't published its pid yet. So
// we recheck here just to make sure that all is well.
int status;
if (waitpid(pid, &status, WNOHANG) == pid) {
ALOGE("System server process %d has died. Restarting Zygote!", pid);
RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
}

if (UsePerAppMemcg()) {
// Assign system_server to the correct memory cgroup.
// Not all devices mount memcg so check if it is mounted first
// to avoid unnecessarily printing errors and denials in the logs.
if (!SetTaskProfiles(pid, std::vector<std::string>{"SystemMemoryProcess"})) {
ALOGE("couldn't add process %d into system memcg group", pid);
}
}
}
return pid;
}

Zygote.forkSystemServer方法:

  1. ZygoteHooks.preFork(),fork 之前停止Zyote的4个Daemon子线程的运行,初始化gc堆
  2. 调用native层方法nativeForkSystemServer() 内部会调用fork()方法 fork 子进程,设置新进程的主线程id,重置gc堆性能数据,设置信号处理函数等功能
  3. ZygoteHooks.postForkCommon(),fork 之后启动4个Deamon子线程

fork() 函数是一次执行,两次返回。说的更严谨一点是 两个进程对一个程序的两次执行。当 pid == 0 时,说明现在处于子进程,当 pid > 0 时,说明处于父进程。子进程 (system_server) 中会返回执行 handleSystemServerProcess(parsedArgs) 的结果,父进程 (zygote) 会返回 null。

回到 ZygoteInit.forkSystemServer() 中执行完 Zygote.forkSystemServer 之后的逻辑处理:

1
2
3
4
5
6
7
8
9
10
11
/* For child process */
//pid == 0 表示子进程即system_server进程,继续剩余工作
if(pid == 0){
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
//父进程 (zygote) 会返回 null
return null;

回到 ZygoteInit.main() 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);

// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
// r == null 说明是在 zygote 进程
// r != null 说明是在 system_server 进程
if (r != null) {
r.run();
return;
}
}

// 循环等待处理客户端请求
caller = zygoteServer.runSelectLoop(abiList);

子进程 system_server 返回的是一个 Runnable,执行 r.run(),然后就直接 return 了。而父进程 zygote 返回的是 null,所以不满足 if 的判断条件,继续往下执行 runSelectLoop()

ZygoteInit.handleSystemServerProcess

子进程 (system_server) 继续完成系统服务进程的剩余工作,调用 handleSystemServerProcess 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
// set umask to 0077 so new files and directories will default to owner-only permissions.
// 通过umask设置创建文件的默认权限
Os.umask(S_IRWXG | S_IRWXO);
// 设置当前进程名为 "system_server"
if (parsedArgs.mNiceName != null) {
Process.setArgV0(parsedArgs.mNiceName);
}
// 获取环境变量SYSTEMSERVERCLASSPATH,环境变量位于init.environ.rc中
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
// 对环境变量SYSTEMSERVERCLASSPATH中的jar包进行dex优化
if (performSystemServerDexOpt(systemServerClasspath)) {
sCachedSystemServerClassLoader = null;
}
// prevents it.
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
try {
prepareSystemServerProfile(systemServerClasspath);
} catch (Exception e) {
Log.wtf(TAG, "Failed to set up system server profile", e);
}
}
}
//启动参数未包含"--invoke-with",invokeWith 一般为空,直接走else
if (parsedArgs.mInvokeWith != null) {
String[] args = parsedArgs.mRemainingArgs;
// If we have a non-null system server class path, we'll have to duplicate the
// existing arguments and append the classpath to it. ART will handle the classpath
// correctly when we exec a new process.
if (systemServerClasspath != null) {
String[] amendedArgs = new String[args.length + 2];
amendedArgs[0] = "-cp";
amendedArgs[1] = systemServerClasspath;
System.arraycopy(args, 0, amendedArgs, 2, args.length);
args = amendedArgs;
}

WrapperInit.execApplication(parsedArgs.mInvokeWith,
parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);

throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
} else {
// 创建类加载器,并赋给当前线程
createSystemServerClassLoader();
ClassLoader cl = sCachedSystemServerClassLoader;
if (cl != null) {
Thread.currentThread().setContextClassLoader(cl);
}

/*
* Pass the remaining arguments to SystemServer.
*/
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, cl);
}
}

ZygoteInit.handleSystemServerProcess方法:

  1. 设置进程名为 system_server,获取环境变量值,进行 dex 优化
  2. 创建类加载器,并设置给当前线程
  3. 调用 ZygoteInit.zygoteInit() 继续处理剩余参数
ZygoteInit.zygoteInit

ZygoteInit.zygoteInit() 继续处理剩余参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//通过zygote方法,在开启的时候,来调用main方法。
//如果native代码的nativeFinishInit()中通过Zygote合理的启动,将会与main()统一。
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
//日志重定向 System.out 和 System.err 到 Android log
RuntimeInit.redirectLogStreams();

// 一些通用初始化工作
RuntimeInit.commonInit();
// JNI调用,native 层zygote初始化
ZygoteInit.nativeZygoteInit();
// 调用入口函数
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

ZygoteInit.zygoteInit 方法:

  1. RuntimeInit.redirectLogStreams()日志重定向
  2. RuntimeInit.commonInit()进行一些通用的初始化
  3. ZygoteInit.nativeZygoteInit() 进行 native 层 zygote 初始化,创建Binder线程池
  4. 调用RuntimeInit.applicationInit()进行应用的初始化
ZygoteInit.nativeZygoteInit

文件位于 frameworks/base/core/jni/AndroidRuntime.cpp

1
2
3
4
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();//调用AndroidRuntime的zygoteInit
}

调用了onZygoteInit()函数,具体实现是在AppRuntime里面,AndroidRuntimeapp_processapp_main中有一个子类对象AppRuntime,位于frameworks/base/cmds/app_process/app_main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class AppRuntime : public AndroidRuntime
{
public:
AppRuntime(char* argBlockStart, const size_t argBlockLength)
: AndroidRuntime(argBlockStart, argBlockLength)
, mClass(NULL)
{
}
...
virtual void onZygoteInit()
{
//单例模式创建ProcessState全局变量
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();//启动新Binder线程池,设置线程名称
}
...
}

此处创建了一个ProcessState的对象,并调用了它的startThreadPool()函数,跟踪下去可以发现内部调用了spawnPooledThread的函数来创建线程并启动的。

ProcessState.cpp,位于frameworks/nativ/libs/binder/ProcessState.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class PoolThread : public Thread
{
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != NULL) {
return gProcess;
}
gProcess = new ProcessState("/dev/binder");
return gProcess;
}

void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);//创建线程并启动
}
}

//创建Binder线程池名称
String8 ProcessState::makeBinderThreadName() {
int32_t s = android_atomic_add(1, &mThreadPoolSeq);
pid_t pid = getpid();
String8 name;
name.appendFormat("Binder:%d_%X", pid, s);
return name;
}

void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {//判断线程已开启
String8 name = makeBinderThreadName();//创建Binder线程池名称
ALOGV("Spawning new pooled thread, name=%s\n", name.string());
sp<Thread> t = new PoolThread(isMain);//创建主线程
t->run(name.string());//执行线程
}
}
}

AppRuntime.onZygoteInit方法:

  1. 构造了进程的ProcessState全局变量,主要作用就是调用open()打开/dev/binder驱动设备,再利用mmap()映射内核的地址空间,将Binder驱动的fd赋值ProcessState对象中的变量mDriverFD,用于交互操作
  2. 启动 Binder 线程池,创建一个新的binder,使 system_server 进程和其他进程进行Binder通信
RuntimeInit.applicationInit

调用RuntimeInit.applicationInit方法进行应用的初始化,位于frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
// If the application calls System.exit(), terminate the process
// immediately without running any shutdown hooks. It is not possible to
// shutdown an Android application gracefully. Among other things, the
// Android runtime shutdown hooks close the Binder driver, which can cause
// leftover running threads to crash before the process actually exits.
//true 代表应用程序退出时,不调用AppRuntime.onExit(),否则会在退出前调用
nativeSetExitWithoutCleanup(true);

// We want to be fairly aggressive about heap utilization, to avoid
// holding on to a lot of memory that isn't needed.
// 设置虚拟机的内存利用率数值为0.75
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
// 解析参数
final Arguments args = new Arguments(argv);

// The end of of the RuntimeInit event (see #zygoteInit).
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

// Remaining arguments are passed to the start class's static main
//寻找 startClass 的静态main() 方法。这里的 startClass 是 com.android.server.SystemServer
return findStaticMain(args.startClass, args.startArgs, classLoader);
}

RuntimeInit 的 applicationInit 方法:

  1. 解析调用参数
  2. 调用findStaticMain()寻找startClass类的静态main()方法
RuntimeInit.findStaticMain

调用 findStaticMain 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//调用目标类className类的静态main(argv []) 方法。
//将各种失败异常转化为RuntimeExceptions,并且这些异常将会导致VM实例退出。
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;

try {
//找到指定的className类
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}

Method m;
try {
//找到className类的main()方法
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);
}

/*
* This throw gets caught in ZygoteInit.main(), which responds
* by invoking the exception's run() method. This arrangement
* clears up all the stack frames that were required in setting
* up the process.
*/
//返回一个 Runnable,在 Zygote 的 main() 方法中执行 run() 方法
//之前的版本是抛出一个异常,在 main() 方法中捕获,这样做的好处是清空栈帧,提高栈帧利用率
return new MethodAndArgsCaller(m, argv);
}

RuntimeInit.findStaticMain方法:

  1. 找到指定的className类
  2. 找到className类的main()方法
  3. 返回一个 Runnable,在 ZygoteInit 的 main() 方法中执行 run() 方法
MethodAndArgsCaller.run

最后调用 MethodAndArgsCallerrun() 方法,通过反射机制调用 SystemServer 类的 main()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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 {
// 根据传递过来的参数,可知此处通过反射机制调用的是SystemServer.main()方法
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);
}
}
}
}

MethodAndArgsCaller.run方法:

  1. 通过反射机制执行传递过来的参数 method 方法

zygote启动system_server进程的流程已经一步步的简要分析完了,最后通过反射机制调用SystemServer的静态函数main方法,进行类似与初始化的工作内容了。

注:为什么不直接在findStaticMain()方法中直接动态调用SystemServer的main()方法呢?

原因:是这种递归返回后再执行入口方法的方式会让SystemServer的main()方法看起来像是SystemServer的入口方法,而且,这样也会清除之前所有SystemServer相关设置过程中需要的堆栈帧

至此,总结一下 SystemServer 进程启动过程:

  1. Zygote进程调用ZygoteInit.forkSystemServer开始fork进程
  2. 调用 Zygote.forkSystemServerfork 出SystemServer进程
  3. 调用ZygoteInit.handleSystemServerProcess处理SystemServer进程fork后的剩余工作
  4. 调用ZygoteInit.zygoteInit() 进行通用和native层的初始化,并启动Binder线程池,使system_server进程可与其他进程进程通信
  5. 调用RuntimeInit.applicationInit进行应用的初始化
  6. 调用RuntimeInit.findStaticMain反射进入SystemServer类的静态函数main()方法
SystemServer.main

SystemServer类的静态函数main方法,位于 frameworks/base/services/java/com/android/server/SystemServer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
new SystemServer().run(); //调用 run 方法
}

public SystemServer() {
// Check for factory test mode.
mFactoryTestMode = FactoryTest.getMode();
//记录进程开始信息
// one for the password screen, second for the actual boot.
mStartCount = SystemProperties.getInt(SYSPROP_START_COUNT, 0) + 1;
mRuntimeStartElapsedTime = SystemClock.elapsedRealtime();
mRuntimeStartUptime = SystemClock.uptimeMillis();
mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
}

SystemServer.run 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
private void run() {
try {
traceBeginAndSlog("InitBeforeStartServices");

// Record the process start information in sys props.
//在sys props中记录进程启动信息。
SystemProperties.set(SYSPROP_START_COUNT, String.valueOf(mStartCount));
SystemProperties.set(SYSPROP_START_ELAPSED, String.valueOf(mRuntimeStartElapsedTime));
SystemProperties.set(SYSPROP_START_UPTIME, String.valueOf(mRuntimeStartUptime));

EventLog.writeEvent(EventLogTags.SYSTEM_SERVER_START,
mStartCount, mRuntimeStartUptime, mRuntimeStartElapsedTime);

// 计算时间 如果当前系统时间比1970年更早,就设置当前系统时间为1970年
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
// Default the timezone property to GMT if not set.
//如果未设置时区属性,则将其默认为GMT。
String timezoneProperty = SystemProperties.get("persist.sys.timezone");
if (timezoneProperty == null || timezoneProperty.isEmpty()) {
Slog.w(TAG, "Timezone not set; setting to GMT.");
SystemProperties.set("persist.sys.timezone", "GMT");
}
// NOTE: Most changes made here will need an equivalent change to
// core/jni/AndroidRuntime.cpp
// 如果没有设置 语言,则设置当地的语言
if (!SystemProperties.get("persist.sys.language").isEmpty()) {
final String languageTag = Locale.getDefault().toLanguageTag();

SystemProperties.set("persist.sys.locale", languageTag);
SystemProperties.set("persist.sys.language", "");
SystemProperties.set("persist.sys.country", "");
SystemProperties.set("persist.sys.localevar", "");
}

// The system server should never make non-oneway calls
//设置系统服务器不应进行非单向调用
Binder.setWarnOnBlocking(true);
// The system server should always load safe labels
//系统服务器应始终加载安全标签
PackageItemInfo.forceSafeLabels();

// Default to FULL within the system server.
SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL;

// Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized
//在初始化设置provider之前,停用SQLiteCompatibilityWalFlags
SQLiteCompatibilityWalFlags.init(null);

// Here we go!
Slog.i(TAG, "Entered the Android system server!");
int uptimeMillis = (int) SystemClock.elapsedRealtime();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
if (!mRuntimeRestart) {
MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
}

// 设置虚拟机库文件路径,5.0以后是libart.so
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

// Mmmmmm... more memory!
// 清除VM内存增长上限,由于启动过程需要较多的虚拟机内存空间
VMRuntime.getRuntime().clearGrowthLimit();

// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
// 设置内存可能有效使用率为0.8
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

// Some devices rely on runtime fingerprint generation, so make sure
// we've defined it before booting further.
// 针对部分设备依赖运行时就产生指纹信息,因此需要在开机完成前已经定义
Build.ensureFingerprintProperty();

// Within the system server, it is an error to access Environment paths without
// explicitly specifying a user.
// 设置访问环境变量的条件,即需要明确指定用户
Environment.setUserRequired(true);

// Within the system server, any incoming Bundles should be defused
// to avoid throwing BadParcelableException.
BaseBundle.setShouldDefuse(true);

// Within the system server, when parceling exceptions, include the stack trace
Parcel.setStackTraceParceling(true);

// Ensure binder calls into the system always run at foreground priority.
//确保当前系统进程的binder调用,总是运行在前台优先级(foreground)
BinderInternal.disableBackgroundScheduling(true);

// Increase the number of binder threads in system_server
BinderInternal.setMaxThreads(sMaxBinderThreads);

// Prepare the main looper thread (this thread).
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
//创建主线程Looper,就在当前线程运行
Looper.prepareMainLooper();
Looper.getMainLooper().setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

// Initialize native services.
// 加载“android_servers.so”库,该库包含源码在frameworks/base/services/目录下
System.loadLibrary("android_servers");

// Debug builds - allow heap profiling.
//调试模式初始化堆分析
if (Build.IS_DEBUGGABLE) {
initZygoteChildHeapProfiling();
}

// Check whether we failed to shut down last time we tried.
// This call may not return.
//检查上次关键是否失败了,可能没有返回值
performPendingShutdown();

// Initialize the system context.
// 初始化系统上下文
createSystemContext();

// Create the system service manager.
// 创建SystemServiceManager 用于后面的binder机制
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
//添加注册到LocalServices
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
//为初始化任务准备线程池
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}

// Start services.
//启动各种系统服务
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();//启动引导服务AMS、PackageManagerService等
startCoreServices();// 启动核心服务BatteryService、UsageStatsService等
startOtherServices();// 启动其他服务WindowManagerService、InputManagerService等
SystemServerInitThreadPool.shutdown();//关闭系统服务初始化使用的线程池
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
StrictMode.initVmDefaults(null);
...
// Loop forever.
// 主进程的looper开启循环处理消息
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}

SystemServer 进程执行过程,调用SystemServer.main方法:

  1. 调用createSystemContext()来创建ActivityThread对象和系统上下文
  2. 创建SystemServiceManager
  3. 启动各种系统服务并进行生命周期管理
  4. 调用Looper.loop(),进入处理消息的循环
SystemServer.createSystemContext
1
2
3
4
5
6
7
8
9
private void createSystemContext() {
//创建system_server进程的上下文信息
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
SystemServer.startBootstrapServices
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
private void startBootstrapServices() {
...
// Wait for installd to finish starting up so that it has a chance to
// create critical directories such as /data/user with the appropriate
// permissions. We need this to complete before we initialize other services.
Installer installer = mSystemServiceManager.startService(Installer.class);
// In some cases after launching an app we need to access device identifiers,
// therefore register the device identifier policy before the activity manager.
mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
// Uri Grants Manager.
mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class);
// Activity manager runs the show.
// 创建启动ATMS(ActivityTaskManagerService)
//是通过"ssm"反射创建"atm"的静态内部类Lifecycle对象,并通过该对象的getService()获取到"atm"实例对象
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
// 创建启动AMS(ActivityManagerService)
//调用"ams"的静态内部类Lifecycle的静态方法"startService"函数,把"ssm"和"atm"传递过去
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);//内部还是使用"ssm"来创建的"ams"

mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mWindowManagerGlobalLock = atm.getGlobalLock();
// Power manager needs to be started early because other services need it.
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
...
}

ActivityManagerService是如何启动的

ActivityManagerService是在startBootstrapServices函数中开启的服务,主要涉及到了三个类,ActivityTaskManagerServiceActivityManagerServiceSystemServiceManager,分两步:

  1. 先通过mSystemServiceManager.startService(class)反射调用ATMS静态内部类Lifecycle的构造方法来创建ATMS对象,通过Lifecycle的getService()得到ATMS对象;
  2. 通过调用AMS的静态内部类Lifecycle方法ActivityManagerService.Lifecycle.startService(ssm,atm)传入mSystemServiceManager和atm对象,内部还是通过mSystemServiceManager.startService(class)反射调用AMS静态内部类Lifecycle的构造方法创建AMS对象,在调用mSystemServiceManager.startService(service)启动service时,会调用service的onStart()方法中,在该方法中调用AMS对象的start()方法。

其中ATMS和AMS中有着相似的设计,都是通过静态内部类Lifecycle来创建和获取本类对象,即当前系统服务的。

SystemServer.startCoreServices
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void startCoreServices() {
// Tracks the battery level. Requires LightService.
mSystemServiceManager.startService(BatteryService.class);

// Tracks application usage stats.
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));

// Tracks whether the updatable WebView is in a ready state and watches for update installs.
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
traceBeginAndSlog("StartWebViewUpdateService");
mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
traceEnd();
}
...
}
SystemServer.startOtherServices
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
private void startOtherServices() {
final Context context = mSystemContext;
VibratorService vibrator = null;
DynamicSystemService dynamicSystem = null;
IStorageManager storageManager = null;
NetworkManagementService networkManagement = null;
IpSecService ipSecService = null;
NetworkStatsService networkStats = null;
NetworkPolicyManagerService networkPolicy = null;
ConnectivityService connectivity = null;
NsdService serviceDiscovery = null;
WindowManagerService wm = null;
SerialService serial = null;
NetworkTimeUpdateService networkTimeUpdater = null;
InputManagerService inputManager = null;
TelephonyRegistry telephonyRegistry = null;
ConsumerIrService consumerIr = null;
MmsServiceBroker mmsService = null;
HardwarePropertiesManagerService hardwarePropertiesService = null;

boolean disableSystemTextClassifier = SystemProperties.getBoolean(
"config.disable_systemtextclassifier", false);
boolean disableNetworkTime = SystemProperties.getBoolean("config.disable_networktime",
false);
boolean disableCameraService = SystemProperties.getBoolean("config.disable_cameraservice",
false);
...
try {
final String SECONDARY_ZYGOTE_PRELOAD = "SecondaryZygotePreload";
mZygotePreload = SystemServerInitThreadPool.get().submit(() -> {
try {
Slog.i(TAG, SECONDARY_ZYGOTE_PRELOAD);
TimingsTraceLog traceLog = new TimingsTraceLog(
SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
traceLog.traceBegin(SECONDARY_ZYGOTE_PRELOAD);
if (!Process.ZYGOTE_PROCESS.preloadDefault(Build.SUPPORTED_32_BIT_ABIS[0])) {
Slog.e(TAG, "Unable to preload default resources");
}
traceLog.traceEnd();
} catch (Exception ex) {
Slog.e(TAG, "Exception preloading default resources", ex);
}
}, SECONDARY_ZYGOTE_PRELOAD);

ServiceManager.addService("sec_key_att_app_id_provider",
new KeyAttestationApplicationIdProviderService(context));

mSystemServiceManager.startService(KeyChainSystemService.class);

ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
...
}

Launcher

Launcher是在ActivityManagerService里面启动的,而ActivityManagerService是SystemServer进程执行startBootstrapServices()函数开启的。

SystemServer.startOtherServices

SystemServer在开启其他服务时,在执行startOtherServices()方法中调用 mActivityManagerService.systemReady()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void startOtherServices() {
...
// 调用 AMS 的 systemReady 方法
mActivityManagerService.systemReady(() -> {
Slog.i(TAG, "Making services ready");
traceBeginAndSlog("StartActivityManagerReadyPhase");
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
try {
mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
...
}, BOOT_TIMINGS_TRACE_LOG);
}
ActivityManagerService. systemReady

位于frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
...
final int currentUserId = mUserController.getCurrentUserId();
mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
Integer.toString(currentUserId), currentUserId);
mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
Integer.toString(currentUserId), currentUserId);
mSystemServiceManager.startUser(currentUserId);

synchronized (this) {
...
// Start up initial activity.
// 启动初始activity
mBooting = true;
if (UserManager.isSplitSystemUser() &&
Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
try {
AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
UserHandle.USER_SYSTEM);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
//启动桌面 Home 应用
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
...
}
ActivityTaskManagerInternal.startHomeOnAllDisplays

ActivityTaskManagerInternal是Activity任务管理器本地系统服务接口,是一个抽象类,具体实现是

ActivityTaskManagerService.LocalService

1
2
3
4
5
6
7
8
9
10
final class LocalService extends ActivityTaskManagerInternal {
...
@Override
public boolean startHomeOnAllDisplays(int userId, String reason) {
synchronized (mGlobalLock) {
return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
}
}
...
}
RootActivityContainer.startHomeOnAllDisplays
1
2
3
4
5
6
7
8
boolean startHomeOnAllDisplays(int userId, String reason) {
boolean homeStarted = false;
for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
final int displayId = mActivityDisplays.get(i).mDisplayId;
homeStarted |= startHomeOnDisplay(userId, reason, displayId);
}
return homeStarted;
}
RootActivityContainer.startHomeOnDisplay
1
2
3
4
boolean startHomeOnDisplay(int userId, String reason, int displayId) {
return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
false /* fromHomeKey */);
}
RootActivityContainer.startHomeOnDisplay
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//启动HomeActivity 
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {
// Fallback to top focused display if the displayId is invalid.
if (displayId == INVALID_DISPLAY) {
displayId = getTopDisplayFocusedStack().mDisplayId;
}

Intent homeIntent = null;
ActivityInfo aInfo = null;
if (displayId == DEFAULT_DISPLAY) {
//获取homeIntent
homeIntent = mService.getHomeIntent();
aInfo = resolveHomeActivity(userId, homeIntent);
} else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
aInfo = info.first;
homeIntent = info.second;
}
if (aInfo == null || homeIntent == null) {
return false;
}

if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
return false;
}

// Updates the home component of the intent.
homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
// Updates the extra information of the intent.
if (fromHomeKey) {
homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
}
// Update the reason for ANR debugging to verify if the user activity is the one that
// actually launched.
final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
aInfo.applicationInfo.uid) + ":" + displayId;
// 启动桌面 Activity
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
displayId);
return true;
}
ActivityTaskManagerService.getHomeIntent
1
2
3
4
5
6
7
8
9
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
ActivityStartController.startHomeActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
if (!ActivityRecord.isResolverActivity(aInfo.name)) {
// The resolver activity shouldn't be put in home stack because when the foreground is
// standard type activity, the resolver activity should be put on the top of current
// foreground instead of bring home stack to front.
options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
}
options.setLaunchDisplayId(displayId);
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
.execute();
mLastHomeActivityStartRecord = tmpOutRecord[0];
final ActivityDisplay display =
mService.mRootActivityContainer.getActivityDisplay(displayId);
final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
if (homeStack != null && homeStack.mInResumeTopActivity) {
// If we are in resume section already, home activity will be initialized, but not
// resumed (to avoid recursive resume) and will stay that way until something pokes it
// again. We need to schedule another resume.
mSupervisor.scheduleResumeTopActivities();
}
}
ActivityStarter.execute
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int execute() {
try {
// TODO(b/64750076): Look into passing request directly to these methods to allow
// for transactional diffs and preprocessing.
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
} else {
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
}
} finally {
onExecutionComplete();
}
}
ActivityStarter.startActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {

if (TextUtils.isEmpty(reason)) {
throw new IllegalArgumentException("Need to specify a reason.");
}
mLastStartReason = reason;
mLastStartActivityTimeMs = System.currentTimeMillis();
mLastStartActivityRecord[0] = null;

mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
allowBackgroundActivityStart);

if (outActivity != null) {
// mLastStartActivityRecord[0] is set in the call to startActivity above.
outActivity[0] = mLastStartActivityRecord[0];
}

return getExternalResult(mLastStartActivityResult);
}

总结

最后,从整体上来看 Android 系统的启动流程:

  1. 按下电源,固化在 ROM 中预定位置的 Bootloader 将会被加载到内存中
  2. Bootloader 初始化完软硬件环境后将 Linux 内核启动起来
  3. Linux 内核启动时会做设置缓存、被保护存储器、计划列表和加载驱动等一些列操作,内核启动完成后会启动 init 进程
  4. init 进程会初始化并启动属性服务,并且解析并执行所有 init.rc 文件
  5. init 通过执行特定的 init.rc 文件启动 servermanager 进程,servermanager 被启动后会向 Binder 驱动发送命令让自己成为守护进程并管理所有上下文
  6. init 通过解析 init.rc 文件启动 zygote 进程
  7. zygote 进程启动的过程会创建 DVM 并为其注册 JNI 函数,然后创建服务端 Socket、启动 system_server 进程
  8. 启动 system_server 进程的过程会创建 Binder 线程池使其具有 IPC 能力,然后启动 AMS 等各种系统服务
  9. AMS 启动 Launcher,Launcher 被启动后会将已安装应用的图标显示在界面上

引用文章:

Android启动流程之bootloader引导与Linux启动

Android10.0系统启动流程(三):Zygote

Android系统启动-综述