目录
  1. 1. 一、Android 操作系统的四层架构
    1. 1.1. 1.1 经典分层模型
    2. 1.2. 1.2 各层职责详解
      1. 1.2.1. 第一层:Linux Kernel(Linux 内核)
      2. 1.2.2. 第二层:HAL(硬件抽象层)
      3. 1.2.3. 第三层:Native Libraries + Android Runtime
      4. 1.2.4. 第四层:Java API Framework(Java 框架层)
      5. 1.2.5. 第五层:System Apps(系统应用层)
  2. 2. 二、Linux 内核为 Android 所做的关键修改
    1. 2.1. 2.1 Binder IPC 驱动程序
    2. 2.2. 2.2 ashmem(Android Shared Memory)
    3. 2.3. 2.3 Low Memory Killer (LMK) → lmkd
    4. 2.4. 2.4 Wakelocks 和电源管理
    5. 2.5. 2.5 Android 内核与 Linux 主线的合入
  3. 3. 三、Android 的 Init 系统 vs 传统 Linux Init
    1. 3.1. 3.1 Android init 与 systemd / sysvinit 的对比
    2. 3.2. 3.2 为什么 Android 不直接使用 systemd
  4. 4. 四、为什么 Android 选择 Linux 内核 + Binder IPC?
    1. 4.1. 4.1 选择 Linux 的原因
    2. 4.2. 4.2 选择 Binder 代替 D-Bus / Unix Socket 的原因
  5. 5. 五、Fuchsia:Android 的长期替代方案
    1. 5.1. 5.1 Zircon 与 Linux 的关键差异
    2. 5.2. 5.2 为什么 Android 短期内不会迁移到 Fuchsia
  6. 6. 六、核心面试题
  7. 7. 六、Linux 内核关键子系统在 Android 中的应用
    1. 7.1. 6.1 CFS 调度器与 Android 的任务管理
    2. 7.2. 6.2 VFS(Virtual File System)与 Android 文件系统
    3. 7.3. 6.3 Linux 网络协议栈与 Android 的网络限制
    4. 7.4. 6.4 Android 的 seccomp-bpf 严格化
  8. 8. 七、Android 系统启动流程
    1. 8.1. 7.1 Boot ROM → Kernel → Init 的启动链
    2. 8.2. 7.2 Zygote 的进程预加载机制
  9. 9. 八、Android 安全架构概览
    1. 9.1. 8.1 纵深防御模型
    2. 9.2. 8.2 SELinux 在 Android 中的应用
  10. 10. 九、Android 与嵌入式 Linux 的对比
    1. 10.1. 9.1 Bionic vs glibc
    2. 10.2. 9.2 Android 的文件系统布局
    3. 10.3. 9.3 Android 的启动与 A/B OTA
    4. 10.4. 9.4 Android 不是传统 Linux 发行版
【深入内核篇】操作系统介绍

Android 操作系统并不是从零开始构建的,而是建立在 Linux 内核之上的一个高度定制的软件栈。理解 Android 操作系统的整体架构,是深入理解任何一个子系统(Binder、SurfaceFlinger、AMS、Zygote 等)的前提。本文将系统性地介绍 Android 操作系统的四层架构、Linux 内核为 Android 所做的定制修改,以及 Android 选择 Linux + Binder IPC 架构的深层原因。

一、Android 操作系统的四层架构

1.1 经典分层模型

┌──────────────────────────────────────────────────────┐
│ System Apps │
│ Dialer | Email | Calendar | Camera | Settings │
├──────────────────────────────────────────────────────┤
│ Java API Framework │
│ ActivityManager | WindowManager | ContentProvider │
│ View System | PackageManager | TelephonyManager │
│ ResourceManager | NotificationManager | Location │
├──────────────────────────────────────────────────────┤
│ Native Libraries Android Runtime │
│ ┌──────────────────────┐ ┌────────────────┐ │
│ │ Surface Manager │ │ ART (AOT+JIT) │ │
│ │ Media Framework │ │ Core Libraries│ │
│ │ SQLite │ │ (libcore) │ │
│ │ OpenGL ES │ └────────────────┘ │
│ │ libc (Bionic) │ │
│ │ WebKit/Chromium │ │
│ │ Audio Manager │ │
│ │ FreeType | Skia │ │
│ └──────────────────────┘ │
├──────────────────────────────────────────────────────┤
│ Hardware Abstraction Layer (HAL) │
│ Audio | Camera | Sensors | GPS | Bluetooth | WiFi │
├──────────────────────────────────────────────────────┤
│ Linux Kernel │
│ Binder | ashmem | ION | wakelocks | lowmemorykiller│
│ Display | Camera | Audio | Input | Power Management │
└──────────────────────────────────────────────────────┘

