Android 进阶解密:init 进程启动过程

init 进程启动过程

      • 一、init 进程
      • 二、init 进程启动流程
      • 三、启动 init 进程
      • 四、解析 init.rc 文件

Android 系统启动与很多内容都有关联,如应用进程启动流程、四大组件原理、AMS、ClassLoader 等

一、init 进程

init 进程是 Android 系统中用户进程的第一个进程,进程号为 1,被赋予很多极其重要的职责,如创建 Zygote 进程和属性服务等。init 进程由多个源文件组成,文件位于 system/core/init 目录

二、init 进程启动流程

① 启动电源以及系统启动
按下电源时,引导芯片代码从预定义的地方(固化在 ROM)开始执行,加载引导程序 BootLoader 到 RAM 中,然后执行
② 引导程序 BootLoader
是 Android 操作系统运行之前的一个小程序,把系统 OS 拉起来并运行
③ Linux 内核启动
当内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。在内核完成系统设置后,首先在系统文件中寻找 init.rc 文件,并启动 init 进程
④ init 进程启动
主要用来初始化和启动属性服务,也用来启动 Zygote 进程

三、启动 init 进程

Linux 内核加载完成之后,第一件事就是启动 init 进程,首先会在系统文件中寻找 init.rc 文件

文件位置:system/core/init/init.cpp

init.cpp 的入口函数 main() 方法代码流程:
① 创建和挂载启动所需的文件目录
② property_init():对属性进行初始化
③ signal_handler_init():设置子进程信号处理函数,子进程(Zygote 进程)异常退出,init 进程会调用当前函数中设定的信号处理函数来进行处理
④ start_property_service():启动属性服务
⑤ parse.ParseConfig("/init.rc"):解析 init.rc 配置文件
⑥ restart_processes():重启死去的进程

在 main() 函数中,②④ 分别完成了属性服务的初始化和启动,⑤ 用于解析 init.rc 文件,① 用于挂载系统运行时目录(系统停止时消失),③⑥ 分别用来设置信号处理函数和处理进程终止信号(防止 init 子进程成为僵尸进程,进程终止时,如果注册了信号处理函数,则函数内部会针对终止信号进行相应处理,如重启进程)

四、解析 init.rc 文件

parse.ParseConfig("/init.rc")

文件位置:system/core/init/init_parse.cpp

init.rc 是由 Android 初始化语言编写的一个非常重要的配置脚本文件。Android 初始化语言主要包含 5 种类型的语句:Action、Service、Command、Option、Import

Android 8.0 对 init.rc 文件进行了拆分,每个服务对应一个 rc 文件,其中 Zygote 启动脚本在 init.ZygoteXX.rc 中定义,64 位处理器对应 init.Zygote64.rc,对应文件目录 system/core/rootdir/init.zygote64.rc

在启动 Zygote 之前
首先会解析 Service 类型语句,把 Service 对象加入到 Service 链表中

init 启动 Zygote
会遍历 Service 链表,找到 class_name 为 main 的 Service,其中:
① Zygote 的 classname 为 main
② Zygote 执行程序的路径为 /system/bin/app_process64,对应文件为 app_main.cpp
init.rc 文件最后会调用 Service#Start() 函数(函数所在文件为 system/core/init/service.cpp),如果 Service 已经运行,则不再启动,否则最终通过会 execve(…) 函数去启动子进程,这样 Service 子进程就会被启动,如果当前启动的 Service 是 Zygote,则会进入 app_main.cpp 的 mian() 函数,也就是在 Zygote 的 main() 函数,接着就会调用 AppRuntime#start() 方法启动 Zygote,至此 Zygote 就启动了

你可能感兴趣的:(Android,读书笔记)