Android Architecture Explained: From Linux Kernel to Apps

Android is not “Linux with a touchscreen.” It is a five-layer software stack. A modified Linux kernel sits at the bottom, a hardware abstraction layer above it, native libraries and the Android Runtime (ART) in the middle, a Java/Kotlin framework above that, and apps on top. Every tap you make travels through all of them. This guide walks the stack bottom to top, shows commands to inspect each layer with adb, and covers boot sequence, security, and troubleshooting.

Quick Takeaways

  • Kernel: Android uses a Linux kernel (GKI, Generic Kernel Image, since Android 12) plus Android-specific drivers such as Binder, ashmem/memfd, and lowmemorykiller/LMKD integration.
  • HAL: Hardware Abstraction Layer modules (HIDL/AIDL) isolate vendor drivers from the framework, so one OS image can run on many SoCs.
  • ART: The Android Runtime compiles DEX bytecode with AOT, JIT, and profile-guided compilation.
  • Framework: system_server hosts services like ActivityManagerService and PackageManagerService. Apps reach them through Binder IPC.
Layer Primary Component Language Role
5. Apps System and user apps Kotlin/Java UI and business logic
4. Framework system_server, Android APIs Java/Kotlin Services and app lifecycle
3. Runtime and Native Libs ART, Bionic, libc++, SurfaceFlinger C/C++/Java Execution and graphics
2. HAL Vendor HAL implementations C/C++ Hardware abstraction
1. Kernel Linux (GKI) + Android patches C/Rust Scheduling, memory, drivers, security

Prerequisites

Set up a debugging environment before running the commands below.

  1. Install Android SDK Platform-Tools (adb) on Linux, Windows, or macOS.
  2. On the device, enable Developer Options and USB debugging.
  3. Connect and verify:
adb devices

adb devices lists attached devices. You should see a serial number with the state device.

adb shell getprop ro.build.version.release
adb shell getprop ro.build.version.sdk

getprop reads system properties. These return the Android version and API level.

Layer 1: The Linux Kernel

Android’s foundation is the Linux kernel. It handles process scheduling, memory management, the network stack, and device drivers. Google maintains Android Common Kernels (ACKs) with Android-specific features that were once out-of-tree and are now largely upstream.

Android-Specific Kernel Features

  • Binder: The IPC driver at /dev/binder (plus /dev/hwbinder and /dev/vndbinder). Nearly all framework communication flows through it.
  • Low Memory Killer Daemon (lmkd): A userspace daemon that uses kernel PSI (Pressure Stall Information) to kill background processes before the system thrashes.
  • Wakelocks / Suspend control: Prevents the device from sleeping while work is active.
  • SELinux: Mandatory access control, enforcing since Android 5.0.
  • Control groups (cgroups): Used for CPU, memory, and freezer policies, including the app freezer for cached apps.

Generic Kernel Image (GKI)

Since Android 12, GKI separates the core kernel from vendor code. Vendors ship hardware support as loadable modules against a stable Kernel Module Interface (KMI). Google can then update the core kernel without rewriting each vendor’s fork.

Inspect the Kernel

adb shell uname -a
adb shell cat /proc/version
adb shell cat /proc/pressure/memory
adb shell ls -l /dev/binder /dev/hwbinder /dev/vndbinder
  • uname -a prints kernel version and build info.
  • /proc/pressure/memory shows PSI stall metrics that lmkd consumes.
  • The ls command confirms the three Binder device nodes exist.

Android Kernel vs. Mainline Desktop Linux

Feature Android Kernel Typical Desktop Linux
IPC Binder (primary) D-Bus over sockets
Memory pressure handling lmkd + PSI OOM killer / systemd-oomd
libc Bionic glibc / musl
Init system Android init systemd
Security model App UID sandbox + SELinux DAC + optional SELinux/AppArmor
Driver packaging GKI + vendor modules Distro kernel modules

Layer 2: Hardware Abstraction Layer (HAL)

The HAL defines standard interfaces for camera, audio, sensors, Bluetooth, and graphics. The framework calls the interface. The vendor supplies the implementation.

HAL Evolution: HIDL to AIDL

Aspect Legacy HAL HIDL Stable AIDL
Introduced Android 7 and earlier Android 8 (Project Treble) Android 11+, preferred since 13
Process model In-process .so Separate process via hwbinder Separate process via Binder
Versioning None Package versions Per-interface versioning
Status Deprecated Deprecated Recommended

