Today is the first day of the first lunar month, and everything is a new beginning. As we head into the New Year, we may be launching many meaningful projects, but on this special day, let’s take a look at how Android gets started.

  • Init process and init.rc
  • Init syntax Description
    • The Action with the Command
    • The Service and Option
    • Import
  • Init. rc code instance
  • conclusion

Init process and init.rc

The init process is where it all starts. On Android, all processes have an indeterminate process number, except the init process whose process number must be 1. Because this process is the first one to be systemized. Also, the init process controls the startup process of the entire system.

We know that Android can run on a variety of different platforms and devices. Therefore, the startup logic is not the same. To accommodate the needs of various platforms and devices, initialization of the init process is managed through the init.rc configuration file. Init. rc uses the Android Init Language as its syntax. The main entry to the configuration file is /init.rc, which imports other configuration files using the import keyword. In this case, we call these files init.rc.

/init.rc may import. Rc files from the following paths:

  • ${ro.hardware}. Rc Master configuration file provided by the hardware vendor
  • /system/etc/init/ Configuration file of the core system module
  • /vendor /etc/init. / SoC Configuration file provided by the SoC vendor
  • /odm /etc/init. / Configuration file provided by the device manufacturer

Init syntax Description

Init language, delimited by statements, delimited by Spaces, and started with “#” for comments. There are five types of expressions supported in the configuration file:

  • Action: Contains a series of commands
  • Command: a Command in the init language
  • Service: Service started by the init process
  • Option: configuration options for the service
  • Import: Imports other configuration files

In this case, Action and Service must have unique names.

The Action with the Command

The syntax for Action expressions is as follows:

on <trigger> [&& <trigger>]*
   <command>
   <command>
   <command>
Copy the code

Trigger is the Trigger on which the Action is executed, and when the Trigger condition is met, the command is executed. Triggers come in two categories:

  1. Event triggers: Events can be emitted by the “trigger” command or passed by the init processQueueEventTrigger()Function a
  2. Property trigger: Fires when the specified property is satisfied

An Action can have multiple property triggers, but only one event trigger. Here are some examples:

  • on boot && property:a=bFired when the “boot” event occurs and property A has a value of B
  • on property:a=b && property:c=dFired when the value of attribute A is B and attribute C is d

The Command in Action is defined by the init language. All supported commands are shown in the following table:

Command Parameter format instructions
bootchart_init Start the bootchart
chmod octal-mode path Change the access permission of a file
chown owner group path Change the owner and group of a file
class_start serviceclass Starts a service of the specified category
class_stop serviceclass Stop and disable services of a specified category
class_reset serviceclass Stops services of the specified category, but does not disable them
copy src dst Copy files
domainname name Set the domain name
enable servicename Enable Indicates a disabled service
exec [seclabel[user[group]]] –command [argument] * Fork a child process to execute the specified command
export name value Exporting environment variables
hostname name Setting the host Name
ifup iterface Bring the NIC online
insmod path Installs the module at the specified path
load_all_props Load attributes from /system, /vendor, etc
load_persist_props Load persistent properties
loglevel level Set the logging level for the kernel
mkdir path [mode] [owner] [group] Create a directory
mount_all fstab [ path[-] *option] Mount the file system and import the specified. Rc file
mount type device dir [ flag] * [options] Mount a file system
powerctl Internal implementation use
restart service Restart the service
restorecon path [ path] * Set the security context for the file
restorecon_recursive path [ path] * A recursive version of Restorecon
rm path Call unlink(2) for the specified path
rmdir path Delete folders
setprop name value Setting property values
setrlimit resource cur max Specifies the rlimit of the resource
start service Start the service
stop service Stop the service
swapon_all fstab Call fs_mgr_swapon_all on the specified file
symlink target path Creating symbolic links
sysclktz mins_west_of_gmt Specifies the system clock baseline
trigger event Trigger an event
umount path Unmount Specifies the file system
verity_load_state Internal implementation use
verity_update_state mount_point Internal implementation use
wait path [ timeout ] Wait for a file to exist until time out, or return if it exists
write path content Writes to the specified file

The Service and Option

A Service is an executable that starts the init process. The service can choose to be restarted by init after it exits.

The syntax for a Service expression is as follows:

service <name> <pathname> [ <argument> ]*
   <option>
   <option>
Copy the code

Options are modifications to services that affect how and when the init process starts the service. All supported options are shown in the following table:

option Parameter format instructions
critical This service is identified as a system critical service. Exiting the service for several times will cause the system to restart to recovery mode
disabled Will not start automatically with the category, you must explicitly start
setenv name value Set environment variables for the started process
socket name type perm [user [group [seclabel]]] Create a Unix Domain Socket
user username Switch the user before performing the service
group groupname [ groupname] * Switch groups before execution
seclabel seclabel Switch secLabel before executing the service
oneshot One-time service, no need to restart after death
class name Specify the type of service
onrestart Execute the specified command when the service restarts
writepid The file… Writes the pid of the child process to the specified file

Import

Import is a keyword, not a command. You can use this keyword to load other.rc files in.rc files. The syntax is simple:

import path
Copy the code

Path can be another. Rc file or a folder. If it is a folder, all files under that folder are imported, but it does not loop through files in subdirectories.

Init. rc code instance

The AOSP contains the most basic. Rc files required by the Android system, which are located at /system/core/rootdir/.

We’ve picked up a snippet or two to get a feel for it:

# /system/core/rootdir/init.rc import /init.environ.rc import /init.usb.rc import /init.${ro.hardware}.rc import /init.usb.configfs.rc import /init.${ro.zygote}.rc on 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 ueventd on 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 ...Copy the code

This is the initial code snippet in the root /init.rc file. With that in mind, this code should be fairly straightforward. In this code:

  • Several other.rc files are introduced through the import keyword
  • Set an Action with an event of Early-init
  • Set an Action for the event init

Both events “eraly-init” and “init” are emitted by the init process.

Let’s look at another code snippet:

# /system/core/rootdir/init.zygote32.rc

service 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
Copy the code

This code defines a Service named zygote, which is started with the executable /system/bin/app_process, passing arguments: -Xzygote /system/bin –zygote –start-system-server.

Zygote, which means “fertilized egg” in Chinese, is one of the most important services in Android. This is a very suggestive name: all application processes are children of the Zygote fork, so the Zygote process is the parent of all application processes.

We’ve covered Zygote in another article, but see the Zygote process here for a review.

conclusion

Android system is an operating system across a variety of devices, from the initial development of the system to the use of the end user, which has experienced many development processes. The developers of each process have the potential to customize the system to varying degrees.

The designers of the Android system had this complexity in mind from the start, and this is evident in the design of many of the system’s modules. A good example is the system startup mechanism: there is a mechanism for developers at different stages to adjust and expand, without modifying any source code, on the premise of ensuring the order of the system’s core services.

This kind of observance of the “open and close principle” is very worthy of our learning.