December 17, 2025
5 min read

The Init Process in Android (AOSP) – Complete Guide

AOSP
Android
Init
Android booting process
SSamir Dubey
Samir Dubey

AOSP Engineer

When you power on an Android device, a fascinating sequence unfolds before your home screen appears. At the heart of this journey lies the **Init process** – the very first userspace process (PID 1) that Android launches.

🔑 The Init Process in Android (AOSP) – Complete Guide

When you power on an Android device, a fascinating sequence unfolds before your home screen appears. At the heart of this journey lies the Init process – the very first userspace process (PID 1) that Android launches.

Init is more than just “booting stuff up”; it’s the brain of the Android boot process, responsible for setting up filesystems, starting daemons, enforcing security, and ultimately enabling the Android runtime.

In this guide, we’ll cover everything you need to know about:

  • What the Init process is in Android
  • The Init language used in configuration
  • Key use cases and best practices
  • The Android boot timeline with Init internals
  • A sample init.rc walkthrough
  • Common mistakes and FAQs

Let’s dive in 🚀


🚀 What is the Init Process in Android?

On Linux-based systems, the first process started by the kernel is init. Android extends this with a custom implementation located in AOSP (system/core/init/).

Roles of Init in Android:

  • Mounts essential filesystems (/dev, /proc, /sys)
  • Loads and applies SELinux policies
  • Starts system daemons (e.g., logd, servicemanager, netd)
  • Launches Zygote (the Android app runtime)
  • Runs device- and vendor-specific initialization scripts

👉 Without Init, your phone would never get past the boot screen.


📜 The Init Language in Android

Unlike traditional Linux init scripts (which use shell), Android uses a custom declarative language with .rc configuration files (init.rc, init.${hardware}.rc, vendor rc files).

Key elements of Init language

  1. Actions – Triggered by events
on boot
    start zygote
  1. Services – Define long-running daemons
service surfaceflinger /system/bin/surfaceflinger
    class core
    user system
  1. Options – Modify service behavior
service myservice /system/bin/mybinary
    oneshot
    disabled
  1. Imports – Include other rc files
import /init.${ro.hardware}.rc

This makes the system modular and easier to configure per device or vendor.


📂 Location of Init Files

  • Core init file: /system/etc/init/hw/init.rc
  • Device-specific: /init.${hardware}.rc (e.g., init.qcom.rc)
  • Vendor-specific: /vendor/etc/init/

These files together describe how the device boots.


🕒 Where Init Fits in the Boot Process

Here’s a timeline of the Android boot flow:

📌 Bootloader -> Kernel -> Init (PID 1) -> Zygote -> System Services -> Home Screen


🔎 Expanded View with Init Internals

Below is a diagram showing what happens inside Init:

  • Mount filesystems
  • Load SELinux policies
  • Start core daemons (logd, servicemanager)
  • Launch Zygote (Java runtime)
  • Run vendor/device init.rc actions

📷 (Diagram inserted here – our timeline with orange Init + gold internals)


🛠️ Best Use Cases of Init & Init Language

  1. Starting core system services

    • Example: Media server, camera daemon, display compositor
  2. Setting system properties

setprop persist.sys.locale en-US
  1. Assigning permissions to devices
chmod 0666 /dev/ttyUSB0
  1. Running one-time initialization tasks
on post-fs-data
    mkdir /data/myapp 0770 system system

✅ Best Practices

  • Use init only for system-level setup (not app logic).
  • Split configs into hardware/vendor-specific rc files.
  • Prefer properties over hardcoded values.
  • Debug with logs:
adb logcat -b all | grep init

⚠️ Common Mistakes

❌ Adding app-level services in init – not the right place. ❌ Using complex shell logic inside rc – slows boot. ❌ Ignoring SELinux labels – leads to “permission denied.” ❌ Forgetting disabled -> services restart in loops.


📖 Sample init.rc Walkthrough

Here’s a real-world snippet from a simplified init.rc:

# Import hardware-specific configs
import /init.${ro.hardware}.rc

# Boot-time actions
on boot
    setprop persist.sys.locale en-US
    setprop persist.sys.timezone Asia/Kolkata
    mkdir /data/myapp 0770 system system

# Logging daemon
service logd /system/bin/logd
    class core
    user log
    group log readproc
    seclabel u:r:logd:s0

# Zygote service
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 restart media
    onrestart restart netd

Explanation:

  • Imports: include device-specific init files.
  • Actions (on boot): run at boot, set properties, create directories.
  • Service logd: defines the logging daemon with security context.
  • Service zygote: launches Android runtime (critical for apps).

👉 Without Zygote, no apps can run.


🔍 Advanced Topics

  • Property triggers:
on property:sys.boot_completed=1
    start myservice
  • Class-based startup: groups services (core, main, late_start) to control boot phases.

  • Init & SELinux: Init enforces security labels for every service, ensuring Android’s sandbox model.


📌 Summary

  • Init process = first userspace process (PID 1), runs after kernel.
  • Init language = declarative config system (.rc files) for services and actions.
  • Use cases: start daemons, set properties, manage permissions.
  • Best practices: keep configs modular, respect SELinux, avoid app-level hacks.

👉 Next time you boot your phone, remember: Init quietly orchestrates everything behind the scenes.


💡 Try it yourself: Run these commands on a device/emulator:

adb shell ls /system/etc/init/ /vendor/etc/init/
adb shell cat /system/etc/init/hw/init.rc | less

Explore how your device’s boot sequence is defined.


That’s it – now you know what Init is, how Init language works, and why it’s crucial in AOSP. 🚀

Comments (0)

Sign in to join the conversation

Loading comments...