Android系统启动流程4---init进程的工作流程

概况:

  1. 启动init进程
  2. 运行init.rc
  3. 启动zygote服务
  4. Zygote fork的第一个进程——SystemServer
  5. SystemServer启动系统服务

1. linux启动第一个应用程序init

kernel\init\main.c
static int __ref kernel_init(void *unused)
{
    
    
	int ret;
	kernel_init_freeable();
	/* need to finish all async __init code before freeing the memory */
	async_synchronize_full();
	free_initmem();
	mark_readonly();
	system_state = SYSTEM_RUNNING;
	numa_default_policy();
	flush_delayed_fput();
	if (ramdisk_execute_command) {
    
    
		ret = run_init_process(ramdisk_execute_command);
		if (!ret)
			return 0;
		pr_err("Failed to execute %s (error %d)\n",
		       ramdisk_execute_command, ret);
	}
	/*
	 * We try each of these until one succeeds.
	 *
	 * The Bourne shell can be used instead of init if we are
	 * trying to recover a really broken machine.
	 */
	if (execute_command) {
    
    
		ret = run_init_process(execute_command);
		if (!ret)
			return 0;
		pr_err("Failed to execute %s (error %d).  Attempting defaults...\n",
			execute_command, ret);
	}
	if (!try_to_run_init_process("/sbin/init") ||
	    !try_to_run_init_process("/etc/init") ||
	    !try_to_run_init_process("/bin/init") ||
	    !try_to_run_init_process("/bin/sh"))
		return 0;
 
	panic("No working init found.  Try passing init= option to kernel. "
	      "See Linux Documentation/init.txt for guidance.");
}

init进程启动前的工作可以参考:https://blog.csdn.net/weixin_40535588/article/details/121221371

2. android 的init进程

不同平台的init进程不太一样,比如android的init进程源代码是放在system\core\init\init.cpp
而linux系统的一般是放在busybox的init.c中
我们先看android的init进程做了什么工作

init进程主要提供以下几个功能:

挂载文件系统、生成部分设备节点、创建目录
属性服务
处理子进程终止
分析和运行init.rc(等等rc文件)

init.rc脚本是由Android中linux的第一个用户级进程init进行解析的。

init.rc的语法参考https://blog.csdn.net/wangzaieee/article/details/84774298

最后运行了init.rc启动了安卓系统所需要的应用进程和服务

3. linux的init进程

linux系统,即大部分的嵌入式系统用的配置文件不是init.rc,而是inittab,但作用差不多,都是为了启动服务,linux系统的init进程的代码是放在busybox里init.c里

busybox被大家比作瑞士军刀,主要是它以很小的体积提供给我们很多很有用的shell指令。但是这里我们要关注的是busybox的init。

除了基本的命令之外,BusyBox还支持init功能,如同其它的init一样,busybox的init也是完成系统的初始化工作,关机前的工作等等,我们知道在Linux的内核被载入之后,机器就把控制权转交给内核,linux的内核启动之后,做了一些工作,然后找到根文件系统里面的init程序,并执行它,BusyBox的init进程会依次进行以下工作:

  1. 为init设置信号处理过程

  2. 初始化控制台

  3. 剖析/etc/inittab文件

  4. 执行系统初始化命令行,缺省情况下会使用/etc/init.d/rcS

  5. 执行所有导致init暂停的inittab命令(动作类型:wait)

  6. 执行所有仅执行一次的inittab(动作类型:once)

参考:https://blog.csdn.net/yangxuan12580/article/details/51372632

4. init.rc和inittab的关系

搭载linux内核的有很多平台,当内核起来后,会启动根文件系统,不同的平台,根文件系统的init进程不太一样,但是作用都是为了启动各自的服务

例如:

  • 嵌入式系统的init进程代码:busybox里的init.c,配置文件是inittab
  • android的init进程代码:system\core\init\init.cpp,配置文件是init.rc ubuntu
  • ubuntu也会使用busybox的init进程,但是有些配置文件已经淘汰inittab,Ubuntu从6.10开始,采用Upstart替代了传统的init进程(/etc/inittab)

5. android 的init.rc的工作

参考:https://blog.csdn.net/zhonglunshun/article/details/78615980

详细可以阅读代码/system/core/rootdir/init.rc

1、sh/bash:
#service console /system/bin/sh
service console /system/bin/bash
   console 
sh和bash服务是控制台服务,其实它是从NetBSD移植过来的,因此它的命令也是比较有限的,不过作为嵌入式系统,使用shell的机会不多.
sh服务的源码位置:system/core/sh;
sh和bash服务使用flex工具生成词法分析代码,使用bison生成语法分析代码.

2、adbd:
#adbd is controlled by the persist.service.adb.enable system property
service adbd /sbin/adbd
   disabled
adbd服务的源码位置:system/core/adb;
adbd服务使用c语言实现,它不但可以在虚拟机里运行,也可以在实际的设备里运行.adbd服务是adb调试系统中的一部分,整个adb调试系统包括有三部分:手机运行的adbd服务、PC运行的服务器、PC运行的客户端.当android启动时,就运行adbd服务,创建一个调试端口,这样就可以让开发机器上的服务器连接过来,通过这个连接就可以发送调试信息给服务器,也可以接收到外面发送过来的调试命令.

3、servicemanager:
service servicemanager /system/bin/servicemanager
   user system
   critical
   onrestart restart zygote
   onrestart restart media
