本篇文章主要介绍 Android
开发中的部分知识点,通过阅读本篇文章,您将收获以下内容:
一、启动流程概述
二、Android启动分析
三、init 进程启动分析
四、init 启动脚本分析
五、init 进程分析
六、init 脚本执行
七、init 进程守护
八、init rc 脚本启动Zygote
九、启动分析小结
一、 启动流程概述
Android
启动流程跟 Linux
启动类似,大致分为如下五个阶段。
- 1.开机上电,加载固化的
ROM
。 - 2.加载
BootLoader
,拉起Android OS
。 - 3.加载
Uboot
,初始外设,引导Kernel
启动等。 - 4.启动
Kernel
,加载驱动,硬件。 - 5.启动
Android
,挂载分区,加载驱动、服务,init
进程等。
Android系统启动大致过程如下:
Android 启动过程
由于水平有限,无法深入了理解驱动层代码,本文主要对 Android
上层启动流程进行分析。
二、Android启动分析
Uboot
启动Kernel
完成系统设置后,会首先在系统中寻找init.rc
文件(文件多存放在/system/core/init目录下)
,并启动init
进程。
Android
启动 主要包含如下两种
- 1.启动脚本
- 2.Zygote 启动
Android 启动分析主要内容如下:
Android 启动分析
三、init 进程启动分析
Init
进程是是Android
启动的第一个进程,进程号为1
,是Android
的系统启动的核心进程,主要用来创建Zygote
、属性服务等。源码主要存在\system\core\init
目录下。
常见init.xxx.rc 进程如下:
常见init.xxx.rc 进程
init 进程的入口 main 函数init.cpp
中的main
函数,是init
进程的入口函数(代码路径:\system\core\init\init.cpp)
main 函数主要做的事情
1.创建挂载启动所需的文件系统(tmpfs、 devpts、 proc、 sysfs、 selinuxfs等)
。
2.初始化并启动属性服务
3.解析init.rc
脚本配置文件,并启动Zygote
进程。
init 进程
init.cpp main 函数实现代码如下:
int main(int argc, char** argv) {
if (!strcmp(basename(argv[0]), "ueventd")) {
return ueventd_main(argc, argv);
}
if (!strcmp(basename(argv[0]), "watchdogd")) {
//启动看门狗函数
return watchdogd_main(argc, argv);
}
if (argc > 1 && !strcmp(argv[1], "subcontext")) {
InitKernelLogging(argv);
const BuiltinFunctionMap function_map;
return SubcontextMain(argc, argv, &function_map);
}
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}
bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);
//启动第一阶段
if (is_first_stage) {
boot_clock::time_point start_time = boot_clock::now();