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.rcwalkthrough - 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
- Actions – Triggered by events
on boot
start zygote
- Services – Define long-running daemons
service surfaceflinger /system/bin/surfaceflinger
class core
user system
- Options – Modify service behavior
service myservice /system/bin/mybinary
oneshot
disabled
- 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.rcactions
📷 (Diagram inserted here – our timeline with orange Init + gold internals)
🛠️ Best Use Cases of Init & Init Language
-
Starting core system services
- Example: Media server, camera daemon, display compositor
-
Setting system properties
setprop persist.sys.locale en-US
- Assigning permissions to devices
chmod 0666 /dev/ttyUSB0
- 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. 🚀