1. General
in the previous chapter Source code details the init process of Android 9.0 § system startup process (phase I) and Source code details the init process of Android 9.0 system startup process (phase II) Explained that after the first two phases of init, the attribute system and SELinux system have been established, but the init process still needs to perform many other operations and start many key system services. However, if it is done line by line like the attribute system and SELinux system, it is a little messy and cumbersome, and it is not easy to expand, So the Android system introduces init.rc.
Init.rc is the configuration script for init process startup. This script is written in a language called Android init language. Before 7.0, the init process only parsed the init.rc file in the root directory, but with the iteration of the version, init.rc became more and more bloated. Therefore, after 7.0, some businesses of init.rc were split into / system/etc/init, /vendor/etc/init and / odm/etc/init. In this article, we will first explain some syntax of init.rc.
2. Android Init Language syntax
init.rc is a configurable initial file and a script written by Android init language. By the way, here are some extensions of Android. What other languages are similar to those unique to Android (such as AIDL, HIDL, etc.)?
init.rc file mainly contains the following five types of declarations:
- Action
- Command
- Service
- Options
- Import
the configuration code of init.rc is in system/core/rootdir/init.rc. If you are careful enough, you will find many init.xxx.rc similar files in the statistics directory. This follow-up will explain why there are so many init.xxx.rc files. as follows
init.rc file is the startup script executed after the init process is started. The file records the operations to be performed by the init process. Android provides an official reference document about init.rc. The path in the Android source code is as follows. system/core/init/README.md has a detailed description, but in English.
Android Init Language --------------------- The Android Init Language consists of five broad classes of statements: Actions, Commands, Services, Options, and Imports. All of these are line-oriented, consisting of tokens separated by whitespace. The c-style backslash escapes may be used to insert whitespace into a token. Double quotes may also be used to prevent whitespace from breaking text into multiple tokens. The backslash, when it is the last character on a line, may be used for line-folding. Lines which start with a `#` (leading whitespace allowed) are comments. System properties can be expanded using the syntax `${property.name}`. This also works in contexts where concatenation is required, such as `import /init.recovery.${ro.hardware}.rc`. Actions and Services implicitly declare a new section. All commands or options belong to the section most recently declared. Commands or options before the first section are ignored. Services have unique names. If a second Service is defined with the same name as an existing one, it is ignored and an error message is logged.
. rc file mainly configures two things: action and service. Trigger and command are supplementary to action and options are supplementary to service. Action, trigger and some commands form a Section; Service plus some options also form a Section rc file is composed of sections There is an import syntax in the header of the rc file, indicating that these. rc files are also included and parsed.
let's explain the five types of statements involved in rc files one by one, including teaching and learning.
2.1 Action
actions appear in the form of sections. Each Action Section can contain several commands. A Section has only a start tag but no clear end tag, that is, it ends the "previous Section" with the start of the "next Section". Here, it should be noted that actions can be repeated, but will be merged in the end.
the last example shows that in fact, the Action in rc is an Action list starting with the keyword "on":
on early-init #Action type statement # Set init and its forked children's oom_adj. write /proc/1/oom_score_adj -1000 #Command statement # Disable sysrq from keyboard write /proc/sys/kernel/sysrq 0 # Set the security context of /adb_keys if present. restorecon /adb_keys
an Action needs a trigger to trigger it. This will be seen in the code parsing the init process. Once the trigger conditions are met, the Action will be added to the end of the execution queue.
the statement format of Action type is:
on <trigger> [&& <trigger>]* #set trigger <command> #The command to execute after the action is triggered <command> <command>
starting with on, trigger is the judgment condition, and command is to perform some specific operations. When the trigger condition is met, these commands are executed.
trigger conditions can be divided into the following situations:
-
The trigger here can be a string, such as
on early-init #Indicates that it is triggered when trigger early init or queueeventtrigger ("early init") is called
-
The trigger here can also be an attribute, such as
on property:sys.boot_from_charger_mode=1 #Indicates when sys.boot_ from_ charger_ The value of mode is passed through property_ Triggered when set is set to 1 class_stop charger trigger late-init on property:sys.init_log_level=* # *Indicates an arbitrary value trigger loglevel ${sys.init_log_level}
-
The trigger conditions here can be multiple. Use & & to connect, such as
on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file #Indicates that the trigger is triggered when all three conditions are met # A/B update verifier that marks a successful boot. exec_start update_verifier_nonencrypted start netd start zygote start zygote_secondary
-
command refers to some specific operations, such as:
mkdir /dev/fscklogs 0770 root system //new directory class_stop charger //Termination of service trigger late-init //Trigger late init
2.2 service
Service also appears in the form of sections, where each Service Section can contain several options. A Section has only a start mark but no clear end mark, that is, it ends the "previous Section" with the start of the "next Section". One thing to note here is that the Service cannot have duplicate names.
to illustrate with the previous example, in fact, the service in rc is a service list starting with the keyword "service":
## Daemon processes to be run by init. ## service ueventd /sbin/ueventd class core critical seclabel u:r:ueventd:s0 shutdown critical
Service refers to a Service program that will be executed through the start command. And judge whether the Service needs to be restarted automatically when exiting according to the option parameter.
The statement structure of Service is as follows:
service <name> <pathname> [ <argument> ]* #< service name > < executor Path > < pass parameters > <option> #option is a modification of service, which affects when and how to start the service <option> <option> ...
from the above interpretation of Action and Service, we can see that these two statements mainly use system environment variables or Linux commands to do some work at different stages of Android startup, mainly as follows:
- The action list is used to create the required directory and specify permissions for some specific files;
- The service list is used to record some sub processes that the init process needs to start. As shown in the above code, the first string after the service keyword represents the name of the service (sub process), and the second string represents the execution path of the service.
another typical example; For example:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote 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
this is configured in / init.zygote64_ The service in the 32. RC file is the startup configuration of the zygote process. Zygote is the process name, and the executable path is / system/bin/app_process64, the executable file parameter (args in the main function of the executable program) is
-Xzygote /system/bin –zygote –start-system-server –socket-name=zygote
the following option s are some service configurations. For example, class main indicates that the class is main, which is equivalent to a classification. Other services can also be classified as main, and they will be started or terminated together. The service has a name and a class. Just like in work, you have a name called foxleezh, or you belong to the android department
2.3 Options
Options are the parameter configuration of Services, which will affect how and when the Service runs. For example:
-
console
console [<console>] Service Console required. Second parameter console You can set the type of console you want. The default console is/dev/console , /dev This prefix is usually ignored. For example, you need to set the console /dev/tty0 ,Then you only need to set it to console tty0
-
critical
critical express Service It's a strict model. If this Service If you exit more than 4 times in 4 minutes, the device will restart and enter recovery pattern
-
disabled
disabled express Service Can't class Can only be started in the form of name Start in the form of
-
setenv
setenv <name> <value> stay Service Set at startup name-value Environment variables for
-
socket
socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ] Create a unix Domain socket,Name is/dev/socket/name , And will fd Return to Service. type Only "dgram", "stream" or "seqpacket".User and group The default value is 0. 'seclabel' This is it socket of SELinux Security context,Its default value is service Security policy or security context based on its executable.Its corresponding local implementation is libcutils of android_get_control_socket
-
file
file <path> <type> Open a file and fd Return to this Service. type Only "r", "w" or "rw". Its corresponding local implementation is libcutils of android_get_control_file
-
user
user <username> At startup Service Former general user Change to username,Default startup user by root(Perhaps the default is none).stay Android M Version, if a process wants to have Linux capabilities(amount to Android You can only set this value. Before, a program wanted to have Linux capabilities,You must first root Run as and demote to the desired uid.Now there is a new mechanism to replace it, It passes fs_config Allow vendors to assign special binaries Linux capabilities. This mechanism is documented in http://source.android.com/devices/tech/config/filesystem.html. When using this new mechanism, The program can pass user Select the required parameters uid,Without the need to root Permission run. stay Android O Version, the program can capabilities Refer to the following for the required capabilities for parameter direct application capabilities explain
-
group
group <groupname> [ <groupname>\* ] At startup Service Former general group Change to first groupname,first groupname It must be, The default value is root(Maybe the default is none), the second one groupname Can not be set, used to append groups (via setgroups).
-
capabilities
capabilities <capability> [ <capability>\* ] At startup Service Shi Jiang capabilities Set to capability. 'capability' Can't be"CAP_" prefix, like "NET_ADMIN" or "SETPCAP". reference resources http://man7.org/linux/man-pages/man7/capabilities.7.html , There are capability Description of.
-
seclabel
seclabel <seclabel> At startup Service Former general seclabel Set to seclabel. Mainly used in rootfs Started on service,such as ueventd, adbd. Running on a system partition service Have your own SELinux If the security policy is not set, it is used by default init Security policy for.
-
oneshot
oneshot No restart after exit
-
class
class <name> [ <name>\* ] by Service appoint class name. Same class Nameless Service Will be started or exited together,The default value is"default",the second name It can not be set, be used for service group.
-
animation
animation class animation class It mainly includes services for startup animation or shutdown animation service. They are started very early and do not exit until the last step of shutdown. They do not allow access/data Directories, they can check/data Directory, but cannot be opened/data Directory, and you need to/data It works normally when it can't be used.
-
onrestart
onrestart stay Service Execute command on restart.
-
writepid
writepid <file> [ <file>\* ] When Service call fork The of the child process pid Write to specified file. be used for cgroup/cpuset Use of when/dev/cpuset/There are no files below but ro.cpuset.default When the value of is not empty,take pid The value of is written to/dev/cpuset/cpuset_name/tasks In the file
-
priority
priority <priority> Set process priority. stay-20~19 The default value is 0,Can pass setpriority realization
-
namespace
namespace <pid|mnt> When fork this service When, set pid or mnt sign
-
oom_score_adjust
oom_score_adjust <value> Set the of child processes /proc/self/oom_score_adj The value of is value,stay -1000 ~ 1000 between.
-
Triggers
Triggers Triggers Is a string. When some events occur and meet this condition, some actions Will be executed Triggers Divided into events Trigger And properties Trigger event Trigger from trigger Command or QueueEventTrigger Method trigger.Its format is a simple string, such as'boot' or 'late-init'. attribute Trigger Is triggered when the property is set or changed. Format is'property:<name>=<value>'or'property:<name>=*',It will be in init Triggered when initializing and setting properties. attribute Trigger Defined Action There may be multiple trigger modes, but the event Trigger Defined Action There may be only one trigger mode For example: on boot && property:a=b Defined action The trigger condition is, boot Trigger Trigger, and properties a The value of is equal to b on property:a=b && property:c=d There are three ways to trigger this definition: On initialization, the property a=b,attribute c=d. In properties c=d Properties in the case of a Changed to b. A In properties a=b Properties in the case of c Changed to d.
2.4 Command
Command is usually associated with Action and generally represents some specific operations. It usually completes relevant operations with Linux commands, such as:
-
bootchart
bootchart [start|stop] Start or terminate bootcharting. This appears in init.rc File, but only in/data/bootchart/enabled Only valid when the file exists, Otherwise it won't work
-
chmod
chmod <octal-mode> <path> Modify file read and write permissions
-
chown
chown <owner> <group> <path> Modify file owner or user group
-
class_start
class_start <serviceclass> Start all to serviceclass Named not started service(service There is one name,There's one, too class,there serviceclass namely class,class_start And the back start There are two ways to start, class_start yes class Form start, start yes name Formal start)
-
class_stop
class_stop <serviceclass> Terminate all to serviceclass Named running service
-
class_reset
class_reset <serviceclass> Terminate all to serviceclass Named running service,But do not disable them. They can be used later class_start restart
-
copy
copy <src> <dst> Copy a file, and write Similar, more suitable for binary or larger files. about src,From linked files world-writable or group-writable Replication is not allowed. about dst,If the target file does not exist, the default permission is 0600,If it exists, overwrite it
-
domainname
domainname <name> Set domain name
-
enable
enable <servicename> A disabled service Set to available. If this service If it is running, it will restart. Generally used in bootloader Set properties when, and then start a service,such as on property:ro.boot.myfancyhardware=1 enable my_fancy_service_for_my_fancy_hardware exec [ <seclabel> [ <user> [ <group>\* ] ] ] -- <command> [ <argument>\* ] Create a new child process and run a command with the specified parameters. This command specifies seclabel(Security Policy), user(owner),group(User group). You can't run other commands until this command is run, seclabel Can be set to - Indicates the default value, argument Represents the attribute value. Until the child process is created, init The process continues.
-
exec_start
exec_start <service> Start a service,Only when the execution result returns, init Process can continue. This and exec Similar, just change the settings of a bunch of parameters to service Defined in
-
export
export <name> <value> Setting environment variables name-value. This environment variable will be used by all started service inherit
-
hostname
hostname <name> Set host name
-
ifup
ifup <interface> Open the specified network interface
-
insmod
insmod [-f] <path> [<options>] install path Module under, specifying parameters options. -f Indicates a forced installation, even if it is currently installed Linux Kernel version does not match
-
load_all_props
load_all_props load/system, /vendor And other attributes under the directory. This is used in init.rc in
-
load_persist_props
load_persist_props load/data Persistent properties under. This is used in init.rc in
-
loglevel
loglevel <level> Set the log output level, level Indicates the level
-
mkdir
mkdir <path> [mode] [owner] [group] Create a directory, path Is the path, mode Is read-write permission. The default value is 755,owner Is the owner, default root,group Is a user group, The default value is root.If the directory already exists, overwrite their mode,owner Other settings
-
mount_all
mount_all <fstab> [ <path> ]\* [--<option>] When triggered manually "early" and "late"When, call fs_mgr_mount_all Functions, specifying fstab The configuration file and import it into the specified directory.rc file Details can be viewed init.rc Relevant definitions in the document
-
mount
mount <type> <device> <dir> [ <flag>\* ] [<options>] stay dir A directory named device Equipment _flag include "ro", "rw", "remount", "noatime", ... options include"barrier=1","noauto_da_alloc", "discard", ... Separate with commas, e.g barrier=1,noauto_da_alloc
-
restart
restart <service> Restart one after termination service,If this service Do nothing just after being restarted. If it is not running, start it
-
restorecon
restorecon <path> [ <path>\* ] Restores the security context of files in the specified directory.the second path Is a security policy file. The specified directory does not need to exist because it only needs to be init Correct marking in
-
restorecon_recursive
restorecon_recursive <path> [ <path>\* ] Recursively recover the security context under the specified directory, the second path Is the security policy file location
-
rm
rm <path> call unlink(2)Delete specified file. Best use exec -- rm ...Instead, this ensures that the system partition is mounted
-
rmdir
rmdir <path> call rmdir(2) remove directory specified
-
setprop
setprop <name> <value> set a property name-value
-
setrlimit
setrlimit <resource> <cur> <max> Specifies the resource limit for a process
-
start
start <service> Start a non running service
-
stop
stop <service> Terminate a running service
-
swapon_all
swapon_all <fstab> call fs_mgr_swapon_all,appoint fstab configuration file.
-
symlink
symlink <target> <path> stay path Create next point target Link to
-
sysclktz
sysclktz <mins_west_of_gmt> Reset system base time(Set to 0 if it is Greenwich mean time)
-
trigger
trigger <event> Trigger event event,By one action Trigger to another action queue
-
umount
umount <path> Uninstall specified path File system for
-
verity_load_state
verity_load_state The internal implementation is load dm-verity State of
-
verity_update_state
verity_update_state <mount-point> The internal implementation is setup dm-verity And set partition.mount-point.verified Properties of. be used for adb Remount, because fs_mgr It cannot be set directly.
-
wait
wait <path> [ <timeout> ] Check whether the specified path exists. Return if found,You can set the timeout. The default value is 5 seconds
-
wait_for_prop
wait_for_prop <name> <value> wait for name Property is set to value,If name Once the value of is set to value,Continue now
-
write
write <path> <content> open path File under and use write(2)write in content content. If the file does not exist, it will be created, and if it exists, it will be overwritten
2.5 Imports
The import keyword is not a command, but if a. rc file contains it, it will immediately parse the section in it.
as we mentioned earlier, there are other types of init.xxx.rc under the system/core/rootdir file directory. How to load these RC files is the credit of import. Import is used to import other init... RC, such as import /init.${ro.hardware}.rc.
usage is as follows:
import <path> analysis path Lower.rc File, including the configuration of the current file. If path It's a directory. All the files in this directory.rc Files are parsed, but not recursive, import It is used in the following two places: 1.Resolve on initialization init.rc file 2.stay mount_all Time resolution{system,vendor,odm}/etc/init/And so on.rc file
Examples are as follows:
import /init.environ.rc import /init.usb.rc import /init.${ro.hardware}.rc import /vendor/etc/init/hw/init.${ro.hardware}.rc import /init.usb.configfs.rc import /init.${ro.zygote}.rc import /init.xiriservice.rc
/ init.rc is the most important. RC file. It is loaded by the init process during initialization and is mainly responsible for system initialization. It will import / init.${ro.hardware}.rc, which is the main. RC file provided by the system level core manufacturer
when the DoFirstStageMount statement is executed, the init process will load all files in the / {system,vendor,odm} directory. Of course, it also includes rc files in the corresponding directory. After the file system is mounted, these directories will serve Actions and Services. This is also an optimization made by Google to divide levels and target different developers at different development stages.
the init.rc functions of the above three directories for extension are as follows:
- /system/etc/init / used for the system itself, such as SurfaceFlinger, MediaService, and logcatd
- /vendor/etc/init / is used for SOC (system level core vendors, such as Qualcomm) to provide them with some core functions and services
- /odm/etc/init / used by equipment manufacturers (odm customized manufacturers, such as Huawei and Xiaomi) to provide some core functions and services for their sensors or peripherals
3. Summary
this article explains the syntax rules of the Android startup file init.rc. The next article will analyze how the init process parses the startup configuration file.