1.2 各层职责详解

第一层:Linux Kernel(Linux 内核)

Linux 内核是 Android 平台的基石,负责:

  • 进程管理:创建、调度、终止进程和线程(CFS 调度器)
  • 内存管理:虚拟内存、物理页面分配(buddy system)、进程间内存隔离(页表)、内存回收(kswapd)
  • 设备驱动:硬件设备的抽象和访问控制
  • 文件系统:ext4 / erofs / f2fs / tmpfs 等文件系统支持
  • 网络协议栈:TCP/IP、WiFi、蓝牙、NFC
  • 安全模型:基于 UID/GID 的进程隔离、SELinux、Capabilities、seccomp

**CFS (Completely Fair Scheduler)**:Linux 内核的默认调度器,基于红黑树维护所有可运行任务,按虚拟运行时间(vruntime)排序。调度器总是选择 vruntime 最小的任务执行——即”获得 CPU 时间最少的任务优先”。

内存管理核心机制

  • VMA(Virtual Memory Area):每个进程的地址空间被划分为多个 VMA,描述连续虚拟地址区域的属性(代码段、堆、栈、mmap 区域等)
  • Page Fault:当进程访问尚未映射的虚拟地址时,触发缺页异常。内核的 page fault handler 根据 VMA 的属性分配物理页面或从磁盘加载数据
  • Buddy System:物理页面分配器,以 2 的幂次大小为分配单位,通过伙伴合并机制减少内存碎片

第二层:HAL(硬件抽象层)

HAL 是 Android 架构中最重要的抽象之一。每个硬件组件都有一个 HAL 模块(通常以 .so 文件形式存在),框架层通过 HAL 接口调用硬件,而不直接与内核驱动交互。

App → Android Framework → HAL Interface → HAL Implementation → Kernel Driver → Hardware

Android 8+ 引入了 HIDL(HAL Interface Definition Language)将 HAL 服务运行在独立进程中,进一步隔离了框架层和硬件实现层,这是 Treble 架构的核心。

Binderized HAL vs Passthrough HAL

  • Binderized HAL:HAL 实现在独立进程中,通过 Binder IPC 通信。接口用 HIDL 或 AIDL 定义。Android 8+ 推荐
  • Passthrough HAL:HAL 实现以 .so 形式加载到框架进程(如 mediaserver)的地址空间中。Android 7 及之前的模式

第三层:Native Libraries + Android Runtime

Native C/C++ Libraries(原生库)

  • Bionic:Android 定制的 C 标准库,替代 glibc。设计目标:更小、更快、BSD 许可
  • SurfaceFlinger:显示合成引擎,将所有可见窗口的 buffer 合成为最终显示帧
  • Media Framework:音视频编解码框架(Stagefright)
  • SQLite:嵌入式关系型数据库
  • OpenGL ES / Vulkan:3D 图形渲染 API
  • Skia:2D 图形渲染引擎(同时也是 Flutter 的渲染引擎)

**Android Runtime (ART)**:

  • AOT (Ahead-Of-Time) 编译:安装时把 DEX 字节码编译为 native 指令
  • JIT (Just-In-Time) 编译:运行时对热点代码进行即时编译
  • GC(垃圾回收):并发压缩回收、分代回收(Android 10+)
  • Profile-guided 优化:基于应用使用模式优化编译

第四层:Java API Framework(Java 框架层)