servicemanager服务的源码位置:frameworks/base/cmds/servicemanager;
servicemanager服务的作用主要是服务管理,所谓的服务管理其实就是获取服务、检查服务、添加服务、枚举所有服务.服务管理器是一个容器管理器,方便服务添加、调用和删除.在应用层的程序,都向这个服务管理器获取需要使用的服务,而所有提供服务的程序,都向这个服务器管理器注册自己的服务.服务管理器是应用程序与服务沟通的桥梁.

4、vold:
service vold /system/bin/vold
   socket vold stream 0660 root mount
vold服务的源码位置:system/core/vold;
vold服务的主要作用是负责完成系统的动态卷管理,比如CD-ROM、U盘、MMC卡等外存储的管理.当有这外存储设备插入时,就需要监视这种变化,并加载相应的驱动程序,然后报告给系统和应用程序有新存储设备可以使用.
vold处理过程大致分为三步:
1).创建链接:
在vold作为一个守护进程,一方面接受驱动的信息,并把信息传给应用层;另一方面接受上层的命令并完成相应.所以这里的链接一共有两条:
(1)vold socket: 负责vold与应用层的信息传递;
(2)访问udev的socket: 负责vold与底层的信息传递;
这两个链接都是在进程的一开始完成创建的.
2).引导:
这里主要是在vold启动时,对现有外设存储设备的处理.首先,要加载并解析vold.conf,并检查挂载点是否已经被挂载; 其次,执行MMC卡挂载; 最后,处理USB大容量存储.
3).事件处理:
这里通过对两个链接的监听,完成对动态事件的处理,以及对上层应用操作的响应.

5、nexus:
service nexus /system/bin/nexus
   socket nexus stream 0660 root system
   disabled
nexus服务的源码位置:system/core/nexus;
nexus服务的主要作用就是监听网络命令,提供网络管理的功能.

6、zygote:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
   socket zygote stream 666
   onrestart write /sys/android_power/request_state wake
   onrestart write /sys/power/state on
   onrestart restart media
zygote服务的源码位置:frameworks/base/cmds/app_process;
zygote服务主要作用就是创建一个服务监听用户的命令,并且根据用户的命令创建应用程序运行.称为Android运行时环境虚拟机;

7、mediaserver:
service media /system/bin/mediaserver
   user media
   group system audio camera graphics inet net_bt net_bt_admin
mediaserver服务的源码位置:frameworks/base/media/mediaserver
mediaserver服务是多媒体服务的守护进程,负责多媒体/照相机/音频等三项服务.

8、bootanimation:
service bootanim /system/bin/bootanimation
   user graphics
   group graphics
   disabled
   oneshot
bootanimation 服务的源码位置:frameworks/base/cmds/bootanimation;
bootanimation服务是开机动画,主要用来加载动画资源.

9、dbus:
service dbus /system/bin/dbus-daemon --system --nofork
   socket dbus stream 660 bluetooth bluetooth
   user bluetooth
   group bluetooth net_bt_admin
dbus服务的源码位置:external/dbus/bus;
dbus服务是android使用的一种特殊的进程间通讯系统.它具有面向对象接口的协议,以及应用程序之间互相发现和监视的守护进程.dbus设计用来作为用户与系统服务之间的分隔以及系统服务之间的通讯.因此,dbus通讯安全,但效率有点差.

10、installd:
service installd /system/bin/installd
   socket installd stream 600 system system
installd 服务的源码位置:frameworks/base/cmds/installd
installd服务是提供安装dex文件的服务.

11、keystore:
service keystore /system/bin/keystore /data/misc/keystore
   user keystore
   group keystore
   socket keystore stream 666
keystore服务的源码位置:frameworks/base/cmds/keystore;
keystore服务是加解密储存键值的服务.它主要作用就是验证应用程序与签名文件是否一致.

12、netd:
service netd /system/bin/netd
   socket netd stream 0660 root system
netd服务的源码位置:system/netd;
netd服务是Android专用的一个守护进程;主要负责整个系统的网络服务,包括nat、uab tethering、wifi tethering、soft ap设置,还有网络接口的add、remove、change事件的通知;在Framework层,有NetworkManagementService负责与netd服务进行通信;

13、debuggerd:
service debuggerd /system/bin/debuggerd
该服务是配合adb和adbd用于调试用的;

我们主要关注init.rc去启动zygote进程

import /init.${
    
    ro.zygote}.rc

# It is recommended to put unnecessary data/ initialization from post-fs-data
# to start-zygote in device's init.rc to unblock zygote start.
on zygote-start && property:ro.crypto.state=unencrypted
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start netd
    start zygote
    start zygote_secondary

on zygote-start && property:ro.crypto.state=unsupported
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start netd
    start zygote
    start zygote_secondary

on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start netd
    start zygote
    start zygote_secondary

zygote是受精卵的意思,它是Android中的一个非常重要的守护进程服务(Daem Service),所有的其他Dalvik虚拟机进程都是通过zygote孵化(fork)出来的。Android应用程序是由Java语言编写的,运行在各自独立的Dalvik虚拟机中。如果每个应用程序在启动之时都需要单独运行和初始化一个虚拟机,会大大降低系统性能,因此Android首先创建一个zygote虚拟机,然后通过它孵化出其他的虚拟机进程,进而共享虚拟机内存和框架层资源,这样大幅度提高应用程序的启动和运行速度。

Zygote是Android中非常重要的一个进程,和Init进程,SystemServer进程是支撑Android世界的三极。Zygote进程在Init进程中以service的方式启动的。

下一节我们来分析Zygote的启动流程和工作流程

猜你喜欢

转载自blog.csdn.net/weixin_40535588/article/details/121352614