AOSP Foundations
2 min read

The init Process in Detail

A deeper look at the Second Stage init, the property service, and the complex action trigger sequence.

While the First Stage init focuses purely on mounting partitions from the ramdisk, the Second Stage init is responsible for launching the massive Android user space environment.

This phase is entirely driven by the complex event loop and property system managed by the init binary.

The Property Service

One of the most powerful features managed by init is the Android Property System (often accessed via getprop and setprop in the ADB shell).

The Property System is a globally accessible, shared memory dictionary of key-value pairs (e.g., ro.build.version.release = 14).

  • Initialization: During the Second Stage, init reads the build.prop files located in /system, /vendor, and /product and securely loads them into memory.
  • Triggering Events: Properties are not just static text. They are dynamic triggers. An init.rc script can say: "Do not start the Wi-Fi daemon until the property sys.boot_completed equals 1."
# Changing a property to trigger an action (if you have root)
adb shell setprop ctl.start surfaceflinger

Actions and Services

The .rc scripts parsed by init contain two fundamental building blocks: Actions and Services.

1. Actions

Actions are sequences of commands (like mkdir, chown, write) that are executed when a specific "trigger" occurs.

on post-fs-data
    # This action triggers after the userdata partition is mounted
    mkdir /data/vendor/wifi 0770 wifi wifi
    mkdir /data/misc/camera 0770 camera camera

2. Services

Services are executable programs that init will launch as background daemon processes.

service surfaceflinger /system/bin/surfaceflinger
    class core
    user system
    group graphics drmrpc
    onrestart restart zygote

This tells init to launch the surfaceflinger binary, securely assign it to the system user, and if it crashes, init must also force restart the zygote process.

The Trigger Sequence

init does not execute actions randomly. It follows a strictly ordered, hardcoded sequence of triggers in C++ to ensure dependencies are met.

  1. early-init: Basic memory management and cgroups setup.
  2. init: General system setup.
  3. fs: Mounts the remaining file systems (if any).
  4. post-fs-data: Executed after the /data partition is mounted and decrypted. This is when native daemons can finally create their private folders.
  5. boot: This trigger signals that the base native environment is ready, and it is time to start the massive Java framework processes (the Zygote).