这是 Android 应用开发的核心 API:

  • ActivityManagerService — 四大组件管理
  • WindowManagerService — 窗口管理
  • PackageManagerService — 包管理
  • ContentProvider — 数据共享
  • View System — UI 组件体系

第五层:System Apps(系统应用层)

预装的系统级应用,与第三方应用共享同一运行时。

二、Linux 内核为 Android 所做的关键修改

Android 并不是简单地拿一个标准 Linux 内核来用。Google 对 Linux 内核做了大量的定制修改,这些修改通过 Android Mainline Project 逐步合入 Linux 主线。

2.1 Binder IPC 驱动程序

Binder 是 Android 最核心的 IPC(进程间通信)机制,作为内核驱动实现:

// drivers/android/binder.c (Android 内核中的 Binder 驱动)
// Binder 的核心功能:
// 1. 零拷贝数据传输(通过 mmap 在内核空间映射接收缓冲区)
// 2. 引用计数管理(自动管理跨进程对象生命周期)
// 3. 死亡通知(Binder peer 意外退出时通知其他进程)
// 4. 权限校验(基于 UID/PID 的调用者识别)

Binder 驱动在 /dev/binder 上为用户空间提供接口。Android 10+ 引入了多 Binder 域:

  • /dev/binder — 系统服务通信(framework 和 app 之间)
  • /dev/hwbinder — HIDL HAL 服务通信
  • /dev/vndbinder — Vendor 域 HAL 服务通信

每个 Binder 域有独立的 context manager,实现了不同安全等级的 IPC 隔离。

2.2 ashmem(Android Shared Memory)

ashmem 是 Android 特有的共享内存机制,支持通过名称引用和引用计数自动回收:

// drivers/staging/android/ashmem.c
// ashmem 特性:
// 1. 基于名称的内存区域引用,而不是文件描述符
// 2. 引用计数自动管理:所有引用者关闭后内存自动释放
// 3. 支持 pin/unpin 操作(允许 LMK 在内存压力时回收 unpinned 页面)
// 4. 通过 /dev/ashmem 设备文件访问

在 Android 10+ 中,ashmem 正逐步被 Linux 标准的 memfd_create() 替代。memfd 提供了类似的功能(基于 fd 的匿名内存),而且支持 sealing(防止共享者修改内容)。

2.3 Low Memory Killer (LMK) → lmkd

Android 最初在内核中实现了低内存杀手(LMK)驱动,在内存不足时选择性杀死进程。从 Android 9 开始,这个功能被迁移到用户空间的 lmkd 守护进程:

// system/memory/lmkd/lmkd.cpp
// lmkd 的工作机制:
// 1. 通过 /proc/pressure/memory 或 /proc/vmstat 监测内存压力
// 2. 读取每个进程的 /proc/<pid>/oom_score_adj 决定 kill 优先级
// 3. 使用 cgroup 的 memory.high/memory.max 进行更精细的控制
// 4. 支持 vmpressure 事件通知(内核 → lmkd)

2.4 Wakelocks 和电源管理

Android 的电源管理非常激进——设备默认进入 suspend 状态,由 wakelock 机制决定何时保持唤醒:

// drivers/power/wakelock.c (Android 内核修改)
// wakelock 类型:
// 1. WAKE_LOCK_SUSPEND: 防止系统进入 suspend
// 2. WAKE_LOCK_IDLE: 防止系统进入 idle

// Android 用户空间接口(已废弃,使用 /sys/power/wake_lock 替代):
// /sys/power/wake_lock — 获取锁
// /sys/power/wake_unlock — 释放锁

Android 新的电源管理通过 PowerManagerService 和 WakeLock 类实现,底层驱动接口逐步向 Linux 主线的 autosleep 机制靠拢。

2.5 Android 内核与 Linux 主线的合入

从 Android 11 开始,Google 通过 Android Generic Kernel Image (GKI) 项目将 Android 内核修改逐步合入 Linux 主线或封装为独立模块。目标是:

  • GKI 1.0 (Android 11):内核版本 5.4,厂商模块与内核解耦
  • GKI 2.0 (Android 12+):内核版本 5.10+,更大的主线上游覆盖率

