1. 课程导入

在 Android 系统开发中,Vendor Module(厂商模块)是连接 AOSP 通用框架与具体硬件平台的关键桥梁。随着 Android 8.0 Project Treble 的引入,Google 将系统框架与厂商实现彻底解耦,Vendor 分区、VINTF、HAL 接口、Vendor Module 驱动等概念成为每一位 Android 底层工程师必须掌握的核心知识。本课程围绕“Vendor Module 驱动工程”这一主线,从驱动加载机制、内核模块编译、HAL 接口实现,到 Vendor 分区打包与系统集成,构建一条完整的工程化学习路径。

一、学习目标:从“会写驱动”到“会交付模块”

本课程的学习目标不是停留在“能写一个字符设备驱动”,而是建立一套面向 Android 产品交付的 Vendor Module 工程能力。具体包括四个层次:

  • 认知层:理解 Treble 架构下 System / Vendor / Product 分区的职责边界,明确 Vendor Module 在其中的位置。
  • 机制层:掌握 Linux Kernel Module(LKM)的加载、卸载、依赖与符号导出机制,理解 Android 特有的模块加载策略。
  • 接口层:能够基于 HIDL / AIDL 定义并实现 HAL 接口,完成驱动到框架的贯通。
  • 工程层:能够使用 Android.bp、Kernel Makefile、VINTF Manifest 等工具完成模块编译、打包与集成验证。
核心判断标准:一个合格的 Vendor Module 驱动工程师,应当能够独立完成“驱动代码 → 内核模块 → HAL 服务 → Vendor 分区 → 系统启动验证”的全链路交付。

二、核心概念:五个必须厘清的术语

在进入实操之前,需要先建立清晰的概念坐标系。以下五个概念贯穿整个课程:

概念 含义 典型载体
Vendor Module 运行在 Vendor 分区、由厂商维护的驱动或服务模块 vendor/lib/modules/*.ko
HAL 硬件抽象层,定义框架与硬件之间的标准接口 android.hardware.xxx@1.0-service
VINTF Vendor Interface,描述框架与 Vendor 之间的接口契约 manifest.xml / compatibility_matrix.xml
KMI Kernel Module Interface,内核模块与内核之间的稳定接口 Module.symvers / abi_gki_aarch64
GKI Generic Kernel Image,统一内核镜像,Vendor 模块以 .ko 形式加载 boot.img + vendor_boot.img

其中,GKI 与 KMI 是 Android 11 之后驱动工程的最大变量。传统“把驱动编进内核”的方式逐渐被“内核模块动态加载”取代,这要求工程师必须理解模块与内核之间的 ABI 约束。

三、整体知识框架:四层结构一张图

为了把零散知识点组织成体系,本节用一张结构关系图展示 Vendor Module 驱动工程的整体框架。图中自下而上分为硬件层、内核层、HAL 层与框架层,Vendor Module 横跨内核层与 HAL 层,是整条链路的交付核心。

Android Vendor Module 驱动工程四层结构 框架层 Framework SystemServer · CameraService · AudioFlinger · SensorService 通过 VINTF 契约调用 HAL,不直接接触驱动 HAL 层 Hardware Abstraction Layer HIDL / AIDL 接口 · xxx@1.0-service · passthrough / binderized Vendor Module 在此暴露标准接口,屏蔽硬件差异 VINTF Manifest 声明接口版本与实例名 内核层 Kernel GKI 通用内核 · KMI 稳定接口 · LKM 动态加载 Vendor Module 以 .ko 形式存在,通过 insmod / modprobe 加载 Module.symvers 约束符号版本,保证 ABI 兼容 硬件层 Hardware SoC · Camera Sensor · Audio Codec · Touch Panel · GPIO / I2C / SPI 驱动通过总线与寄存器操作直接控制硬件 Vendor Module 驱动 + HAL 交付核心

这张图揭示了三个关键关系:第一,Vendor Module 不是孤立代码,而是同时向下依赖内核接口、向上提供 HAL 接口;第二,VINTF 是框架与 Vendor 之间的“合同”,任何接口变更都必须同步更新;第三,GKI 让内核与驱动分离,驱动工程的重心从“改内核”转向“写模块 + 配接口”。

四、实战路线图:从环境搭建到系统验证

本课程后续章节将按照一条可执行的路线推进,建议按顺序学习,每一步都对应可验证的产物:

  1. 环境搭建:下载 AOSP 源码、配置 lunch 目标、编译 GKI 内核,产出可启动的 boot.img。
  2. 驱动开发:编写第一个字符设备驱动,理解 file_operations、ioctl、sysfs 等核心结构。
  3. 模块编译:使用 Android.bp 与 Kernel Makefile 将驱动编译为 .ko,处理 KMI 符号依赖。
  4. HAL 实现:定义 HIDL/AIDL 接口,实现 binderized 服务,完成驱动到框架的调用链。
  5. VINTF 配置:编写 manifest.xml 与 compatibility_matrix.xml,通过 vintf_fixer 校验。
  6. 打包集成:将 .ko 与 HAL 服务放入 vendor 分区,配置 init.rc 与 SELinux 策略。
  7. 验证排障:通过 dmesg、logcat、lshal、vintf 等工具定位加载失败与接口不匹配问题。
建议在每一步都保留可回滚的产物:内核镜像、模块文件、HAL 服务、VINTF 配置。Vendor Module 工程最大的痛点不是“写不出来”,而是“改坏了不知道哪一层出问题”。

五、典型场景与常见误区

以一个真实场景为例:某项目需要新增一颗 I2C 接口的温湿度传感器。传统做法是直接修改内核源码,把驱动编进内核。但在 GKI 架构下,正确做法是:将驱动编译为独立 .ko,通过 vendor_boot 或 vendor 分区加载;同时实现一个 Sensor HAL 服务,将传感器数据通过 AIDL 上报给 SensorService;最后在 VINTF Manifest 中声明该 HAL 接口。

# 典型模块加载日志
[    3.421] vendor_module: loading out-of-tree module taints kernel
[    3.425] vendor_module: probe i2c-1 addr=0x48 success
[    3.430] vendor_module: registered sensor hal interface v1.0
[    3.435] init: starting service 'vendor.sensor-hal-1-0'
[    3.440] vintf: manifest check passed for android.hardware.sensors@1.0

常见误区集中在三点:

  • 误区一:把驱动当应用写。内核模块运行在内核态,不能调用标准 C 库,必须使用内核 API,且要注意并发与内存安全。
  • 误区二:忽略 KMI 约束。直接使用未导出的内核符号,导致模块加载时报 “Unknown symbol”,必须通过 GKI 允许的符号列表。
  • 误区三:VINTF 与实现不同步。HAL 接口版本升级后忘记更新 manifest,导致框架启动时找不到服务,表现为 “HAL not found”。
排障顺序建议:先看 dmesg 确认 .ko 是否加载成功,再看 logcat 确认 HAL 服务是否启动,最后用 lshal 与 vintf 检查接口契约是否匹配。不要一上来就改代码,先定位问题在哪一层。