Project Treble (Android 8.0) split the OS into the system partition and the vendor partition. A Vendor Interface (VINTF) manifest declares what each side provides. This is why Google can ship OS updates without waiting on every driver rewrite.

Inspect HALs

adb shell lshal
adb shell service list
adb shell ls /vendor/lib64/hw/
  • lshal lists registered HIDL services (on newer builds, much of the AIDL list shows in service list).
  • /vendor/lib64/hw/ holds HAL shared libraries on many devices.

Layer 3: Native Libraries and Android Runtime (ART)

Native Libraries

Library Purpose
Bionic Android’s libc, libm, and dynamic linker (/system/bin/linker64)
SurfaceFlinger Composites app surfaces into the display
libhwui / Skia Hardware-accelerated 2D rendering
Media stack (Codec2, NDK Media) Audio/video codecs
SQLite Embedded database used across the platform
Vulkan / OpenGL ES GPU APIs

Android Runtime (ART)

ART replaced Dalvik in Android 5.0. Apps compile to DEX (classes.dex) bytecode. ART then executes it using a hybrid strategy:

  1. Install time: Minimal or no compilation (since Android 7).
  2. First runs: The JIT compiles hot methods and records a profile.
  3. Idle and charging: dex2oat performs profile-guided AOT compilation, producing .odex, .vdex, and .art files.
  4. Cloud profiles: Play Store can ship aggregated profiles so new installs start optimized.

Control and Inspect Compilation

adb shell dumpsys package dexopt | head -n 40
adb shell cmd package compile -m speed-profile -f com.example.app
adb shell cmd package compile -m everything -f com.example.app
  • dumpsys package dexopt reports compilation state.
  • -m speed-profile compiles using the recorded profile.
  • -m everything compiles all methods (larger storage footprint, longer compile).
  • -f forces recompilation.

Layer 4: The Java/Kotlin API Framework

The framework is the set of APIs developers call. Most run inside one process: system_server.

Core System Services

Service Responsibility
ActivityManagerService (AMS) Process lifecycle, task stacks, broadcasts
WindowManagerService (WMS) Window layout and input dispatch
PackageManagerService (PMS) Install, permissions, intent resolution
PowerManagerService Wakelocks, doze, screen state
NotificationManagerService Notification posting and ranking
ConnectivityService Network selection and VPN

How Binder IPC Works

An app calls a method on a proxy object. The proxy marshals the arguments into a Parcel and sends it via ioctl() on /dev/binder. The kernel driver copies data once into the target process’s memory and wakes a thread in the service. The service executes the call and returns a reply the same way. Binder also carries the caller’s UID and PID, which the receiver uses for permission checks.

Inspect Services

adb shell dumpsys activity processes | head -n 30
adb shell dumpsys meminfo com.android.systemui
adb shell dumpsys window displays
adb shell ps -A | grep system_server
  • dumpsys <service> prints a system service’s internal state.
  • meminfo breaks down a process’s PSS memory by category.

Layer 5: Applications

Every app runs in its own Linux process under a unique UID, with its own private directory at /data/data/<package> (and /data/user/0/<package>). This is the application sandbox, enforced by Linux DAC and SELinux domains (untrusted_app).

Application Components

Component Purpose
Activity A single UI screen
Service Background or foreground work
BroadcastReceiver Responds to system or app events
ContentProvider Structured data sharing across apps

The AndroidManifest.xml declares these components and the permissions the app requests. After install, the APK lives under /data/app/.

adb shell pm list packages -3
adb shell pm path com.android.chrome
adb shell dumpsys package com.android.chrome | grep -A 20 "granted=true"
  • pm list packages -3 lists third-party apps.
  • pm path shows the APK location.
  • The dumpsys package grep shows granted permissions.

The Boot Sequence: Power Button to Home Screen

  1. Boot ROM loads the bootloader from fixed storage.
  2. Bootloader verifies and loads the kernel and ramdisk. Android Verified Boot (AVB) checks partition integrity.
  3. Kernel initializes hardware, mounts the ramdisk, and starts /init.
  4. init parses *.rc files, mounts partitions, applies SELinux policy, and starts native daemons (servicemanager, vold, lmkd, logd).
  5. zygote starts. It preloads framework classes and common resources, then waits on a socket.
  6. system_server is forked from Zygote and starts the core services.
  7. Launcher activity starts, and BOOT_COMPLETED broadcasts.