三、Android 的 Init 系统 vs 传统 Linux Init

3.1 Android init 与 systemd / sysvinit 的对比

特性 Android init systemd sysvinit
配置语言 init.rc(自定义语言) unit 文件 (.service, .target 等) shell 脚本
依赖管理 触发器机制 (on property:) 显式依赖 (Requires=, Wants=) 脚本顺序(无依赖)
服务监控 内置(SIGCHLD + epoll) 内置(cgroups 监控) 需要额外守护进程
并行启动 事件驱动并行 Socket-based 并行 串行
属性存储 内置 Property Service systemd 不支持 N/A
设备节点管理 内置 ueventd udevd (systemd-udevd) udev / mdev

3.2 为什么 Android 不直接使用 systemd

  1. 资源开销:systemd 设计为功能完备的 init 系统,包含 journald、logind、networkd 等大量组件,这些对嵌入式移动设备是过度设计
  2. 启动性能:Android 的设备节点管理和服务启动优化极度精简,专注于亚秒级启动
  3. Android 特化需求:android init 深度集成了 property service、SELinux 上下文管理、USB gadget 配置等 Android 特有的功能

四、为什么 Android 选择 Linux 内核 + Binder IPC?

4.1 选择 Linux 的原因

  1. 成熟的驱动生态:Linux 已有大量 ARM 处理器和外设的优质驱动
  2. 活跃的开发社区:持续的 bug 修复、安全补丁、新硬件支持
  3. 经过验证的安全模型:UID/GID 隔离、SELinux、Capabilities
  4. 开源许可兼容:GPL v2 内核与 Apache 2.0 用户空间的组合在商业和法律上可行

4.2 选择 Binder 代替 D-Bus / Unix Socket 的原因

Binder 的设计由前 BeOS 工程师 Dianne Hackborn 主导,针对移动设备进行了深入优化:

Binder 相比 D-Bus 的优势:

  • 零拷贝传输:通过 mmap 在内核空间映射接收缓冲区(1MB - 8MB),传输大块数据时避免用户空间复制
  • 调用者身份保证:内核驱动保证 sender_euid / sender_pid 不被伪造
  • 引用计数和死亡通知:自动管理跨进程对象引用
  • 线程池管理:Binder 驱动内建线程池,Binder 调用在服务端自动分配线程

五、Fuchsia:Android 的长期替代方案

5.1 Zircon 与 Linux 的关键差异

特性 Linux(Android 使用) Zircon(Fuchsia 使用)
内核架构 宏内核(Monolithic) 微内核(Microkernel)
驱动模型 内核空间驱动 用户空间驱动(部分)
IPC 机制 Binder(内核模块) Channel(原生内核对象)
调度模型 CFS 基于 deadline 的调度器
能力模型 UID/GID + SELinux 基于 capability 的对象句柄

5.2 为什么 Android 短期内不会迁移到 Fuchsia

  1. 生态惯性:数十亿设备和数以百万计的 App 依赖 Linux 内核
  2. 硬件驱动:Linux 的驱动覆盖范围远超 Zircon
  3. 工程成本:迁移整个运行时时到新内核 API 是天文数字的工程

六、核心面试题

Q1:Android 为什么使用 Linux 内核而不是其他内核(如 BSD、L4)?

答:(1) Linux 在 ARM 平台上有最成熟的硬件驱动生态,而移动设备 SoC 种类繁多;(2) Linux 社区活跃,持续获得安全补丁和性能优化;(3) Linux 的 GPL v2 许可与 Android 用户空间的 Apache 2.0 许可兼容;(4) Linux 的 UID/GID 隔离模型天然适合 Android 的每个 App 一个 UID 的设计。

Q2:Binder 在 Android 中为什么比传统的 Unix Domain Socket 更适合做 IPC?

答:(1) 零拷贝:Binder 通过 mmap 在内核空间预分配接收缓冲区,避免了一次用户空间拷贝。(2) 身份认证:Binder 驱动在每次事务中携带 sender_euid 和 sender_pid,服务端可以信任这些信息。(3) 死亡通知:Binder 通过 linkToDeath 自动通知服务端客户端进程的退出。(4) 对象引用计数:Binder 驱动自动管理跨进程对象引用。

