4. Android内核源码结构:内核源码目录树解析

Android 内核基于长期支持(LTS)版本的 Linux 内核,并在此基础上增加了大量面向移动设备、硬件抽象层(HAL)和 Android 特有驱动(如 Binder、ashmem、ion)的补丁。理解内核源码的目录结构,是进行内核裁剪、驱动开发和调试的基础。

4.1 内核源码顶层目录树

在完成内核源码下载后(通常位于 kernel/ 或 common/ 目录),顶层目录结构如下表所示。每个目录都承载着特定的功能模块。

目录/文件 功能描述 Android 工程中的关键性
arch/ 体系结构相关代码,包含 CPU 调度、内存管理、中断等底层实现 极高:决定内核支持哪些 SoC 架构
block/ 块设备层 I/O 调度与请求处理 中:影响存储性能
crypto/ 内核加密 API,支持硬件加速 中:用于文件加密(FBE/FDE)
drivers/ 设备驱动集合,占源码体积最大 极高:Android 硬件适配的核心
fs/ 文件系统实现(ext4、f2fs、sdcardfs 等) 高:f2fs 和 sdcardfs 是 Android 特色
include/ 内核头文件,定义 API 与数据结构 极高:驱动开发必须引用
init/ 内核初始化流程(main.c) 高:启动顺序调试入口
kernel/ 核心调度、进程管理、锁机制 极高:系统稳定性的基石
mm/ 内存管理(页分配、SLAB、VMA) 高:低内存场景优化关键
net/ 网络协议栈(Wi-Fi、蓝牙、蜂窝) 高:无线通信基础
sound/ 音频子系统(ALSA) 中:音频通路调试
security/ 安全模块(SELinux、KEYS) 极高:Android 安全模型强制依赖
scripts/ 编译脚本、配置工具、DT 编译工具 中:编译环境配置
Makefile 顶层构建文件,定义编译入口 极高:编译命令的起点
Kconfig 内核配置菜单的顶层描述 高:make menuconfig 的根节点
实践提示: 在 Android 通用内核(ACK)中,common/ 目录下还包含 android/ 子目录,用于存放 Android 特有的内核补丁和 vendor/ 模块钩子。这是与上游 Linux 内核最直观的差异点。

4.2 arch/arm64 与 arch/x86 目录解析

arch/ 目录是内核移植的核心。Android 设备目前以 arm64(AArch64)为主流,x86 主要用于模拟器和部分 Chromebook。两个目录的结构高度对称,但实现细节差异巨大。

4.2.1 目录结构对比

子目录/文件 arch/arm64 说明 arch/x86 说明
boot/ 生成 Image.gz、dts 打包 生成 bzImage,传统 BIOS/UEFI 启动
configs/ 提供 defconfig(如 gki_defconfig) 提供 i386_defconfig、x86_64_defconfig
include/ asm 头文件,页表、系统寄存器定义 asm 头文件,分段、分页、MSR 定义
kernel/ 异常向量表、CPU 休眠、SMP 启动 系统调用入口、APIC、MCE 处理
mm/ 4K/16K/64K 页表、透明大页 PAE、PAT、ioremap 实现
lib/ memcpy、cache 操作优化 string 操作、checksum 优化
Kconfig ARM64 特有配置(页大小、虚拟化) x86 特有配置(MTRR、微码)

4.2.2 arm64 启动入口关键文件

对于 Android 设备,arch/arm64 的启动流程集中在以下文件中:

  • head.S:内核入口点,设置页表、使能 MMU、跳转到 start_kernel。
  • entry.S:异常向量表,处理同步/异步异常、系统调用。
  • smp.c:多核启动协议(PSCI 实现)。
  • cpu_ops.c:CPU 操作函数表,支持 spin-table 和 PSCI。
关键差异: arm64 依赖设备树(DT)传递硬件信息,而 x86 依赖 ACPI。在 Android GKI 2.0 中,强制要求 arm64 设备使用设备树叠加层(DTO)来分离 SoC 与板级配置。

4.3 drivers/ 与 kernel/ 核心目录

drivers/ 和 kernel/ 是内核工程中修改最频繁的两个目录。前者负责硬件交互,后者负责系统核心机制。

4.3.1 drivers/ 目录:硬件适配的主战场

drivers/ 包含数百个子目录,每个对应一类设备。Android 工程中重点关注以下子目录:

子目录 驱动类型 Android 典型场景
staging/android/ Android 特有驱动 Binder、ashmem、ion、lowmemorykiller
input/ 输入子系统 触摸屏、按键、传感器
gpio/ GPIO 控制器 外设控制、中断唤醒
pinctrl/ 引脚复用控制 SoC 引脚功能配置
regulator/ 电压调节器 CPU 动态调压、外设供电
clk/ 时钟框架 CPU/总线频率缩放
i2c/ I2C 总线 连接摄像头、传感器、PMIC
spi/ SPI 总线 显示屏、NFC 控制器
dma/ DMA 引擎 音视频数据搬运
media/ 多媒体驱动 Camera、Codec、ISP
power/ 电源管理 suspend/resume、wakeup source

4.3.2 kernel/ 目录:系统核心机制

kernel/ 目录虽然代码量不如 drivers/,但决定了系统的调度、同步和进程管理行为。Android 工程中常涉及以下文件:

  • sched/:调度器核心,CFS、RT 调度、EAS(能耗感知调度)——Android 对 EAS 有深度定制。
  • locking/:锁机制(spinlock、mutex、rwlock),死锁检测(lockdep)。
  • power/:suspend/resume 流程、wakeup count、autosleep。
  • cgroup/:控制组,Android 用于 CPU/内存/IO 的资源隔离。
  • printk/:内核日志系统,调试 Android 启动和驱动问题的一线工具。
调试注意: 在 Android 内核中,kernel/printk/printk.c 经常被修改以调整日志缓冲区大小和级别。如果遇到 dmesg 日志丢失,首先检查 CONFIG_LOG_BUF_SHIFT 配置。

4.4 内核源码结构总览图

下图展示了 Android 内核源码的核心目录关系,以及从架构代码到驱动、核心机制的调用链路。

Android 内核源码核心目录结构图 Android 内核源码核心目录结构 Kernel Source Root arch/ arm64/ x86/ drivers/ staging/android/ input/ gpio/ i2c/ media/ power/ kernel/ sched/ power/ cgroup/ Android 特有驱动位于 drivers/staging/android/,包含 Binder、ashmem、ion 等核心 IPC 与内存管理模块 kernel/sched/ 中的 EAS 调度器是 Android 能效优化的关键组件

4.5 关键文件与配置示例

在实际工程中,开发者需要频繁查阅和修改以下文件。这里给出一个典型的 Android 内核配置与编译流程示例:

# 1. 进入内核源码根目录
cd kernel/common/

# 2. 查看 arm64 架构的默认配置
ls arch/arm64/configs/
# 输出示例: gki_defconfig  vendor_defconfig

# 3. 加载 GKI 默认配置
make ARCH=arm64 gki_defconfig

# 4. 通过菜单界面微调配置
make ARCH=arm64 menuconfig
# 在菜单中导航到:
#   -> Device Drivers
#      -> Staging drivers
#         -> Android
#            [*] Binder IPC Driver

# 5. 查看最终生效的配置项
grep -E "CONFIG_ANDROID|CONFIG_BINDER" .config
# 输出示例:
# CONFIG_ANDROID=y
# CONFIG_ANDROID_BINDER_IPC=y
# CONFIG_ANDROID_BINDERFS=y
工程要点: 在 Android GKI 2.0 架构下,gki_defconfig 是 Google 强制要求的基础配置。OEM 厂商必须在此基础上叠加 vendor_defconfig,且不能修改 GKI 核心配置项。违反此规则会导致设备无法通过 CTS/VTS 认证。

4.6 本章小结

  • 顶层目录:arch/、drivers/、kernel/ 是 Android 内核工程的三大核心目录,分别对应体系结构、硬件驱动和系统机制。
  • arch/arm64 vs x86:arm64 依赖设备树(DT),x86 依赖 ACPI;arm64 的启动入口在 head.S,x86 在 startup_32/64。
  • drivers/:staging/android/ 是 Android 特有驱动的聚集地,Binder 和 ion 是最高频的修改对象。
  • kernel/:sched/ 和 power/ 是能效优化的核心,cgroup/ 是资源隔离的基础。
  • 配置管理:使用 make menuconfig 和 .config 文件进行内核功能裁剪,GKI 架构下需严格遵守基础配置不可变原则。