概况:
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
不同平台的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启动了安卓系统所需要的应用进程和服务
linux系统,即大部分的嵌入式系统用的配置文件不是init.rc,而是inittab,但作用差不多,都是为了启动服务,linux系统的init进程的代码是放在busybox里init.c里
busybox被大家比作瑞士军刀,主要是它以很小的体积提供给我们很多很有用的shell指令。但是这里我们要关注的是busybox的init。
除了基本的命令之外,BusyBox还支持init功能,如同其它的init一样,busybox的init也是完成系统的初始化工作,关机前的工作等等,我们知道在Linux的内核被载入之后,机器就把控制权转交给内核,linux的内核启动之后,做了一些工作,然后找到根文件系统里面的init程序,并执行它,BusyBox的init进程会依次进行以下工作:
为init设置信号处理过程
初始化控制台
剖析/etc/inittab文件
执行系统初始化命令行,缺省情况下会使用/etc/init.d/rcS
执行所有导致init暂停的inittab命令(动作类型:wait)
执行所有仅执行一次的inittab(动作类型:once)
参考:https://blog.csdn.net/yangxuan12580/article/details/51372632
搭载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)
参考: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的启动流程和工作流程