Q3:Android 的 HAL 层与标准 Linux 的驱动模型有什么不同?

答:标准 Linux 驱动模型是:用户空间 → 系统调用 → 内核驱动 → 硬件。Android HAL 在驱动之上增加了一层抽象:用户空间 → HAL 接口 → HAL 实现 → 内核驱动 → 硬件。上层框架使用统一的 HAL 接口,厂商只需实现 HAL 接口而不需要修改框架代码。HIDL(Android 8+)进一步将 HAL 实现放入独立进程。

Q4:lmkd(用户空间 LMK)和内核 LMK 相比有什么优势?

答:(1) 策略硬编码在内核中 → 策略在用户空间,更新无需改内核;(2) 内核无法读取进程的 importance 等 framework 层信息 → lmkd 可通过 AMS 获取 OOM ADJ;(3) 内核基于简单内存阈值触发 → lmkd 可通过 /proc/pressure/memory 获取内存压力事件、通过 cgroup 进行精细控制。

Q5:Fuchsia 的 Zircon 微内核架构相比 Linux 宏内核有什么优势?为什么 Google 在 Android 之外又开发 Fuchsia?

答:微内核架构优势:(1) 故障隔离——驱动 crash 不会导致整个系统崩溃,内核可重启驱动进程;(2) 更小的 TCB(Trusted Computing Base);(3) 可更新性——无需重启系统即可更新驱动。Google 开发 Fuchsia 的动机包括:Linux 开发流程和许可证不完全符合 Google 利益、GKI 无法从根本上解决版本碎片化、Google 希望在新一代 OS 的 IPC、调度器、安全架构方面有完整控制权。

六、Linux 内核关键子系统在 Android 中的应用

6.1 CFS 调度器与 Android 的任务管理

CFS(Completely Fair Scheduler)是 Linux 内核的默认调度器,从 Linux 2.6.23 开始使用。Android 进程的调度完全依赖 CFS。

CFS 的核心数据结构是红黑树,按虚拟运行时间(vruntime)组织所有可运行任务。vruntime 的计算公式:
vruntime += (actual_runtime) * (NICE_0_LOAD / task_weight)

其中 task_weight 由 nice 值决定——nice 值越低(优先级越高),weight 越大,vruntime 增长越慢,因此获得更多 CPU 时间。

Android 依赖 Linux 的 cgroup(Control Groups)来对任务进行分组管理和资源限制:

// Android 使用 cgroup 隔离不同优先级的任务
// /dev/cpuctl/ 目录下:
// foreground/ — 前台进程(top-app cgroup)
// background/ — 后台进程(background cgroup)
// system-background/ — 系统后台进程

// 通过 cpu.shares 控制 CPU 份额:
// foreground: 1024 (默认权重)
// background: 52 (约 5% 的 CPU)

// 通过 cpu.cfs_quota_us / cpu.cfs_period_us 限制 CPU 使用率

Android 8+ 引入了 cpuset cgroup,将前台应用绑定到”大核”(big cores),后台任务绑定到”小核”(little cores),实现 energy-aware scheduling(EAS)——在性能和功耗间找到平衡点。

6.2 VFS(Virtual File System)与 Android 文件系统

Linux 的 VFS 层为 Android 提供了统一的文件系统接口,使得不同文件系统(ext4、f2fs、erofs、sdcardfs)可以无缝共存:

用户空间 open/read/write/close

VFS(Virtual File System Switch)
├── ext4 (data 分区)
├── f2fs (data 分区——Flash Friendly File System)
├── erofs (system 分区——Enhanced Read-Only File System)
├── tmpfs (/dev, /sys/fs/cgroup)
└── sdcardfs (模拟外部存储)

f2fs(Flash Friendly File System):三星为 NAND flash 设备优化的文件系统。Android 在 Pixel 设备上默认使用 f2fs 作为 data 分区文件系统。相比 ext4,f2fs 在随机写入和小文件操作上有显著性能提升。

