参考:
https://blog.csdn.net/pepsimaxin/article/details/107284563
https://www.it610.com/article/1304931662924124160.htm
https://www.cnblogs.com/pyjetson/p/14901076.html
https://juejin.cn/post/6844903946151002125
https://www.bilibili.com/read/cv9263357
前文:
http://www.gaohaiyan.com/4021.html
http://www.gaohaiyan.com/4030.html
%lineage%/system/core/init/init.cpp 约690行
SecondStageMain称为init的第二阶段。仍旧是Linux中的操作。代码还没有Android层的。
● 完成 SELinux 相关工作
● 启动属性服务
● 创建 epoll 句柄事件监听
● 装载子进程信号处理器
● 解析init.rc启动脚本,启动相关服务
● while (true)持续处理action、关机等事件。到这,运行中的系统就是这个死循环。
进入SecondStageMain有3种情景:
main –> FirstStageMain –>SetupSelinux–> SecondStageMain
main –> SetupSelinux–> SecondStageMain
main –> 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 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 |
#include "init.h" #include <dirent.h> #include <fcntl.h> #include <pthread.h> #include <signal.h> #include <stdlib.h> #include <string.h> #include <sys/eventfd.h> #include <sys/mount.h> #include <sys/signalfd.h> #include <sys/types.h> #include <unistd.h> #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ #include <sys/_system_properties.h> #include <functional> #include <map> #include <memory> #include <mutex> #include <optional> #include <thread> #include <vector> #include <android-base/chrono_utils.h> #include <android-base/file.h> #include <android-base/logging.h> #include <android-base/parseint.h> #include <android-base/properties.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <fs_avb/fs_avb.h> #include <fs_mgr_vendor_overlay.h> #include <keyutils.h> #include <libavb/libavb.h> #include <libgsi/libgsi.h> #include <processgroup/processgroup.h> #include <processgroup/setup.h> #include <selinux/android.h> #include "action_parser.h" #include "builtins.h" #include "epoll.h" #include "first_stage_init.h" #include "first_stage_mount.h" #include "import_parser.h" #include "keychords.h" #include "lmkd_service.h" #include "mount_handler.h" #include "mount_namespace.h" #include "property_service.h" #include "proto_utils.h" #include "reboot.h" #include "reboot_utils.h" #include "security.h" #include "selabel.h" #include "selinux.h" #include "service.h" #include "service_parser.h" #include "sigchld_handler.h" #include "subcontext.h" #include "system/core/init/property_service.pb.h" #include "util.h" using namespace std::chrono_literals; using namespace std::string_literals; using android::base::boot_clock; using android::base::ConsumePrefix; using android::base::GetProperty; using android::base::ReadFileToString; using android::base::SetProperty; using android::base::StringPrintf; using android::base::Timer; using android::base::Trim; using android::fs_mgr::AvbHandle; namespace android { namespace init { static int property_triggers_enabled = 0; static int signal_fd = -1; static int property_fd = -1; struct PendingControlMessage { // 略 }; static std::mutex pending_control_messages_lock; static std::queue<PendingControlMessage> pending_control_messages; static int wake_main_thread_fd = -1; static void InstallInitNotifier(Epoll* epoll) { // 略 } static void WakeMainInitThread() { // 唤醒init进程 // 略 } static class PropWaiterState { // 略 } prop_waiter_state; bool start_waiting_for_property(const char* name, const char* value) { return prop_waiter_state.StartWaiting(name, value); } void ResetWaitForProp() { prop_waiter_state.ResetWaitForProp(); } static class ShutdownState { // 略 } shutdown_state; void DumpState() { // 略 } Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) { // 略 } Parser CreateServiceOnlyParser(ServiceList& service_list, bool from_apex) { // 略 } static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) { // 略 } void PropertyChanged(const std::string& name, const std::string& value) { // 略 } static std::optional<boot_clock::time_point> HandleProcessActions() { // 略 } static Result<void> DoControlStart(Service* service) { return service->Start(); } static Result<void> DoControlStop(Service* service) { service->Stop(); return {}; } static Result<void> DoControlRestart(Service* service) { // 略 } enum class ControlTarget { // 略 }; using ControlMessageFunction = std::function<Result<void>(Service*)>; static const std::map<std::string, ControlMessageFunction, std::less<>>& GetControlMessageMap() { // 略 } static bool HandleControlMessage(std::string_view message, const std::string& name, pid_t from_pid) { // 略 } bool QueueControlMessage(const std::string& message, const std::string& name, pid_t pid, int fd) { // 略 } static void HandleControlMessages() { // 略 } static Result<void> wait_for_coldboot_done_action(const BuiltinArguments& args) { // 略 } static Result<void> SetupCgroupsAction(const BuiltinArguments&) { // 略 } static void export_oem_lock_status() { // 略 } static Result<void> property_enable_triggers_action(const BuiltinArguments& args) { // 略 } static Result<void> queue_property_triggers_action(const BuiltinArguments& args) { // 略 } static void SetUsbController() { // 略 } static void HandleSigtermSignal(const signalfd_siginfo& siginfo) { // 略 } static void HandleSignalFd() { // 略 } static void UnblockSignals() { // 略 } static void InstallSignalFdHandler(Epoll* epoll) { // 略 } void HandleKeychord(const std::vector<int>& keycodes) { // 略 } static void UmountDebugRamdisk() { // 略 } static void MountExtraFilesystems() { #define CHECKCALL(x) \ // 略 #undef CHECKCALL } static void RecordStageBoottimes(const boot_clock::time_point& second_stage_start_time) { // 略 } void SendLoadPersistentPropertiesMessage() { // 略 } // 入口 int SecondStageMain(int argc, char** argv) { if (REBOOT_BOOTLOADER_ON_PANIC) { InstallRebootSignalHandlers(); } boot_clock::time_point start_time = boot_clock::now(); // 约219行。关机回调 trigger_shutdown = [](const std::string& command) { shutdown_state.TriggerShutdown(command); }; SetStdioToDevNull(argv); // 标准输入输出错误 => /dev/null InitKernelLogging(argv); // 内核log => /dev/kmsg LOG(INFO) << "init second stage started!"; // Init should not crash because of a dependence on any other process, therefore we ignore SIGPIPE and handle EPIPE at the call site directly. // Note that setting a signal to SIG_IGN is inherited across exec, but custom signal handlers are not. // Since we do not want to ignore SIGPIPE for child processes, we set a no-op function for the signal handler instead. // Init不应该因为依赖于任何其他进程而崩溃,因此我们忽略SIGPIPE,直接在调用站点处理EPIPE。 // 请注意,将信号设置为SIG_IGN是跨exec继承的,但定制信号处理程序并非如此。 // 由于我们不想忽略子进程的SIGPIPE,我们为信号处理程序设置了一个no-op函数。 { struct sigaction action = {.sa_flags = SA_RESTART}; action.sa_handler = [](int) {}; sigaction(SIGPIPE, &action, nullptr); // 忽略SIGPIPE信号异常 } // Set init and its forked children's oom_adj.设置init进程自己的oomadj值-1000,表示不能杀掉 if (auto result = WriteFile("/proc/1/oom_score_adj", StringPrintf("%d", DEFAULT_OOM_SCORE_ADJUST)); !result.ok()) { LOG(ERROR) << "Unable to write " << DEFAULT_OOM_SCORE_ADJUST << " to /proc/1/oom_score_adj: " << result.error(); } // 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:表示获取当前进程的 SESSION_KEYRING // 1:表示如果获取不到就新建一个会话密钥环 keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1); // Indicate that booting is in progress to background fw loaders, etc. // 创建 /dev/.booting 文件,就是个标记,表示booting进行中 close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000)); // See if need to load debug props to allow adb root, when the device is unlocked. // 读取 INIT_FORCE_DEBUGGABLE,这个属性是在第1阶段设置的,也就是debug ramdisk setup成功。 const char* force_debuggable_env = getenv("INIT_FORCE_DEBUGGABLE"); bool load_debug_prop = false; if (force_debuggable_env && AvbHandle::IsDeviceUnlocked()) { // unlock是判断cmdline中androidboot.verifiedbootstate=orange load_debug_prop = "true"s == force_debuggable_env; } unsetenv("INIT_FORCE_DEBUGGABLE"); // Umount the debug ramdisk so property service doesn't read .prop files from there, when it is not meant to. // 当Property不读取.prop文件时,卸载 if (!load_debug_prop) { UmountDebugRamdisk(); // 约637行。卸载调试磁盘 } // system/core/init/property_service.cpp PropertyInit(); //初始化Property子系统属性相关的东西,管理存储和获取Property属性。使用mmap共享内存,"/dev/__properties__/property_info" // Umount the debug ramdisk after property service has read the .prop files when it means to. // 当Property读取.prop文件后,卸载 if (load_debug_prop) { UmountDebugRamdisk(); // 约637行。卸载调试磁盘 } // Mount extra filesystems required during second stage init // 挂载apex和linkerconfig的文件系统,因为根目录是只读的,所以需要把apex和linkerconfig挂载到tmpfs才能创建文件夹 MountExtraFilesystems(); // 约643行。 // Now set up SELinux for second stage.为第二阶段配置SELinux SelinuxSetupKernelLogging(); // 注册回调,用来设置需要写入kmsg的selinux日志 SelabelInitialize(); // 设置sehandle为selinux_android_set_sehandle SelinuxRestoreContext(); // 进行SELinux第二阶段并恢复一些文件安全上下文,因为这些文件是在SELinux安全机制初始化前创建的,所以需要重新恢复上下文 Epoll epoll; // 创建epoll实例,并返回epoll的文件描述符,实现init的一些事件监控。使用IO复用机制,即 event poll,是poll机制的升级版 if (auto result = epoll.Open(); !result.ok()) { PLOG(FATAL) << result.error(); } InstallSignalFdHandler(&epoll); // 约574行。信号处理函数。监控子进程的SIGCHLD和SIGTERM信号,并在收到信号后通过HandleSignalFd函数处理 InstallInitNotifier(&epoll); // 约119行。用来唤醒init进程的 // system/core/init/property_service.cpp 约1151行。 StartPropertyService(&property_fd); // 启动属性服务。创建property_service有名socket,创建property_fd 无名socket(用来和init进程通信),以及propertyservice线程。当有设置property的请求,通过handle_property_set_fd去处理。 // Make the time that init stages started available for bootstat to log. 使init开始的时间可供bootstat记录。 // 设置init,first_stage,selinux的ro.boottime属性 RecordStageBoottimes(start_time); // 约657行 // Set libavb version for Framework-only OTA match in Treble build. // 设置avb的版本号。INIT_AVB_VERSION 设置给ro.boot.avb_version if (const char* avb_version = getenv("INIT_AVB_VERSION"); avb_version != nullptr) { SetProperty("ro.boot.avb_version", avb_version); } unsetenv("INIT_AVB_VERSION"); // system/core/fs_mgr/fs_mgr_vendor_overlay.cpp 约113行 fs_mgr_vendor_overlay_mount_all(); // 根据ro.vndk.version 版本号,将/system/vendor_overlay/"和/product/vendor_overlay/挂载在vendor上 export_oem_lock_status(); // 487行。如果设备不支持刷写解锁,应将 ro.oem_unlock_supported 设置为“0”;如果支持刷写解锁,应将其设置为“1”。 // 如果设备支持刷写解锁(即 ro.oem_unlock_supported = 1),则引导加载程序应通过将内核命令行变量 androidboot.flash.locked //(或 /firmware/android/flash.locked DT 属性)设置为“1”(如果已锁定)或“0”(来指示锁定状态)如果已解锁。 // system/core/init/mount_handler.cpp约115行 MountHandler mount_handler(&epoll);// 监控/proc/mounts 节点,发生变化也就是有新分区mount的时候执行MountHandlerFunction函数 SetUsbController(); // 约513行。读取/sys/class/udc目录的文件也就是USB设备控制器的节点,设置给属性sys.usb.controller,使USB主机端可以正常枚举到该USB设备 const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();// 返回builtins的函数跳转表。可以根据函数的字符串简称,找到对应函数入口,去调用该函数 Action::set_function_map(&function_map); // 初始化Action的function_map_ 为刚才的函数表,以便于后续执行Aciton 调用对应函数 if (!SetupMountNamespaces()) { // 设置mount namespace相关的东西,根目录下默认全部都是shared的。这个主要设置 ./ apex 分区的挂载信息权限。参考:https://cizixs.com/2017/08/29/linux-namespace/ PLOG(FATAL) << "SetupMountNamespaces failed"; } // system/core/init/subcontext.cpp 约332行 InitializeSubcontext(); // 初始化subcontext模块。在androidP(9.0)引入的, 是为了完全隔离system和vendor。给vendor oem增加u:r:vendor_init:s0权限 ActionManager& am = ActionManager::GetInstance(); // system/core/init/action_manager.cpp 创建ActionManager对象 ServiceList& sm = ServiceList::GetInstance(); // system/core/init/service_list.cpp 创建ServiceList对象 // 约273行 LoadBootScripts(am, sm);//【重点】加载 system/core/rootdir/init.rc 文件,保存到actionmanager和servicelist中 // 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();// 约247行。把解析并维护起来的Action service dump出来用去debug // Make the GSI status available before scripts start running. // gsi相关的 auto is_running = android::gsi::IsGsiRunning() ? "1" : "0"; // system/gsid/libgsi.cpp约44行。GSI是google原生代码的镜像,一般用于VTS测试 SetProperty(gsi::kGsiBootedProp, is_running); auto is_installed = android::gsi::IsGsiInstalled() ? "1" : "0"; SetProperty(gsi::kGsiInstalledProp, is_installed); // 构建action,放到event_queue,等待执行函数 am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups");//在ActionManager的队列中依次加入Action和Trigger am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict"); am.QueueBuiltinAction(TestPerfEventSelinuxAction, "TestPerfEventSelinux"); am.QueueEventTrigger("early-init"); // 执行on early-init 内容,主要包括 start ueventd 等 // 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"); Keychords keychords; am.QueueBuiltinAction( [&epoll, &keychords](const BuiltinArguments& args) -> Result<void> { for (const auto& svc : ServiceList::GetInstance()) { keychords.Register(svc->keycodes()); } keychords.Start(&epoll, HandleKeychord); return {}; }, "KeychordInit"); // Trigger all the boot actions to get us started. am.QueueEventTrigger("init"); // 【重点】执行on init 内容,主要包括 创建/挂载一些目录,以及symlink等 // 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"); // Don't mount filesystems or start core system services in charger mode. std::string bootmode = GetProperty("ro.bootmode", ""); if (bootmode == "charger") { // 充电时启动手机,会执行 on 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"); // Restore prio before main loop setpriority(PRIO_PROCESS, 0, 0); while (true) { // 运行中的系统即这个死循环 // By default, sleep until something happens. auto epoll_timeout = std::optional<std::chrono::milliseconds>{}; // 关机相关 auto shutdown_command = shutdown_state.CheckShutdown(); if (shutdown_command) { HandlePowerctlMessage(*shutdown_command); } //当前没有事件需要处理时。初次默认false if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running())) { am.ExecuteOneCommand(); // 【重点】am 队列中依次执行每个action中携带command对应的执行函数 } // system/core/init/reboot.cpp 约1058行 if (!IsShuttingDown()) { // 服务重启相关 auto next_process_action_time = HandleProcessActions(); // 约318行。重启死掉的子进程 // If there's a process that needs restarting, wake up in time for that. if (next_process_action_time) { // 决定timeout的时间,将影响while循环的间隔 epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>( *next_process_action_time - boot_clock::now()); if (*epoll_timeout < 0ms) epoll_timeout = 0ms; } } // exec执行是要waiting的;persist属性的设置初始化,要等待 if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running())) { // If there's more work to do, wake up again immediately. if (am.HasMoreCommands()) epoll_timeout = 0ms;//有command等着处理的话,不等待 } auto pending_functions = epoll.Wait(epoll_timeout); // 没有事件到来的话,最多阻塞epoll_timeout_ms时间 if (!pending_functions.ok()) { LOG(ERROR) << pending_functions.error(); // signal,mount_handle,notification唤醒,keycode相关,property_service,subcontext相关 } else if (!pending_functions->empty()) { // We always reap children before responding to the other pending functions. // This is to prevent a race where other daemons see that a service has exited and ask init to start it again via ctl.start before init has reaped it. // 有事件到来,执行对应处理函数。根据上文知道,epoll句柄(即epoll_fd)主要监听子进程结束,及其它进程设置系统属性的请求。 ReapAnyOutstandingChildren(); // system/core/init/sigchld_handler.cpp 约109行 for (const auto& function : *pending_functions) { // 执行epoll的functions (*function)(); } } if (!IsShuttingDown()) { HandleControlMessages(); // 约442行。处理属性的control命令,ctl.开头的属性 SetUsbController(); // 约513行。设置usb属性,sys.usb.controller,只需要设置一次 } } return 0; } } // namespace init } // namespace android |
- end
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/4035.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设