Source code details the init.rc syntax rules of Android 9.0(P) system startup process

Posted by adige72 on Mon, 08 Nov 2021 23:52:28 +0100

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 similar files in the statistics directory. This follow-up will explain why there are so many 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/ 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
`${}`. 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

    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
    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

  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:

  1. 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
  2. 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
  3. disabled

    express Service Can't class Can only be started in the form of name Start in the form of
  4. setenv

    setenv <name> <value>
    stay Service Set at startup name-value Environment variables for
  5. 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
  6. 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
  7. 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 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
  8. 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).
  9. 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 ,
    There are capability Description of.
  10. 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.
  11. oneshot

    No restart after exit
  12. 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.
  13. 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.
  1. onrestart

    stay Service Execute command on restart.
  2. 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
  3. priority

    priority <priority>
    Set process priority. stay-20~19 The default value is 0,Can pass setpriority realization
  4. namespace

    namespace <pid|mnt>
    When fork this service When, set pid or mnt sign
  5. 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.
  6. 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:

  1. 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
  2. chmod

    chmod <octal-mode> <path>
    Modify file read and write permissions
  3. chown

    chown <owner> <group> <path>
    Modify file owner or user group
  4. 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)
  5. class_stop

    class_stop <serviceclass> 
    Terminate all to serviceclass Named running service
  6. 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
  7. 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
  8. domainname

    domainname <name>
    Set domain name
  9. 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.
  10. 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
  11. export

    export <name> <value>
    Setting environment variables name-value. This environment variable will be used by all started service inherit
  12. hostname

    hostname <name> 
    Set host name
  13. ifup

    ifup <interface>
    Open the specified network interface
  14. 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
  15. load_all_props

    load/system, /vendor And other attributes under the directory. This is used in init.rc in
  16. load_persist_props

    load/data Persistent properties under. This is used in init.rc in
  17. loglevel

    loglevel <level>
    Set the log output level, level Indicates the level
  18. 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
  19. 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
  20. 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
  21. restart

    restart <service>
    Restart one after termination service,If this service Do nothing just after being restarted. If it is not running, start it
  22. 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
  23. restorecon_recursive

    restorecon_recursive <path> [ <path>\* ]
    Recursively recover the security context under the specified directory, the second path Is the security policy file location
  24. rm

    rm <path>
    call unlink(2)Delete specified file. Best use exec -- rm ...Instead, this ensures that the system partition is mounted
  25. rmdir

    rmdir <path>
    call rmdir(2) remove directory specified
  26. setprop

    setprop <name> <value>
    set a property name-value 
  27. setrlimit

    setrlimit <resource> <cur> <max>
    Specifies the resource limit for a process
  28. start

    start <service> 
    Start a non running service
  29. stop

    stop <service>
    Terminate a running service
  30. swapon_all

    swapon_all <fstab>
    call fs_mgr_swapon_all,appoint fstab configuration file.
  31. symlink

    symlink <target> <path>
    stay path Create next point target Link to
  32. sysclktz

    sysclktz <mins_west_of_gmt>
    Reset system base time(Set to 0 if it is Greenwich mean time)
  33. trigger

    trigger <event>
    Trigger event event,By one action Trigger to another action queue
  34. umount

    umount <path>
    Uninstall specified path File system for
  35. verity_load_state

    The internal implementation is load dm-verity State of
  36. 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. 
  37. wait

    wait <path> [ <timeout> ]
    Check whether the specified path exists. Return if found,You can set the timeout. The default value is 5 seconds
  38. 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
  39. 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 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.

Topics: Java Android Apache