Android系统启动:init进程与init语言
来源:互联网 发布:easybcd引导linux失败 编辑:程序博客网 时间:2024/05/16 15:10
今天是农历正月初一,一切又是全新的开始。面向新的一年,我们可能启动了许多有意义的计划,在这个有着特殊意义的日子里,让我们来一起学习一下Android系统是如何启动的。
init进程与init.rc
init进程是一切的开始,在Android系统中,所有进程的进程号都是不确定的,唯独init进程的进程号一定是1。因为这个进程是系统起来的第一个进程。并且,init进程掌控了整个系统的启动流程。
我们知道,Android可能运行在各种不同的平台,不同的设备上。因此,启动的逻辑是不尽相同的。为了适应各种平台和设备的需求,init进程的初始化工作通过init.rc
配置文件来管理。init.rc以Android Init Language作为语法,下文我们简称Android Init Language为init语言。配置文件的主入口文件是/init.rc,这个文件会通过import
关键字引入其他的配置文件。在这里,我们统称这些文件为init.rc
。
/init.rc可能import
以下路径中的.rc文件:
- /init.${ro.hardware}.rc 硬件厂商提供的主配置文件
- /system/etc/init/ 核心系统模块的配置文件
- /vendor/etc/init/ SoC厂商提供的配置文件
- /odm/etc/init/ 设备制造商提供的配置文件
init语法说明
init语言,以换行为语句分隔,以空格来为符号分隔,以“#“为注释开始。配置文件中支持五种类型的表达式:
- Action: 包含了一系列的Command
- Command: init语言中的命令
- Service: init进程启动的服务
- Option: 对于服务的配置选项
- Import: 引入其他配置文件
这其中,Action和Service需要保证名称唯一。
Action与Command
Action表达式的语法如下:
on <trigger> [&& <trigger>]* <command> <command> <command>
这里的Trigger是Action执行的触发器,当触发器条件满足时,command会被执行。触发器有两类:
- 事件触发器: 事件可以由”trigger”命令发出,也可以是init进程通过
QueueEventTrigger()
函数发出 - 属性触发器: 当指定的属性满足时触发
一个Action可以有多个属性触发器,但是只能包含一个事件触发器。下面是一些例子:
on boot && property:a=b
在”boot”事件发生时,并且属性a的值是b时触发on property:a=b && property:c=d
在属性a的值是b并且属性c的值是d时触发
Action中的Command是init语言定义的命令,所有支持的命令如下表所示:
Service与Option
Service是init进程启动的可执行程序。服务可以选择在自己退出之后,由init将其重启。
Service表达式的语法如下:
service <name> <pathname> [ <argument> ]* <option> <option>
Option是对服务的修饰,它们影响着init进程如何以及何时启动服务。所有支持的option如下表所示:
Import
import是一个关键字,并不是一个命令。可以在.rc文件中通过这个关键字来加载其他的.rc文件。它的语法很简单:
import path
path可以是另外一个.rc文件,也可以是一个文件夹。如果是文件夹,那么这个文件夹下面的所有文件都会被导入,但是它不会循环加载子目录中的文件。
init.rc代码实例
AOSP中包含了Android系统需要的最基本的.rc文件,它们位于这个路径:/system/core/rootdir/ 。
我们选取其中了一两个代码片段来了解一下:
# /system/core/rootdir/init.rcimport /init.environ.rcimport /init.usb.rcimport /init.${ro.hardware}.rcimport /init.usb.configfs.rcimport /init.${ro.zygote}.rcon early-init # Set init and its forked children's oom_adj. write /proc/1/oom_score_adj -1000 # Disable sysrq from keyboard write /proc/sys/kernel/sysrq 0 # Set the security context of /adb_keys if present. restorecon /adb_keys # Shouldn't be necessary, but sdcard won't start without it. http://b/22568628. mkdir /mnt 0775 root system # Set the security context of /postinstall if present. restorecon /postinstall start ueventdon init sysclktz 0 # Mix device-specific information into the entropy pool copy /proc/cmdline /dev/urandom copy /default.prop /dev/urandom # Backward compatibility. symlink /system/etc /etc symlink /sys/kernel/debug /d # Link /vendor to /system/vendor for devices without a vendor partition. symlink /system/vendor /vendor...
这是根目录/init.rc文件中一开始的代码片段。有了前面的讲解之后,这段代码应当还是比较好理解的。在这段代码中:
- 通过import关键字引入了其他几个.rc文件
- 设定了一个事件为early-init的Action
- 设定了一个事件init的Action
“eraly-init”和”init”这两个事件都是由init进程发出的。
下面,我们再来看另外一个代码片段:
# /system/core/rootdir/init.zygote32.rcservice zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main 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 writepid /dev/cpuset/foreground/tasks
这段代码定义了一个名称为zygote
的Service,这个服务是通过可执行命令/system/bin/app_process启动的,启动的时候传递了参数:-Xzygote /system/bin --zygote --start-system-server
。
Zygote是Android系统中一个非常重要的服务,zygote的中文意思是“受精卵“。这是一个很有寓意的名称:所有的应用进程都是由zygote
fork出来的子进程,因此zygote进程是所有应用进程的父进程。
关于Zygote,我们已经在另外一篇文章中讲解过了,参见这里Zygote进程,有兴趣的读者可以再次回顾一下。
结束语
Android系统是一个跨越了多种设备的操作系统,从最初的系统的研发到最终终端用户的使用,这其中经历了许多道的开发流程。而每一道流程的开发者都有可能对系统做不同程度的定制。
Android系统的设计者从一开始就考虑到了这种复杂性,这一点从很多系统模块的设计中很能看得出来。系统启动的机制便是一个很好的范例:这里在保证系统核心服务启动顺序的前提下,还为不同阶段的开发者预留好了便于调整和扩展的机制,并且不用修改任何的源代码。
这种对于“开闭原则”的遵守,是非常值得我们学习的。
- Android系统启动:init进程与init语言
- Linux-Android系统启动之INIT进程和system v init
- Android系统启动流程——init进程
- Android系统启动流程 四--init进程
- Android系统启动-init篇
- Android init 进程 init.rc init.*.rc
- Android init 进程 init.rc init.*.rc
- Android init 进程 init.rc init.*.rc
- android init进程 init.rc
- Android系统启动流程(一)解析init进程启动过程
- Android系统启动流程(一)解析init进程启动过程
- android init 进程分析
- Android init进程启动
- Android init进程分析
- Android init进程启动
- Android Init进程分析
- Android之Init进程
- Android Init进程分析
- 在一个已排序的循环链表中插入节点
- 使用终端编译C语言程序
- Mysql分区
- kettle变量
- JDBC数据库连接之配置文件
- Android系统启动:init进程与init语言
- 10——字符个数统计
- IDEA的一些设置
- Spark性能优化 开发调优
- etcd v3命令和API
- 欢迎使用CSDN-markdown编辑器
- 416. Partition Equal Subset Sum
- PHP版 RabbitMQ小技巧(一)用代码获得服务器上的消息队列名
- Field 'id' doesn't have a default value