init进程启动过程
init进程是Android系统中用户空间的第一进程,进程号为 1,是Android系统启动的开始,作为第一进程,有很重要的工作,比如创建 zygote进程 和属性服务等等。
引导init进程
首先我们需要了解Android系统是如何引导 init 进程的。
启动电源以及系统启动
当电源按下时引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序Bootloader到RAM,然后执行。
引导程序Bootloader
引导程序是在Android操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行。
linux内核启动
内核启动时,设置缓存、被保护存储器、计划列表,加载驱动。当内核完成系统设置,它首先在系统文件中寻找”init”文件,然后启动root进程或者系统的第一个进程。
init进程启动
init进程的工作很多,主要用来初始化和启动属性服务,同时也用来启动 zygote进程.
入口函数
int main(int argc, char** argv) {
...
//清理umask
umask(0);
//创建和挂在启动所需的文件目录
if (is_first_stage) {
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
mkdir("/dev/pts", 0755);
mkdir("/dev/socket", 0755);
mount("devpts", "/dev/pts", "devpts", 0, NULL);
#define MAKE_STR(x) __STRING(x)
mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
mount("sysfs", "/sys", "sysfs", 0, NULL);
}
open_devnull_stdio();
klog_init();
klog_set_level(KLOG_NOTICE_LEVEL);
NOTICE("init %s started!\n", is_first_stage ? "first stage" : "second stage");
if (!is_first_stage) {
// Indicate that booting is in progress to background fw loaders, etc.
close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
//对属性服务进行初始化
property_init();
process_kernel_dt();
process_kernel_cmdline();
export_kernel_boot_props();
}
...
//创建epoll句柄
epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (epoll_fd == -1) {
ERROR("epoll_create1 failed: %s\n", strerror(errno));
exit(1);
}
//用于设置子进程信号处理函数,如果子进程(zygote进程)异常退出,init进程会调用该函数中
//设定的信号处理函数来进行处理
signal_handler_init();
//导入默认的环境变量
property_load_boot_defaults();
export_oem_lock_status();
//启动属性服务
start_property_service();
const BuiltinFunctionMap function_map;
Action::set_function_map(&function_map);
Parser& parser = Parser::GetInstance();
parser.AddSectionParser("service",std::make_unique<ServiceParser>());
parser.AddSectionParser("on", std::make_unique<ActionParser>());
parser.AddSectionParser("import", std::make_unique<ImportParser>());
//解析init.rc配置文件
parser.ParseConfig("/init.rc");//3
...
}
return 0;
}
init的main方法做了很多事情,我们只需要关注主要的几点, property_init来对属性进行初始化以及 start_property_service启动属性服务, parser.ParseConfig(“/init.rc”)用来解析init.rc。解析init.rc的文件为system/core/init/init_parse.cpp文件,接下来我们查看init.rc里做了什么。
其实我们只需要关心,init进程是如何把zygote进程启动起来的即可,因为zygote进程才是Android中最为重要的进程。
在 zygote进程 简单介绍过 rc 文件中的语法以及他的使用,该文件主要是让系统去启动指定的进程。
同样的,在 init.rc 中也有启动 zygote进程的语法,因此,只需要知道,zygote进程是由init进程启动的,并且是通过 rc 文件语法来进行操作。
另外需要注意的是,Binder机制中的servicemanager服务也是在init进程中开启的。
总结
总结起来init进程主要做了三件事:
1.创建一些文件夹并挂载设备
2.初始化和启动属性服务
3.解析init.rc配置文件并启动zygote进程
转载于:https://www.yuque.com/mikaelzero/blog/gmgxq1
网友评论