Zygote is the key optimization. Every app process is a fork of Zygote, so apps share preloaded memory pages via copy-on-write. This is why cold-starting an app is faster than loading a full runtime from scratch.

adb shell ps -A | grep -E "zygote|system_server|init"
adb shell getprop init.svc.zygote
adb logcat -b events | grep boot_progress
adb shell getprop sys.boot_completed
  • boot_progress events in the events buffer mark boot stages.
  • sys.boot_completed returns 1 once boot finishes.

Security Architecture

Mechanism What It Does Introduced
App Sandbox (UID) Isolates app data and processes Android 1.0
SELinux Mandatory access control for all processes 4.3 (enforcing in 5.0)
Verified Boot (AVB) Cryptographic check of boot chain 4.4 / AVB 2.0 in 8.0
File-Based Encryption (FBE) Per-user, per-file encryption keys 7.0
Runtime permissions User grants at use time 6.0
Scoped storage Restricts broad file access 10 / enforced 11
Hardware-backed Keystore / StrongBox Keys in TEE or secure element 6.0+
Memory tagging (MTE) Detects memory-safety bugs on supported hardware 12+

Check SELinux mode and security patch level:

adb shell getenforce
adb shell getprop ro.build.version.security_patch
adb shell getprop ro.boot.verifiedbootstate
  • getenforce should return Enforcing.
  • verifiedbootstate returns green on a locked, verified device.

Android vs. Other Mobile and Linux Platforms

Attribute Android iOS Desktop Linux
Kernel Linux (GKI) XNU (Mach + BSD) Linux
App runtime ART (DEX) + native Native ARM binaries Native / interpreters
IPC Binder XPC / Mach ports D-Bus / sockets
Primary languages Kotlin, Java, C++ Swift, Objective-C Any
Update model Treble / Mainline modules + OTA Monolithic OTA Package manager
Customization High (OEM skins, AOSP) Low Very high

Project Mainline and Modular Updates

Since Android 10, Project Mainline delivers updates to core components, such as the media codecs, ART, and networking modules, as APEX packages through Google Play. These modules live under /apex/.

adb shell pm list packages --apex-only --show-versioncode
adb shell ls /apex/
  • --apex-only lists Mainline modules and their version codes.

Troubleshooting and Real-World Scenarios

Scenario 1: Device Stuck in a Boot Loop

Symptoms: The boot animation repeats. system_server or zygote crashes.

adb logcat -b all -d > bootlog.txt
adb shell dmesg > dmesg.txt
adb shell cat /proc/last_kmsg
  • -b all captures every log buffer. -d dumps and exits.
  • On newer devices use /sys/fs/pstore/ for the last kernel panic log (requires root or recovery access).

Search for FATAL EXCEPTION, avc: denied (SELinux), or Zygote crash traces. A common cause is a corrupted /data partition or an incompatible module. Boot into recovery and choose a cache or data wipe only after backing up.

Scenario 2: App Killed in the Background

Symptoms: Background apps reload constantly on low-memory devices.

adb shell dumpsys meminfo | head -n 30
adb logcat -b events | grep -i lmk
adb shell cat /proc/pressure/memory

High some/full PSI values indicate memory pressure. The lmk events show which processes lmkd killed and why. Reduce background services, trim app memory, or check for leaks.

Scenario 3: Binder Transaction Failures

Symptoms: TransactionTooLargeException or DeadObjectException.

adb shell cat /sys/kernel/debug/binder/failed_transaction_log
adb shell cat /sys/kernel/debug/binder/state

Binder’s per-process transaction buffer is about 1 MB, shared across all in-flight transactions. Keep Intent extras and Parcel payloads small. Pass large data through files, ContentProvider, or shared memory. Debugfs may need root or a userdebug build.

Scenario 4: App Slow After Install or Update

adb shell cmd package compile -m speed-profile -f <package>
adb shell cmd package bg-dexopt-job
  • bg-dexopt-job triggers the background optimization job immediately instead of waiting for idle and charging.

Scenario 5: Performance Profiling

