Android System Architecture

Last update: 2022-01-06 03:13:05 +0800 +0800
Available translations: 日本語 / 中文(简体) / 中文(繁體)

Android uses the Linux kernel for scheduling, process isolation, device drivers, networking, and filesystems, but supplies its own native library, runtime, framework, and application model. Bionic is Android’s C library. ART executes DEX bytecode, and Binder provides the principal cross-process RPC mechanism.

Runtime and Process Creation #

Build tools compile Java or Kotlin sources to class files and then transform them into DEX code. An APK or app bundle delivery split packages DEX, resources, native libraries, signing metadata, and a manifest. ART compiles and interprets DEX as appropriate for the device and profile state; an APK is not simply an executable JAR.

init is Android’s PID 1 process. It mounts early filesystems, applies policy, starts native services, and launches Zygote. Zygote preloads common runtime classes and resources, then forks application processes on system request. The fork model shares pages until either process writes them, reducing application startup cost.

Application Isolation and Binder #

Package installation normally assigns a distinct Linux UID. File ownership and kernel credentials isolate app-private files, while SELinux applies mandatory access-control policy to processes, files, services, and Binder calls. Permissions are checked by framework and service boundaries in addition to kernel controls.

An app component launched in another package runs in the target package’s process. Binder transfers a transaction to that process and carries caller identity for permission checks. Binder object references are capabilities with lifecycle and permission semantics; an exported component or service must validate all caller-controlled arguments.

System Partitions and Updates #

Modern devices divide the operating-system image into logical, generally read-only partitions:

MountPurpose
/systemCore framework, runtime, and platform applications
/system_extSystem extensions with a platform-specific lifecycle
/productProduct and OEM customization
/vendorHardware-vendor libraries, HALs, and configuration
/odmDevice-specific vendor overlays and configuration
/vendor_dlkm, /system_dlkmDynamically loadable kernel modules
/dataWritable per-device and per-user application data
/metadataMetadata required by encryption and boot services

Dynamic partitions place logical partitions in a physical super partition. Device-mapper names such as dm-5 represent those logical block devices. A read-only image that reports near-full capacity is normally an immutable filesystem image, not a signal that user data storage is exhausted.

Verified Boot establishes a chain of trust for boot and verified partitions. A/B updates write an inactive slot and select it after verification, allowing rollback when the new slot fails to boot.

APEX and Native Interfaces #

APEX packages deliver selected low-level platform modules, including ART and Conscrypt. Android verifies and mounts APEX images below /apex early in boot; stable paths expose the active version. The vendor interface and hardware abstraction layers separate framework releases from vendor implementations, subject to the compatibility rules for a given Android release.

Writable Storage and Mount Namespaces #

/data is the principal writable partition. File-based encryption distinguishes device-encrypted storage, available before user unlock, from credential-encrypted storage, available after it. Per-user paths include /data/user/0 and /data/user_de/0.

Emulated shared storage is exposed through paths such as /storage/emulated/0 and is backed by private storage under /data/media. FUSE and mount namespaces provide each application and user an appropriate view and enforce scoped-storage access rules. /storage/self/primary resolves to the process’s primary shared-storage view; code should use platform storage APIs rather than hard-code an implementation path.

Pseudo-filesystems such as proc, sysfs, binderfs, selinuxfs, cgroupfs, and tracefs expose kernel interfaces rather than persistent files. A mount listing is device-, release-, and process-namespace-specific, so it is diagnostic evidence rather than a portable filesystem contract.

Comments

Read or comment on GitHub (sign-in required to comment)