erofs(Enhanced Read-Only File System):华为贡献的只读文件系统,Android 10+ 用于 system 分区。相比 ext4,erofs 支持透明压缩并减少了读放大。

6.3 Linux 网络协议栈与 Android 的网络限制

Android 对网络栈的定制主要集中在安全控制:

// net/ipv4/af_inet.c — Android 的网络创建限制
// 只有特定 GID (AID_INET = 3003) 的进程可以创建 AF_INET socket
// 这是通过 ANDROID_PARANOID_NETWORK 宏实现的
static inline int current_has_network(void)
{
return in_egroup_p(AID_INET) || capable(CAP_NET_RAW);
}

Android 还通过 iptables/netfilter 实现:

  • 应用级防火墙:限制后台应用的网络访问(Android 7+)
  • Data Saver:白名单机制,仅允许前台应用或用户授权的应用使用数据
  • 私有 DNS:基于 DNS-over-TLS 的系统级加密 DNS(Android 9+)

6.4 Android 的 seccomp-bpf 严格化

Android 8.0 开始对所有应用进程启用 seccomp-bpf:

// bionic/libc/seccomp/seccomp_policy.cpp
// 应用进程的系统调用白名单:
// 允许: read, write, open, close, mmap, ioctl, futex, ...
// 拒绝: ptrace, process_vm_readv, init_module, delete_module, mount, ...

seccomp-bpf 过滤在 bionic libc 初始化阶段安装。整个过程是不可逆的——一旦安装,进程就不能再增加系统调用的权限。

七、Android 系统启动流程

7.1 Boot ROM → Kernel → Init 的启动链

Boot ROM (出厂固化)
→ Bootloader (LK / U-Boot / ABL)
→ Linux Kernel (加载 ramdisk/initramfs)
→ init (第一个用户空间进程,PID=1)
→ init.rc 按阶段执行:
early-init → init → late-init
→ ueventd (设备节点管理)
→ servicemanager (Binder 服务注册中心)
→ vold (卷管理/加密)
→ surfaceflinger (显示合成)
→ system_server (Zygote + System Services)
→ Zygote fork → system_server
→ ActivityManagerService
→ PackageManagerService
→ WindowManagerService
→ ... (100+ 系统服务)
→ launcher (桌面,通过 AMS 启动)

7.2 Zygote 的进程预加载机制

Zygote 是 Android 特有的进程孵化器。它在启动时预加载所有应用的公共类和资源:

// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
static void preload(TimingsTraceLog bootTimingsTraceLog) {
preloadClasses(); // 加载 ~4000 个常用 Java 类
preloadResources(); // 加载常用资源(主题、文本)
preloadOpenGL(); // 预加载 OpenGL 驱动
preloadSharedLibraries(); // 加载常用 .so(libandroid.so, libicuuc.so 等)
}

预加载后,Zygote 的内存页大部分是共享的——所有从 Zygote fork 的应用进程共享这些页的物理内存(COW——Copy On Write)。这大幅减少了每个应用进程的启动时间和内存占用。

八、Android 安全架构概览

8.1 纵深防御模型

Android 的安全架构采用多层纵深防御策略:

  1. 应用层沙箱:每个 App 在自己的 UID 下运行
  2. 权限系统:运行时权限 + 安装时权限
  3. SELinux:强制访问控制
  4. seccomp:系统调用过滤
  5. 应用签名:签名一致的 App 可共享 UID
  6. Verified Boot:从硬件根信任的完整验证链

8.2 SELinux 在 Android 中的应用

Android 从 4.3 引入 SELinux,4.4 起强制开启 Enforcing 模式。SELinux 的核心概念:

进程 (domain) → 操作 (class:permission) → 资源 (type)
如:untrusted_app → file:read → app_data_file

关键 domain 定义:

  • untrusted_app:第三方应用
  • system_app:系统签名应用
  • priv_app:特权应用(比 system_app 有更多权限)
  • isolated_app:隔离进程(如 WebView renderer)

Android 8+ 的 Treble 架构要求 system 和 vendor 的 sepolicy 分离。厂商只能修改 vendor/ 下的 sepolicy,不能修改 system/ 下的平台 sepolicy。这保证了系统升级不破坏厂商的安全策略,反之亦然。