adb shell dumpsys gfxinfo <package> framestats
adb shell am start -W <package>/<activity>
adb shell perfetto -o /data/misc/perfetto-traces/trace -t 10s sched freq idle am wm gfx view
  • am start -W waits for launch and prints TotalTime.
  • Perfetto is the system-wide tracing tool replacing systrace. Open the output at the Perfetto UI.

Developer Checklist

  1. Test on multiple API levels. Behavior changes across versions are documented per release.
  2. Use adb shell dumpsys as the first diagnostic.
  3. Ship Baseline Profiles to cut cold-start time.
  4. Respect scoped storage and runtime permissions.
  5. Use StrictMode in debug builds to catch main-thread I/O.

FAQ

What kernel does Android use?

Android uses a modified Linux kernel, delivered as a Generic Kernel Image (GKI) since Android 12. It adds Android-specific features such as the Binder IPC driver and integration with lmkd. Check yours with adb shell uname -a.

What is the difference between Dalvik and ART?

Dalvik was the original JIT-only VM. ART, the default since Android 5.0, uses ahead-of-time compilation and, since Android 7, a hybrid of JIT, profile-guided AOT, and cloud profiles. ART gives faster startup and better battery life.

What is Zygote in Android?

Zygote is a process started by init that preloads framework classes and resources. Every app and system_server is forked from it, so they share memory pages through copy-on-write. This speeds up app launch and reduces RAM usage.

Is Android the same as Linux?

No. Android uses the Linux kernel but replaces the userspace. It uses Bionic instead of glibc, Android init instead of systemd, and Binder instead of D-Bus. Standard GNU tools and X11/Wayland desktop stacks are not included.

Hot this week

iOS Architecture Explained: Darwin, XNU, and Core Services

Learn how iOS architecture works, from the Darwin kernel and XNU to Core Services and Cocoa Touch. Read the full technical breakdown now.

Windows NT Architecture Explained: Kernel, Executive, and Subsystems

Learn how the Windows NT kernel, Executive, HAL, and subsystems work together. Inspect each layer with real commands. Read the full guide.

The Linux Kernel Explained: Architecture, Modules, and How It Boots

Learn how the Linux kernel works: its architecture, loadable modules, and full boot sequence. Includes commands, tables, and fixes. Read the guide.

The Most Secure Operating Systems: What the Evidence Shows

Compare the most secure operating systems by kernel design, patch cadence, and exploit data. See which OS fits your threat model. Read the guide.

Monitor Linux Performance: top, htop, btop, vmstat, and iostat

Learn to monitor Linux performance with top, htop, btop, vmstat, and iostat. Read every metric, spot bottlenecks, and fix them. Start tuning now.

Topics

iOS Architecture Explained: Darwin, XNU, and Core Services

Learn how iOS architecture works, from the Darwin kernel and XNU to Core Services and Cocoa Touch. Read the full technical breakdown now.

Windows NT Architecture Explained: Kernel, Executive, and Subsystems

Learn how the Windows NT kernel, Executive, HAL, and subsystems work together. Inspect each layer with real commands. Read the full guide.

The Linux Kernel Explained: Architecture, Modules, and How It Boots

Learn how the Linux kernel works: its architecture, loadable modules, and full boot sequence. Includes commands, tables, and fixes. Read the guide.

The Most Secure Operating Systems: What the Evidence Shows

Compare the most secure operating systems by kernel design, patch cadence, and exploit data. See which OS fits your threat model. Read the guide.

Monitor Linux Performance: top, htop, btop, vmstat, and iostat

Learn to monitor Linux performance with top, htop, btop, vmstat, and iostat. Read every metric, spot bottlenecks, and fix them. Start tuning now.

Linux Administration Roadmap: What to Learn After the Basics

Move past Linux basics. Follow this step-by-step sysadmin roadmap with commands, configs, and labs. Start building real server skills today.

PowerShell for Beginners: Commands Every Windows User Should Know

Learn the PowerShell commands every Windows user needs: navigation, files, processes, services, and networking. Copy, paste, and start now.

Dual Boot Windows 11 and Linux Safely (Including Secure Boot Pitfalls)

Dual boot Windows 11 and Linux without data loss. Fix Secure Boot, BitLocker, and GRUB issues with tested commands. Follow the full guide now.

Related Articles

Popular Categories