init的service 启动顺序
inti.rc 各阶段的执行顺序,从 SecondStageMain 方法开始分析
/android-14.0.0_r21/xref/system/core/init/init.cpp
912 int SecondStageMain(int argc, char** argv) {
913 if (REBOOT_BOOTLOADER_ON_PANIC) {
914 InstallRebootSignalHandlers();
915 }
。。。。
// 创建 ActionManager 对象
1032 ActionManager& am = ActionManager::GetInstance();
1033 ServiceList& sm = ServiceList::GetInstance();
1034
// 1)首先执行 LoadBootScripts 方法
1035 LoadBootScripts(am, sm);
。。。
// 2) 执行 QueueBuiltinAction 方法
1053 am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups");
1054 am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");
1055 am.QueueBuiltinAction(TestPerfEventSelinuxAction, "TestPerfEventSelinux");
1056 am.QueueBuiltinAction(ConnectEarlyStageSnapuserdAction, "ConnectEarlyStageSnapuserd");
// 3)执行 QueueEventTrigger 方法
1057 am.QueueEventTrigger("early-init");
1058
1059 // Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...
1060 am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
1061 // ... so that we can start queuing up actions that require stuff from /dev.
1062 am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits");
1063 Keychords keychords;
1064 am.QueueBuiltinAction(
1065 [&epoll, &keychords](const BuiltinArguments& args) -> Result<void> {
1066 for (const auto& svc : ServiceList::GetInstance()) {
1067 keychords.Register(svc->keycodes());
1068 }
1069 keychords.Start(&epoll, HandleKeychord);
1070 return {};
1071 },
1072 "KeychordInit");
1073
1074 // Trigger all the boot actions to get us started.
1075 am.QueueEventTrigger("init");
1076
1077 // Don't mount filesystems or start core system services in charger mode.
1078 std::string bootmode = GetProperty("ro.bootmode", "");
1079 if (bootmode == "charger") {
1080 am.QueueEventTrigger("charger");
1081 } else {
1082 am.QueueEventTrigger("late-init");
1083 }
1084
1085 // Run all property triggers based on current state of the properties.
1086 am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");
。。。
1090 while (true) {
。。。
1103
1104 if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running())) {
// 4)执行所有的command 命令:ExecuteOneCommand
1105 am.ExecuteOneCommand();
1106 // If there's more work to do, wake up again immediately.
// 如果还有命令,则下一次执行的时间就是现在;循环执行命令
1107 if (am.HasMoreCommands()) {
1108 next_action_time = boot_clock::now();
1109 }
1110 }
1)首先执行 LoadBootScripts 方法
337 static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
338 Parser parser = CreateParser(action_manager, service_list);
340 std::string bootscript = GetProperty("ro.boot.init_rc", "");
341 if (bootscript.empty()) {
342 parser.ParseConfig("/system/etc/init/hw/init.rc");
// 将 三个处理的指令 service、on、import保存到 Parser 中
270 Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
271 Parser parser;
272
273 parser.AddSectionParser("service", std::make_unique<ServiceParser>(
274 &service_list, GetSubcontext(), std::nullopt));
275 parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, GetSubcontext()));
276 parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
277
278 return parser;
279 }
// AddSectionParser 方法,缓存对应的on 名字和处理对象 ActionParser
/system/core/init/parser.cpp
37 void Parser::AddSectionParser(const std::string& name, std::unique_ptr<SectionParser> parser) {
38 section_parsers_[name] = std::move(parser);
39 }
// 然后调用 ParseConfig 去解析所有的rc 文件,会走到 ParseData 方法中
45 void Parser::ParseData(const std::string& filename, std::string* data) {
46 data->push_back('\n');
47 data->push_back('\0');
。。
85 case T_NEWLINE: {
86 state.line++;
87 if (args.empty()) break;
88 // If we have a line matching a prefix we recognize, call its callback and unset any
89 // current section parsers. This is meant for /sys/ and /dev/ line entries for
90 // uevent.
91 auto line_callback = std::find_if(
92 line_callbacks_.begin(), line_callbacks_.end(),
93 [&args](const auto& c) { return android::base::StartsWith(args[0], c.first); });
94 if (line_callback != line_callbacks_.end()) {
95 end_section();
96
97 if (auto result = line_callback->second(std::move(args)); !result.ok()) {
98 parse_error_count_++;
99 LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
100 }
101 } else if (section_parsers_.count(args[0])) {
102 end_section();
// section_parser 就是 ActionParser
103 section_parser = section_parsers_[args[0]].get();
104 section_start_line = state.line;
// 调用 ActionParser的 ParseSection 方法
105 if (auto result =
106 section_parser->ParseSection(std::move(args), filename, state.line);
107 !result.ok()) {
108 parse_error_count_++;
109 LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
110 section_parser = nullptr;
111 bad_section_found = true;
112 }
113 } else if (section_parser) {
// 接下列解析每一行字符串值ParseLineSection
114 if (auto result = section_parser->ParseLineSection(std::move(args), state.line);
115 !result.ok()) {
116 parse_error_count_++;
117 LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
118 }
// 调用 ActionParser的 ParseSection 方法
/system/core/init/action_parser.cpp
133 Result<void> ActionParser::ParseSection(std::vector<std::string>&& args,
134 const std::string& filename, int line) {
135 std::vector<std::string> triggers(args.begin() + 1, args.end());
136 if (triggers.size() < 1) {
137 return Error() << "Actions must have a trigger";
138 }
139
140 Subcontext* action_subcontext = nullptr;
141 if (subcontext_ && subcontext_->PathMatchesSubcontext(filename)) {
142 action_subcontext = subcontext_;
143 }
144
145 // We support 'on' for only Vendor APEXes from /{vendor, odm}.
146 // It is to prevent mainline modules from using 'on' triggers because events/properties are
147 // not stable for mainline modules.
148 // Note that this relies on Subcontext::PathMatchesSubcontext() to identify Vendor APEXes.
149 if (StartsWith(filename, "/apex/") && !action_subcontext) {
150 return Error() << "ParseSection() failed: 'on' is supported for only Vendor APEXes.";
151 }
152
153 std::string event_trigger;
154 std::map<std::string, std::string> property_triggers;
155
// ParseTriggers 获取到 on 后面的string值和 property
// 比如:on init && property:ro.product.cpu.abilist32=*
156 if (auto result =
157 ParseTriggers(triggers, action_subcontext, &event_trigger, &property_triggers);
158 !result.ok()) {
159 return Error() << "ParseTriggers() failed: " << result.error();
160 }
161
// 创建 Action 对象
162 auto action = std::make_unique<Action>(false, action_subcontext, filename, line, event_trigger,
163 property_triggers);
164
// 将其保存到 action_
165 action_ = std::move(action);
166 return {};
167 }
// 接下列解析每一行字符串值ParseLineSection,最后走 EndSection
173 Result<void> ActionParser::EndSection() {
174 if (action_ && action_->NumCommands() > 0) {
175 action_manager_->AddAction(std::move(action_));
176 }
177
178 return {};
179 }
/system/core/init/action_manager.cpp
// 将action 保存到 actions_ 中
39 void ActionManager::AddAction(std::unique_ptr<Action> action) {
40 actions_.emplace_back(std::move(action));
41 }
2) 执行 QueueBuiltinAction 方法
/system/core/init/action_manager.cpp
57 void ActionManager::QueueBuiltinAction(BuiltinFunction func, const std::string& name) {
58 auto lock = std::lock_guard{event_queue_lock_};
// 创建了action 对象
59 auto action = std::make_unique<Action>(true, nullptr, "<Builtin Action>", 0, name,
60 std::map<std::string, std::string>{});
// 将func 函数放入到 AddCommand ,command 中
61 action->AddCommand(std::move(func), {name}, 0);
62
// 将action 保存到了 event_queue_和 actions_ 中
63 event_queue_.emplace(action.get());
64 actions_.emplace_back(std::move(action));
65 }
// event_queue_ 可以保存下列 3中类型:
59 std::queue<std::variant<EventTrigger, PropertyChange, BuiltinAction>> event_queue_
60 GUARDED_BY(event_queue_lock_);
3)执行 QueueEventTrigger 方法
/system/core/init/action_manager.cpp
43 void ActionManager::QueueEventTrigger(const std::string& trigger) {
44 auto lock = std::lock_guard{event_queue_lock_};
// 将string 值保存到了 event_queue_ 中
45 event_queue_.emplace(trigger);
46 }
QueueEventTrigger 保存了 “early-init” “init “ 和 “late-init”
4)执行所有的command 命令:ExecuteOneCommand
/system/core/init/action_manager.cpp
// event_queue_ 的值由前面分析,通过 QueueBuiltinAction 和 QueueEventTrigger 增加了
67 void ActionManager::ExecuteOneCommand() {
68 {
69 auto lock = std::lock_guard{event_queue_lock_};
70 // Loop through the event queue until we have an action to execute
71 while (current_executing_actions_.empty() && !event_queue_.empty()) {
// 遍历所有的 actions_
72 for (const auto& action : actions_) {
73 if (std::visit([&action](const auto& event) { return action->CheckEvent(event); },
74 event_queue_.front())) {
// 将action 保存到 current_executing_actions_ 中
75 current_executing_actions_.emplace(action.get());
76 }
77 }
78 event_queue_.pop();
79 }
80 }
81
82 if (current_executing_actions_.empty()) {
83 return;
84 }
85
86 auto action = current_executing_actions_.front();
87
88 if (current_command_ == 0) {
89 std::string trigger_name = action->BuildTriggersString();
// 会打印下列的log
90 LOG(INFO) << "processing action (" << trigger_name << ") from (" << action->filename()
91 << ":" << action->line() << ")";
92 }
93
// 执行命令
94 action->ExecuteOneCommand(current_command_);
95
96 // If this was the last command in the current action, then remove
97 // the action from the executing list.
98 // If this action was oneshot, then also remove it from actions_.
99 ++current_command_;
100 if (current_command_ == action->NumCommands()) {
101 current_executing_actions_.pop();
102 current_command_ = 0;
103 if (action->oneshot()) {
104 auto eraser = [&action](std::unique_ptr<Action>& a) { return a.get() == action; };
105 actions_.erase(std::remove_if(actions_.begin(), actions_.end(), eraser),
106 actions_.end());
107 }
108 }
109 }
// 执行的顺序为:
1-1)为下列 4 个方法
SetupCgroupsAction、SetKptrRestrictAction、TestPerfEventSelinuxAction、ConnectEarlyStageSnapuserdAction 方法
// 然后执行 QueueEventTrigger(“early-init”;
1-2)early-init 阶段
/system/core/rootdir/init.rc
15 on early-init
16 # Disable sysrq from keyboard
17 write /proc/sys/kernel/sysrq 0
18
22 write /proc/sys/kernel/modprobe \n
23
25 restorecon /adb_keys
28 restorecon /postinstall
29
30 mkdir /acct/uid
。。。
1-3)下列 3 个方法
wait_for_coldboot_done、SetMmapRndBitsAction、KeychordInit
1-4)init 阶段
可以看出在 init 阶段启动了 logd、lmkd、servicemanager、hwservicemanager和vndservicemanager
97 on init
98 sysclktz 0
99
100 # Mix device-specific information into the entropy pool
101 copy /proc/cmdline /dev/urandom
102 copy /system/etc/prop.default /dev/urandom
103
104 symlink /proc/self/fd/0 /dev/stdin
105 symlink /proc/self/fd/1 /dev/stdout
106 symlink /proc/self/fd/2 /dev/stderr
107
108 # Create energy-aware scheduler tuning nodes
109 mkdir /dev/stune/foreground
110 mkdir /dev/stune/background
111 mkdir /dev/stune/top-app
112 mkdir /dev/stune/rt
。。。。
468 # Start logd before any other services run to ensure we capture all of their logs.
469 start logd
470 # Start lmkd before any other services run so that it can register them
471 write /proc/sys/vm/watermark_boost_factor 0
472 chown root system /sys/module/lowmemorykiller/parameters/adj
473 chmod 0664 /sys/module/lowmemorykiller/parameters/adj
474 chown root system /sys/module/lowmemorykiller/parameters/minfree
475 chmod 0664 /sys/module/lowmemorykiller/parameters/minfree
476 start lmkd
477
478 # Start essential services.
479 start servicemanager
480 start hwservicemanager
481 start vndservicemanager
1-5)late-init 阶段
// 在late-init 阶段也会设置几个阶段
531 # Mount filesystems and start core system services.
532 on late-init
533 trigger early-fs
539 trigger fs
540 trigger post-fs
541
547 trigger late-fs
548
549 # Now we can mount /data. File encryption requires keymaster to decrypt
550 # /data, which in turn can only be loaded when system properties are present.
551 trigger post-fs-data
552
553 # Should be before netd, but after apex, properties and logging is available.
554 trigger load_bpf_programs
555
556 # Now we can start zygote for devices with file based encryption
557 trigger zygote-start
558
559 # Remove a file to wake up anything waiting for firmware.
560 trigger firmware_mounts_complete
561
562 trigger early-boot
563 trigger boot
在late-init 阶段也分为下列几个阶段:early-fs、fs、post-fs、late-fs、post-fs-data、load_bpf_programs、zygote-start、firmware_mounts_complete、early-boot、boot
// 先看下 trigger 对应的方法的逻辑:
/system/core/init/builtins.cpp
798 static Result<void> do_trigger(const BuiltinArguments& args) {
// 也是调用 ActionManager 对象的 QueueEventTrigger 方法
799 ActionManager::GetInstance().QueueEventTrigger(args[1]);
800 return {};
801 }
1-5-1)early-fs 阶段
// 在此阶段启动了 vold
565 on early-fs
566 # Once metadata has been mounted, we'll need vold to deal with userdata checkpointing
567 start vold
1-5-2)fs 阶段
比如logd 的处理:
/system/logging/logd/logd.rc
29 on fs
30 write /dev/event-log-tags "# content owned by logd
31 "
32 chown logd logd /dev/event-log-tags
33 chmod 0644 /dev/event-log-tags
1-5-3)post-fs 阶段
// post-fs 阶段 会创建一些文件
/xref/system/core/rootdir/init.rc
569 on post-fs
570 exec - system system -- /system/bin/vdc checkpoint markBootAttempt
571
572 # Once everything is setup, no need to modify /.
573 # The bind+remount combination allows this to work in containers.
574 mount rootfs rootfs / remount bind ro nodev
575
576 # Mount default storage into root namespace
577 mount none /mnt/user/0 /storage bind rec
578 mount none none /storage slave rec
579
580 # Make sure /sys/kernel/debug (if present) is labeled properly
581 # Note that tracefs may be mounted under debug, so we need to cross filesystems
582 restorecon --recursive --cross-filesystems /sys/kernel/debug
583
584 # We chown/chmod /cache again so because mount is run as root + defaults
585 chown system cache /cache
586 chmod 0770 /cache
1-5-4)late-fs 阶段
643 on late-fs
644 # Ensure that tracefs has the correct permissions.
645 # This does not work correctly if it is called in post-fs.
646 chmod 0755 /sys/kernel/tracing
647 chmod 0755 /sys/kernel/debug/tracing
648
649 # HALs required before storage encryption can get unlocked (FBE)
650 class_start early_hal
651
652 # Load trusted keys from dm-verity protected partitions
653 exec -- /system/bin/fsverity_init --load-verified-keys
// class_start early_hal 启动配置了 early_hal 的hal进程
/system/core/init/builtins.cpp
164 static Result<void> do_class_start(const BuiltinArguments& args) {
165 // Do not start a class if it has a property persist.dont_start_class.CLASS set to 1.
166 if (android::base::GetBoolProperty("persist.init.dont_start_class." + args[1], false))
167 return {};
168 // Starting a class does not start services which are explicitly disabled.
169 // They must be started individually.
170 for (const auto& service : ServiceList::GetInstance()) {
// 遍历所有的service,找到设置了class 为 early_hal的 进程
171 if (service->classnames().count(args[1])) {
172 if (auto result = service->StartIfNotDisabled(); !result.ok()) {
173 LOG(ERROR) << "Could not start service '" << service->name()
174 << "' as part of class '" << args[1] << "': " << result.error();
175 }
176 }
177 }
178 return {};
179 }
// 比如keystore2 进程
/system/security/keystore2/keystore2.rc
9 service keystore2 /system/bin/keystore2 /data/misc/keystore
10 class early_hal
11 user keystore
1-5-5)post-fs-data 阶段
678 on post-fs-data
679
680 mark_post_data
.。。
741 start logd
742 start logd-reinit
743
748 trigger load_persist_props_action
。。。
790 chown bluetooth bluetooth /data/misc/bluedroid/bt_config.conf
791 mkdir /data/misc/bluetooth 0770 bluetooth bluetooth
792 mkdir /data/misc/bluetooth/logs 0770 bluetooth bluetooth
793 mkdir /data/misc/nfc 0770 nfc nfc
794 mkdir /data/misc/nfc/logs 0770 nfc nfc
795 mkdir /data/misc/credstore 0700 credstore credstore
796 mkdir /data/misc/gatekeeper 0700 system system
797 mkdir /data/misc/keychain 0771 system system
798 mkdir /data/misc/net 0750 root shell
799 mkdir /data/misc/radio 0770 system radio
800 mkdir /data/misc/sms 0770 system radio
801 mkdir /data/misc/carrierid 0770 system radio
1-5-6)load_bpf_programs 阶段
1253 on load_bpf_programs && property:sys.init.perf_lsm_hooks=1
1254 write /proc/sys/kernel/perf_event_paranoid -1
1-5-7)zygote-start 阶段
// 可以通过命令 adb shell getprop ro.crypto.state 获取到对应的值
init: processing action (ro.crypto.state=encrypted && ro.crypto.type=file && zygote-start) from (/system/etc/init/hw/init.rc:1130)
00E1A <14> [ 6.557417] [11-24 16:44:06.557] vold: [libfs_mgr] __mount(source=/dev/block/dm-48,target=/data,type=f2fs)=0,during time: 280 ms: Success
00E1B <15> [ 6.558446] [11-24 16:44:06.558] vold: Mounted /data
00E1C <14> [ 6.574732] [11-24 16:44:06.574] init: Userdata mounted using /vendor/etc/fstab.ums9230_4h10 result : 7
00E1D <14> [ 6.574850] [11-24 16:44:06.574] init: Keyring created with id 1023294143 in process 1
00E1E <14> [ 6.575766] [11-24 16:44:06.575] init: Command 'mount_all /vendor/etc/fstab.${ro.hardware} --late' action=late-fs (/vendor/etc/init/init.md.rc:963) took 1050ms and succeeded
00E1F <14> [ 6.575864] [11-24 16:44:06.575] init: Service 'insmod-sh' (pid 268) exited with status 0 oneshot service took 2.680000 seconds in background
// 可以指导是执行了下列的rc 文件
// 启动了下列几个进程为:statsd、netd、zygote、zygote_secondary
1090 on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
1091 wait_for_prop odsign.verification.done 1
1092 # A/B update verifier that marks a successful boot.
1093 exec_start update_verifier_nonencrypted
1094 start statsd
1095 start netd
1096 start zygote
1097 start zygote_secondary
1-5-8)firmware_mounts_complete 阶段
527 # Indicate to fw loaders that the relevant mounts are up.
528 on firmware_mounts_complete
529 rm /dev/.booting
1-5-9)early-boot 阶段
/frameworks/native/cmds/installd/installd.rc
7 on early-boot
8 mkdir /config/sdcardfs/extensions/1055
9 mkdir /config/sdcardfs/extensions/1056
10 mkdir /config/sdcardfs/extensions/1057
11 mkdir /config/sdcardfs/extensions/1056/3gpp
1-5-10)boot 阶段
1104 on boot
1105 # basic network init
1106 ifup lo
1107 hostname localhost
1108 domainname localdomain
。。。
1206 # Define default initial receive window size in segments.
1207 setprop net.tcp_def_init_rwnd 60
1208
1209 # Start standard binderized HAL daemons
1210 class_start hal
1211
1212 class_start core
// 执行 class_start hal 和 class_start core
/system/core/init/builtins.cpp
164 static Result<void> do_class_start(const BuiltinArguments& args) {
165 // Do not start a class if it has a property persist.dont_start_class.CLASS set to 1.
166 if (android::base::GetBoolProperty("persist.init.dont_start_class." + args[1], false))
167 return {};
168 // Starting a class does not start services which are explicitly disabled.
169 // They must be started individually.
170 for (const auto& service : ServiceList::GetInstance()) {
// 看是否由class 为 hal 或者 core
171 if (service->classnames().count(args[1])) {
// 调用 service 的 StartIfNotDisabled 方法
172 if (auto result = service->StartIfNotDisabled(); !result.ok()) {
173 LOG(ERROR) << "Could not start service '" << service->name()
174 << "' as part of class '" << args[1] << "': " << result.error();
175 }
176 }
177 }
178 return {};
179 }
// 调用 service 的 StartIfNotDisabled 方法
/system/core/init/service.cpp
818 Result<void> Service::StartIfNotDisabled() {
// 如果设置中没有 DISABLED 属性,则执行start 启动进程
819 if (!(flags_ & SVC_DISABLED)) {
820 return Start();
821 } else {
/// 有disable,则设置属性 SVC_DISABLED_START
822 flags_ |= SVC_DISABLED_START;
823 }
824 return {};
825 }
// 比如:bootanim,有 disabled属性
/frameworks/base/cmds/bootanimation/bootanim.rc
1 service bootanim /system/bin/bootanimation
2 class core animation
3 user graphics
4 group graphics audio
5 disabled
6 oneshot
7 ioprio rt 0
8 task_profiles MaxPerformance
/system/core/init/service_parser.cpp
589 {"disabled", {0, 0, &ServiceParser::ParseDisabled}},
134 Result<void> ServiceParser::ParseDisabled(std::vector<std::string>&& args) {
// 设置flags 有 SVC_DISABLED
135 service_->flags_ |= SVC_DISABLED;
136 service_->flags_ |= SVC_RC_DISABLED;
137 return {};
138 }
1-5-10-1)boot 阶段启动 hal 的 进程
/hardware/interfaces/graphics/composer/2.4/default/android.hardware.graphics.composer%402.4-service.rc
1 service vendor.hwcomposer-2-4 /vendor/bin/hw/android.hardware.graphics.composer@2.4-service
2 class hal animation
3 user system
4 group graphics drmrpc
/hardware/interfaces/sensors/2.1/multihal/android.hardware.sensors%402.1-service-multihal.rc
1 service vendor.sensors-hal-2-1-multihal /vendor/bin/hw/android.hardware.sensors@2.1-service.multihal
2 class hal
3 user system
4 group system wakelock context_hub input
…
1-5-10-2)boot 阶段启动 core 的 进程
/packages/modules/adb/apex/adbd.rc
1 service adbd /apex/com.android.adbd/bin/adbd --root_seclabel=u:r:su:s0
2 class core
3 socket adbd seqpacket 660 system system
4 disabled
/frameworks/native/services/surfaceflinger/surfaceflinger.rc
1 service surfaceflinger /system/bin/surfaceflinger
2 class core animation
3 user system
4 group graphics drmrpc readproc
5 capabilities SYS_NICE
6 onrestart restart --only-if-running zygote
/frameworks/av/media/audioserver/audioserver.rc
1 service audioserver /system/bin/audioserver
2 class core
3 user audioserver
/system/core/rootdir/init.usb.rc
14 # adbd is controlled via property triggers in init.<platform>.usb.rc
15 service adbd /system/bin/adbd --root_seclabel=u:r:su:s0
16 class core
17 socket adbd seqpacket 660 system system
18 disabled
19 updatable
20 seclabel u:r:adbd:s0