AOSP 核心路径参考:

  • drivers/android/binder.c — Binder 驱动
  • drivers/staging/android/ashmem.c — 匿名共享内存
  • drivers/power/wakelock.c — 电源管理
  • system/core/init/ — Android init 进程
  • system/memory/lmkd/ — 用户空间低内存杀手
  • system/sepolicy/ — SELinux 策略
  • hardware/interfaces/ — HIDL HAL 接口定义
  • frameworks/native/cmds/servicemanager/ — Binder 服务管理器
  • frameworks/native/services/surfaceflinger/ — 显示合成引擎
  • frameworks/base/core/java/com/android/internal/os/ZygoteInit.java — Zygote 初始化
  • bionic/libc/seccomp/seccomp_policy.cpp — seccomp 策略

九、Android 与嵌入式 Linux 的对比

许多开发者误以为 Android 就是 “Linux + Java”。实际上 Android 在很多方面与传统 Linux 发行版有根本差异:

9.1 Bionic vs glibc

Bionic 是 Android 自行开发的 C 标准库,替代 Linux 标准的 glibc。关键差异:

特性 glibc Bionic
代码大小 ~2.5MB ~400KB
许可证 LGPL BSD
线程实现 NPTL 基于 futex 的简化实现
POSIX 兼容 几乎完整 子集(裁剪了不适用于移动设备的 API)
内存分配 ptmalloc3 jemalloc(Android 10+) / dlmalloc(旧版)
编译优化 通用 为 ARM/i386 优化
C++ 异常 完整支持 支持但不完整(某些 corner case 可能不同)

Bionic 的设计哲学:更小、更快、BSD 许可。它的 printf 实现比 glibc 快约 30%,因为它省略了 POSIX locale 和复杂的 internationalization 支持。

9.2 Android 的文件系统布局

Android 不使用传统的 FHS(Filesystem Hierarchy Standard):

目录 Android 传统 Linux (FHS)
系统二进制 /system/bin /usr/bin, /bin
系统库 /system/lib64 /usr/lib64, /lib64
配置文件 /system/etc /etc
应用数据 /data/data/ /home/
临时文件 /data/local/tmp /tmp
设备文件 /dev /dev
厂商分区 /vendor N/A(无对应)
产品分区 /product N/A

这种布局的设计考量:

  1. 区分只读分区(/system)和读写分区(/data),便于系统升级(OTA)
  2. /vendor 独立于 /system,实现 Treble 架构的厂商-平台分离
  3. /product 用于 OEM 定制,进一步分离运营商/OEM 的修改

9.3 Android 的启动与 A/B OTA

Android 支持 A/B 分区无缝更新(Seamless Updates):

正常启动:
boot_a → system_a → vendor_a → userdata

OTA 更新:
1. 下载更新到 boot_b, system_b, vendor_b
2. 设置启动标记指向 slot b
3. 重启后从 slot b 启动
4. 如果启动失败,自动回退到 slot a

优势:
- 更新在后台完成,无需进入 recovery 模式等待
- 启动失败自动回退,不影响用户使用
- Google 要求 Android 11+ 设备必须支持 A/B 分区(或 Virtual A/B)

9.4 Android 不是传统 Linux 发行版

总结差异:

方面 传统 Linux (Debian/Ubuntu) Android
C 库 glibc Bionic
init 系统 systemd / sysvinit 自定义 init(init.rc)
IPC D-Bus / Unix Socket Binder
显示服务器 X11 / Wayland SurfaceFlinger
包管理 apt / dpkg / rpm APK / PackageManager
进程模型 fork/exec Zygote 预加载 + fork
电源管理 ACPI / systemd-logind Wakelock / PowerManager
系统升级 apt upgrade A/B OTA

这些差异反映了 Android 团队的刻意设计选择——专为移动设备裁剪和优化。Android 并非”在 Linux 上跑 Java”,而是一个深度修改的操作系统,其基础是 Linux 内核,但用户空间几乎完全是自建的。

打赏
  • 微信
  • 支付宝

评论