Android系统启动时,第一个要执行的程序就是/system/core/init/init.rc脚本。这个脚本被称为“init脚本”,是Android启动过程中最重要的一部分。它负责初始化各种系统组件、启动系统服务,以及处理开机自启动的应用程序等。
一、init.rc脚本的结构
init.rc脚本的结构非常简单,它由一系列的Action和Command组成,如下所示:
# This file is read once by the init process to set up the system environment # variables and services. … on early-init … on init … on post-fs … on boot … on property:sys.boot_completed=1 … on property:dev.bootcomplete=1 … on property:selinux.restorecon_recursive=1 …
这些Action和Command分别代表不同的执行环节,在系统启动过程中按照一定的顺序执行。具体来说,它们的含义如下:
- on early-init:系统从内核启动后马上执行的内容
- on init:文件系统被挂载后、Zygote启动之前的内容
- on post-fs:Zygote启动之后的内容
- on boot:启动所有应用程序之前的内容
- on property:sys.boot_completed=1:启动后等待系统初始化完成时执行的内容
- on property:dev.bootcomplete=1:启动后等待设备初始化完成时执行的内容
- on property:selinux.restorecon_recursive=1:在SELinux恢复标签之后执行的内容
这些环节依次执行,保证了系统各个组件的正确初始化和启动顺序。
二、Action和Command
2.1 Action
Action是Init语言中最基本的控制结构,它支持if语句、while语句、switch语句等语法。Action的语法如下:
action_name { command command command }
其中,action_name是一个标志符,用来标识一个Action,在后面的Trigger中可以进行引用;command则表示Action要执行的命令。
一个Action可以包含多个Command,它们按照从上到下的顺序逐个执行。每个Command都可以是一个Shell命令,也可以是系统服务管理命令(如start、stop、restart等)。
2.2 Command
Command是Action的组成部分,它指定了Init进程要执行的命令。Command语法如下:
command [args]
其中,command可以是Shell命令,也可以是系统服务管理命令。
在Init脚本中,常见的命令包括:
- start service_name:启动一个系统服务
- stop service_name:停止一个系统服务
- restart service_name:重启一个系统服务
- write filename string:将一个字符串写入文件
- setprop property_name property_value:设置一个系统属性
三、实例代码片段
下面是一个Init脚本中的代码片段,它通过一个Action来启动Zygote进程:
on init # Set up some memory management write /proc/sys/vm/overcommit_memory "1" # Create some mountpoints and tmpfs filesystems mkdir /dev/socket 0775 system system mkdir /dev/log 0777 root log mkdir /dev/cpuctl mount tmpfs tmpfs /dev/cpuctl mode=0770,gid=1000 mkdir /dev/cpuctl/bg_non_interactive mkdir /dev/cpuctl/fg_boost mkdir /dev/cpuctl/fg_non_interactive mount cgroup none /sys/fs/cgroup/cpuacct,cpu mode=0755 mount cgroup none /sys/fs/cgroup/memory mode=0755 # ...省略其他内容... # Start up the system start ueventd class_start default start servicemanager start vold start zygote start media
以上代码片段,先创建了一些挂载点和临时文件系统,然后使用start命令启动了一些系统服务,最终启动了Zygote进程。
四、总结
Android Init.rc脚本是Android系统启动过程中最重要的一部分。它通过一系列的Action和Command来负责系统初始化、系统服务启动和应用程序管理等任务。了解Init.rc的语法和结构对于深入理解Android系统启动过程和进行系统定制具有重要意义。