安卓的启动流程
安卓的启动流程大致分为几个阶段。
1、BootRom:启动电源以及系统启动。
当电源按下时,引导芯片代码从预定义的地方(固化在ROM中)开始执行。加载引导程序BootLoader到RAM,然后执行。
2、引导程序Bootloader
引导程序BootLoader是在android操作系统开始运行前的一个小程序,他的主要作用是把系统OS拉起来并运行。
3、Linux kernel启动
当内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置时,它首先在系统文件中寻找init.rc文件,并启动init进程。
4、init进程启动
初始化和启动属性服务,并且启动Zygote进程。
5、Zygote进程启动
创建Java虚拟机并为Java虚拟机注册JNI方法,创建服务器端Socket,启动SystemServer进程。
6、systemserver进程启动
启动Binder线程池和SystemServiceManager,并且启动各种系统服务。
7、Launcher进程启动
被SystemServer进程启动的AMS会启动Launcher,Launcher启动后会将已安装应用的快捷图标显示到界面上。
下面介绍安卓世界的启动流程即从init进程开始讲起。
init进程的启动
首先Bootloader引导程序启动完Linux内核后,会加载各种驱动和数据结构,当有了驱动以后,开始启动Android系统,同时会加载用户级别的第一个进程init。启动该进程首先进入到system/core/init/目录下的main.cpp文件中,执行main方法。
51 int main(int argc, char** argv) {
52 #if __has_feature(address_sanitizer)
53 __asan_set_error_report_callback(AsanReportCallback);
54 #endif
55 // Boost prio which will be restored later
56 setpriority(PRIO_PROCESS, 0, -20);
57 if (!strcmp(basename(argv[0]), "ueventd")) {
58 return ueventd_main(argc, argv);
59 }
60
61 if (argc > 1) {
62 if (!strcmp(argv[1], "subcontext")) {
63 android::base::InitLogging(argv, &android::base::KernelLogger);
64 const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
65
66 return SubcontextMain(argc, argv, &function_map);
67 }
68
69 if (!strcmp(argv[1], "selinux_setup")) {
70 return SetupSelinux(argv);
71 }
72
73 if (!strcmp(argv[1], "second_stage")) {
74 return SecondStageMain(argc, argv);
75 }
76 }
77
78 return FirstStageMain(argc, argv);
79 }
80
FirstStageMain
可以在kernel中看到, 启动时并没有带任何参数,所在最先执行的就是FirstStageMain。这个函数主要功能就是创建目录、挂载分区等,最后进入第二次运行init,可以看到这次是带了selinux_setup参数;FirstStageMain函数实现在:system/core/init/first_stage_init.cpp。
int FirstStageMain(int argc, char** argv) {
...
353 if (!DoFirstStageMount(!created_devices)) {
354 LOG(FATAL) << "Failed to mount required partitions early ...";
355 }
...
372 const char* path = "/system/bin/init";
373 const char* args[] = {path, "selinux_setup", nullptr};
374 auto fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC);
375 dup2(fd, STDOUT_FILENO);
376 dup2(fd, STDERR_FILENO);
377 close(fd);
378 execv(path, const_cast<char**>(args));
379
380 // execv() only returns if an error happened, in which case we
381 // panic and never fall through this conditional.
382 PLOG(FATAL) << "execv(\"" << path << "\") failed";
SetupSelinux
我们根据上面main函数的代码,参数为selinux_setup的时候,执行SetupSelinux函数,
第二步:进入SetupSelinux(argv),这个函数实现在system/core/init/selinux.cpp中。主要就是启动SElinux, 然后现再成功的进入下一步,根据参数可以看到, 接下来进入SecondStageMain
714 int SetupSelinux(char** argv) {
724 MountMissingSystemPartitions();
725
726 SelinuxSetupKernelLogging();
727
728 LOG(INFO) << "Opening SELinux policy";
729
730 // Read the policy before potentially killing snapuserd.
731 std::string policy;
732 ReadPolicy(&policy);
...
742 LoadSelinuxPolicy(policy);
762 const char* path = "/system/bin/init";
763 const char* args[] = {path, "second_stage", nullptr};
764 execv(path, const_cast<char**>(args));
765
SecondStageMain
函数实现是在system/core/init/init.cpp中
728 int SecondStageMain(int argc, char** argv) {
PropertyInit();
...
800 // Now set up SELinux for second stage.
801 SelinuxSetupKernelLogging();
802 SelabelInitialize();
803 SelinuxRestoreContext();
...
StartPropertyService(&property_fd);
...
837 ActionManager& am = ActionManager::GetInstance();
838 ServiceList& sm = ServiceList::GetInstance();
839
840 LoadBootScripts(am, sm);
...
am.QueueEventTrigger("early-init");
...
am.QueueEventTrigger("init");
// Don't mount filesystems or start core system services in charger mode.
std::string bootmode = GetProperty("ro.bootmode", "");
if (bootmode == "charger") {
am.QueueEventTrigger("charger");
} else {
am.QueueEventTrigger("late-init");
}
可以该阶段主要做的事情是初始化property系统,解析init.rc。然后再执行early init action,执行init action, 执行 early-boot and boot actions。
其中/init.rc是主要的.rc文件,由init可执行文件在开始执行时加载。它负责系统的初始设置。
在加载主目录/init.rc后,init立即加载包含在/{system,vendor,odm}/etc/init/目录中的所有文件。
303 static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
304 Parser parser = CreateParser(action_manager, service_list);
305
306 std::string bootscript = GetProperty("ro.boot.init_rc", "");
307 if (bootscript.empty()) {
308 parser.ParseConfig("/system/etc/init/hw/init.rc");
309 if (!parser.ParseConfig("/system/etc/init")) {
310 late_import_paths.emplace_back("/system/etc/init");
311 }
312 // late_import is available only in Q and earlier release. As we don't
313 // have system_ext in those versions, skip late_import for system_ext.
314 parser.ParseConfig("/system_ext/etc/init");
315 if (!parser.ParseConfig("/vendor/etc/init")) {
316 late_import_paths.emplace_back("/vendor/etc/init");
317 }
318 if (!parser.ParseConfig("/odm/etc/init")) {
319 late_import_paths.emplace_back("/odm/etc/init");
320 }
321 if (!parser.ParseConfig("/product/etc/init")) {
322 late_import_paths.emplace_back("/product/etc/init");
323 }
324 } else {
325 parser.ParseConfig(bootscript);
326 }
327 }
328
我们先看init.rc文件的具体内容。
7 import /init.environ.rc
8 import /system/etc/init/hw/init.usb.rc
9 import /init.${ro.hardware}.rc
10 import /vendor/etc/init/hw/init.${ro.hardware}.rc
11 import /system/etc/init/hw/init.usb.configfs.rc
12 import /system/etc/init/hw/init.${ro.zygote}.rc
on early-init
...
119 on init
...
418 # This allows the ledtrig-transient properties to be created here so
419 # that they can be chown'd to system:system later on boot
420 write /sys/class/leds/vibrator/trigger "transient"
421
422 # This is used by Bionic to select optimized routines.
423 write /dev/cpu_variant:${ro.bionic.arch} ${ro.bionic.cpu_variant}
424 chmod 0444 /dev/cpu_variant:${ro.bionic.arch}
425 write /dev/cpu_variant:${ro.bionic.2nd_arch} ${ro.bionic.2nd_cpu_variant}
426 chmod 0444 /dev/cpu_variant:${ro.bionic.2nd_arch}
427
428 # Allow system processes to read / write power state.
429 chown system system /sys/power/state
430 chown system system /sys/power/wakeup_count
431 chmod 0660 /sys/power/state
438 # Start logd before any other services run to ensure we capture all of their logs.
439 start logd
440 # Start lmkd before any other services run so that it can register them
441 chown root system /sys/module/lowmemorykiller/parameters/adj
442 chmod 0664 /sys/module/lowmemorykiller/parameters/adj
443 chown root system /sys/module/lowmemorykiller/parameters/minfree
444 chmod 0664 /sys/module/lowmemorykiller/parameters/minfree
445 start lmkd
446
447 # Start essential services.
448 start servicemanager
449 start hwservicemanager
450 start vndservicemanager
...
467 # Mount filesystems and start core system services.
468 on late-init
469 trigger early-fs
...
475 trigger fs
476 trigger post-fs
...
495 # Now we can start zygote for devices with file based encryption
496 trigger zygote-start
497
498 # Remove a file to wake up anything waiting for firmware.
499 trigger firmware_mounts_complete
500
501 trigger early-boot
502 trigger boot
946 # It is recommended to put unnecessary data/ initialization from post-fs-data
947 # to start-zygote in device's init.rc to unblock zygote start.
948 on zygote-start && property:ro.crypto.state=unencrypted
949 wait_for_prop odsign.verification.done 1
950 # A/B update verifier that marks a successful boot.
951 exec_start update_verifier_nonencrypted
952 start statsd
953 start netd
954 start zygote
955 start zygote_secondary
956
957 on zygote-start && property:ro.crypto.state=unsupported
958 wait_for_prop odsign.verification.done 1
959 # A/B update verifier that marks a successful boot.
960 exec_start update_verifier_nonencrypted
961 start statsd
962 start netd
963 start zygote
964 start zygote_secondary
965
966 on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
967 wait_for_prop odsign.verification.done 1
968 # A/B update verifier that marks a successful boot.
969 exec_start update_verifier_nonencrypted
970 start statsd
971 start netd
972 start zygote
973 start zygote_secondary
然后我们看是怎么解析init.rc文件的。给parse 变量进行赋值,创建了三个parser,分别是对service ,on,import进行parse。
首先*.rc 脚本中所有 service关键字定义的服务将会添加到 service_list 列表中。
*.rc 脚本中所有 on 关键开头的项将会被会添加到 action_list 列表中。
282 Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
283 Parser parser;
284
285 parser.AddSectionParser("service", std::make_unique<ServiceParser>(
286 &service_list, GetSubcontext(), std::nullopt));
287 parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, GetSubcontext()));
288 parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
289
290 return parser;
291 }
35 void Parser::AddSectionParser(const std::string& name, std::unique_ptr<SectionParser> parser) {
36 section_parsers_[name] = std::move(parser);
37 }
解析的关键函数是parseData函数,
next_token函数用就是寻找单词结束或者行结束标志,如果是单词结束标志就将单词push到args中,如果是行结束标志,则根据第一个单词来判断是否是一个section,section的标志只有三个"on",“service”,“import”,如果是"section",会根据关键字的不同会调用不同的 parser去解析(多态) 通过相应的ParseSection()函数来处理一个section,,action 使用 ActionParser,而 service 使用 ServiceParser 解析,该部分定义在LoadBootScrip()函数的第一行,parser.AddSectionParser()方法为parser的map成员section_parsers_创建了三个SectionParser,分别用来解析service,on,import的section;否则把这一行继续作为前“section”所属的行来处理
ParseSection()被用来解析一个新的section,ParseLineSection()被用来解析该section下的命令行
43 void Parser::ParseData(const std::string& filename, std::string* data) {
44 data->push_back('\n');
45 data->push_back('\0');
`...
73 for (;;) {
74 switch (next_token(&state)) {
75 case T_EOF:
76 end_section();
77
78 for (const auto& [section_name, section_parser] : section_parsers_) {
79 section_parser->EndFile();
80 }
81
82 return;
83 case T_NEWLINE: {
84 state.line++;
85 if (args.empty()) break;
86 // If we have a line matching a prefix we recognize, call its callback and unset any
87 // current section parsers. This is meant for /sys/ and /dev/ line entries for
88 // uevent.
89 auto line_callback = std::find_if(
90 line_callbacks_.begin(), line_callbacks_.end(),
91 [&args](const auto& c) { return android::base::StartsWith(args[0], c.first); });
92 if (line_callback != line_callbacks_.end()) {
93 end_section();
94
95 if (auto result = line_callback->second(std::move(args)); !result.ok()) {
96 parse_error_count_++;
97 LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
98 }
99 } else if (section_parsers_.count(args[0])) {
100 end_section();
101 section_parser = section_parsers_[args[0]].get();
102 section_start_line = state.line;
103 if (auto result =
104 section_parser->ParseSection(std::move(args), filename, state.line);
105 !result.ok()) {
106 parse_error_count_++;
107 LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
108 section_parser = nullptr;
109 bad_section_found = true;
110 }
111 } else if (section_parser) {
112 if (auto result = section_parser->ParseLineSection(std::move(args), state.line);
113 !result.ok()) {
114 parse_error_count_++;
115 LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
116 }
117 } else if (!bad_section_found) {
118 parse_error_count_++;
119 LOG(ERROR) << filename << ": " << state.line
120 << ": Invalid section keyword found";
121 }
122 args.clear();
123 break;
124 }
125 case T_TEXT:
126 args.emplace_back(state.text);
127 break;
128 }
129 }
130 }
解析完了init.rc文件以后,调用am.QueueEventTrigger(‘init-early’)意为early-init时间已经到来,可以执行triggle只为early-init的action了。
init最终会进入了无限循环的监听状态,可以看到这里面一个核心函数就是 am.ExecuteOneCommand();之前说的QueueEventTrigger(“early-init”)把early-init加入到event_queue_的队列中,ExecuteOneCommand()一开始就遍历之前解析的action向量表。当一个 action 对象所有的 command 均执行完毕后,再执行下一个action。
zygote 启动
ini进程启动进程中,最关键的是启动zygote
我们在init.rc文件中可以看到出zygote的启动流程是,init.cpp中配置了late-init事件,然后在执行late-init事件的时候,触发了zygote-start事件,然后在zygote-start的时候,执行了start zygote以及start zygote_secondary启动了zygote进程。
zygote进程对应的bin文件是/system/bin/app_process64这个可执行文件,对应的源码路径为frameworks/base/cmds/app_process/app_main.cpp,所以会进到它的main函数中。
我们总结一下,zygote的主要行为是
创建虚拟机–startVM
注册JNI函数–startReg
通过JNI知道Java层的com.android.internal.os.ZygoteInit 类,调用main 函数,进入java 世界。
ZygoteInit.java的路径: frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
该类中会调用ZygoteInit.startSystemServer去启动systemserver。
/frameworks/base/cmds/app_process/app_main.cpp
Zygote总结:
解析init.zygote.rc中的参数,创建AppRuntime并调用AppRuntime.start()方法
调用AndroidRuntime的startVM()方法创建虚拟机,再调用startReg()注册JNI函数
通过JNI方式调用ZygoteInit.main(),第一次进入Java世界
registerZygoteSocket()建立socket通道,zygote作为通信的服务端,用于响应客户端请求
preload()预加载通用类、drawable和color资源、openGL以及共享库以及WebView,用于提高app启动效率
通过startSystemServer(),fork得力帮手system_server进程,也是Java Framework的运行载体(下面讲到system server再详细讲解)
调用runSelectLoop(),随时待命,当接收到请求创建新进程请求时立即唤醒并执行相应工作
systemserver进程的启动
system server进程是由zygote进程fork出来的,在上面的ZygoteInit.main方法中调用forksystemserver方法,新创建出来的system_server进程便进入handleSystemServerProcess()方法,然后执行ZygoteInit.zygoteInit通过反射获取SystemServer类的main方法参数
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
888 public static void main(String[] argv) {
...
975 if (startSystemServer) {
976 Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
977
978 // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
979 // child (system_server) process.
980 if (r != null) {
981 r.run();
982 return;
983 }
984 }
startBootstrapServices
启动系统启动所需的一小部分关键服务,这些服务具有复杂的相互依赖关系,所以会在此将他们全部初始化。
startCoreServices
启动一些在startBootstrapServices中没有依赖的一部分服务,具体服务如下:
SystemConfigService、BatteryService、UsageStatsService、CachedDeviceStateService、BinderCallsStatsService、LooperStatsService、RollbackManagerService、NativeTombstoneManagerService、BugreportManagerService、GpuService
startOtherServices
启动一些在startBootstrapServices和startCoreServices没有启动的服务,由于服务过多,在此只展示一些我们熟悉的服务,所有服务请通过阅读源码查看。
WindowManagerService、InputManagerService、VibratorManagerService、AlarmManagerService、BluetoothService、StorageManagerService、UiModeManagerService、StatusBarManagerService、VpnManagerService、NotificationManagerService、LocationManagerService、ConnectivityManager
最终也会启动SystemUI的Service。
SystemServer主要负责一下几部分内容:
启动相关的信息的存储。
设置Binder thread相关的配置。
构建ActivityThread以及系统上下文。
通过SystemServiceManager去启动系统中的各种Service。
使Main Looper进入循环,等待消息处理任务。