Android系统启动过程分析

本文详细分析了Android系统启动的过程,包括电源启动、init进程的四个步骤、Zygote进程的创建及主要任务,以及SystemServer进程的启动和服务管理。在Zygote进程中,启动了虚拟机并预加载类与资源,而后创建SystemServer进程,初始化Binder线程池,并启动系统服务。SystemServer进程则负责创建系统服务和管理Binder通信。
摘要由CSDN通过智能技术生成

主要流程

在这里插入图片描述

init进程启动过程

init进程是Android系统中用户空间的第一个进程。进程号为1。


第一步:启动电源

当电源按下,引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序到RAM,然后执行。

第二步:执行引导程序(Boot Loader)

通常在运行Android系统之前会先执行Boot Loader引导程序,它不属于Android系统,常见的引导程序有:redboot、uboot、qi bootloader等等。或者自行开发引导程序,它是针对特定主板和芯片的,OEM制造厂商或者运营商在加锁的时候就对这个引导程序做修改,比如魅族就是修改了引导程序,所以刷不了机。

第三步:内核

当内核完成系统设置后,在系统文件中寻找init.rc文件,并启动init进程

第四步:执行init进程

system/core/init/init.cpp

int main(int argc, char** argv) {
   
......
if (is_first_stage) {
   
boot_clock::time_point start_time = boot_clock::now();
umask(0);
//创建和挂载启动所需要的文件目录
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));
chmod("/proc/cmdline", 0440);
gid_t groups[] = {
    AID_READPROC };
setgroups(arraysize(groups), groups);
mount("sysfs", "/sys", "sysfs", 0, NULL);
mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
......
}
......
//对属性服务进行初始化
property_init();
......

epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (epoll_fd == -1) {
   
PLOG(ERROR) << "epoll_create1 failed";
exit(1);
}
//用于设置子进程信号处理函数,如果子进程异常退出,init进程会调用该函
//数中设置的信号处理函数进行处理。
signal_handler_init();
......
//启动属性服务
start_property_service();
......
if (bootscript.empty()) {
   
//解析init.rc配置文件
parser.ParseConfig("/init.rc");
parser.set_is_system_etc_init_loaded(
parser.ParseConfig("/system/etc/init"));
parser.set_is_vendor_etc_init_loaded(
parser.ParseConfig("/vendor/etc/init"));
parser.set_is_odm_etc_init_loaded(parser.ParseConfig("/odm/etc/init"));
}
......
while (true) {
   
......
if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
   
am.ExecuteOneCommand();
}
if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
   
//重启死去的服务
restart_processes();
}
......
}
return 0;}
从上述代码中可以看出,init进程主要做了三件事:
  • 从上述代码中可以看出,init进程主要做了三件事:
    启动挂载了tmpfs、devpts、proc、sysfs和selinuxfs共5种文件系统,这些是系统运行时目录,也就是说只有在系统运行的时候才会存在。

  • 初始化和启动属性服务。 ServiceManager也是单独的进程在init进程启动的
    属性服务类似Windows平台上的注册表管理器,注册表中以key-value的形式来记录用户、软件的一些使用信息。即使系统或软件重启,也能够根据之前注册表中的记录,进行相应的初始化工作。

  • 解析init.rc文件,创建Zygote进程
    该文件的路径为:system/core/rootdir/init.rc。它是一个非常重要的配置文件,是由Android初始化语言编写的脚本。Android8.0对该文件进行来拆分,每个服务对应一个rc文件,启动Zygote的脚本在init.zygoteXX.rc中定义,代表多少位处理器。这里以64位为例。

system/core/rootdir/init.zygote64.rc

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks

这里我们只分析zygote进程的创建,所以只贴出了init.rc文件中的Serivice类型的语句,省略了其他语句;这是由Android初始化语言编写的。它的格式如下:
service [ ]* //名字 执行程序路径 传递参数
< option > //修饰词,影响什么时候启动,如何启动service。
< option >

上面的代码的含义就是:通知init进程创建名为zygote的进程,这个进程的执行路径为:/system/bin/app/_process64,其后面的代码是传递给app_process64的参数。class main指的是zygoteclassnamemain

init.rc中的Service类型的语句有相应的类来进行解析,Service语句采用ServiceParser来进行解析,该实现代码在system/core/init/service.app中,代码在这不再贴出,大概的解析过程就是:根据参数创建出Service对象,然后根据选项域中的内容填充Service对象,最后将该对象加入vector类型的Service链表中。(就是把上面传参要启动服务存在Vector链表中)

继续看 在init.rc中有如下代码:

......
on nonencrypted
class_start main
class_start late_start
......

class_start是Android初始化语言中的Command类型的语句,对应的函数为do_class_start,含义就是启动classname为main的Service。,从上述代码我们知道zygote的classname为main

do_class_start函数是在system/core/bin/builtins.cpp中,代码如下:

static int do_class_start(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值