4. Vendor分区结构

在 Android 系统集成中,Vendor 分区是承载“硬件相关、厂商私有”内容的核心分区。它把 SoC 厂商、ODM/OEM 的驱动、固件、HAL 实现、配置文件与专有库从 AOSP 通用代码中剥离出来,使 system 分区可以独立升级,而 vendor 分区随硬件平台版本演进。理解 vendor 分区的目录布局、关键文件、镜像生成流程以及挂载方式,是排查开机失败、HAL 加载异常、OTA 升级问题的基本功。

一、Vendor 分区的目录布局

vendor 分区在设备上的挂载点通常是 /vendor,其内部结构遵循 Android 的标准化约定。不同平台会有所增删,但主干目录高度一致:

  • /vendor/bin:厂商可执行程序,如传感器守护进程、指纹 HAL 服务、音频 HAL 服务等。
  • /vendor/lib 与 /vendor/lib64:厂商私有共享库,包括 HAL 实现库、编解码库、算法库。
  • /vendor/etc:配置文件集中地,如 init.vendor.rc、fstab、音频策略、传感器配置、媒体编解码配置。
  • /vendor/firmware:Wi-Fi、蓝牙、摄像头、触控等外设固件文件。
  • /vendor/lib/modules:内核模块(.ko),由 vendor 分区提供,配合内核版本加载。
  • /vendor/overlay:RRO 运行时资源覆盖包,用于定制系统资源。
  • /vendor/etc/vintf:VINTF 清单片段,声明该分区提供的 HAL 接口与版本。

这些目录并非随意堆放,而是与 Android 的 分区隔离原则 对应:system 分区不能直接依赖 vendor 中的私有符号,二者通过 HAL 接口、VINTF 清单和稳定 AIDL 进行契约式交互。

vendor 分区目录布局与关键文件 /vendor bin/ 厂商可执行程序 lib/ lib64/ 私有库 etc/ 配置与 rc 脚本 firmware/ 外设固件 lib/modules/ 内核模块 overlay/ RRO 资源覆盖 etc/vintf/ HAL 清单 关键文件示例 init.vendor.rc fstab.vendor manifest.xml (VINTF) audio_policy_configuration.xml android.hardware.*.so wlan.ko / touch.ko 构建输入 device/<vendor>/<board>/ vendor/<oem>/ PRODUCT_COPY_FILES Android.bp / Android.mk BOARD_VENDOR_* 变量 vendor.img 生成 1. 收集模块 install 到 staging 2. 生成文件列表 installed-files.txt 3. 制作文件系统 ext4 / erofs 4. 打包镜像 mkuserimg / build_image 5. 签名与校验 avbtool / dm-verity

二、关键文件与库的作用

vendor 分区中真正决定设备能否正常启动和工作的,是以下几类文件:

文件/目录作用典型问题
init.vendor.rc定义 vendor 服务的启动时机、权限、依赖服务未启动、SELinux 拒绝
fstab.vendor声明 vendor 分区挂载参数与 dm-verity 配置挂载失败、校验不通过
manifest.xmlVINTF 清单,声明提供的 HAL 与版本HAL 版本不匹配、VINTF 检查失败
lib/modules/*.ko内核模块,驱动外设内核版本不匹配、模块未加载
firmware/*外设固件,运行时由驱动加载固件缺失导致 Wi-Fi/蓝牙不可用
lib64/android.hardware.*.soHAL 实现库,供 hwservicemanager 加载符号缺失、ABI 不兼容
VINTF 清单是 system 与 vendor 之间的“接口合同”。如果 vendor 声明的 HAL 版本与 system 期望的不一致,开机时会出现 VINTF 兼容性错误,甚至无法进入系统。

三、vendor.img 的生成与打包流程

vendor.img 的生成由构建系统自动完成,核心步骤可以概括为“收集—列表—制作—打包—签名”。在 AOSP 中,关键变量与命令如下:

# 典型构建命令
source build/envsetup.sh
lunch aosp_arm64-userdebug
make vendorimage -j$(nproc)

# 关键中间产物
out/target/product/<device>/vendor/
out/target/product/<device>/vendor.img
out/target/product/<device>/obj/PACKAGING/vendor_intermediates/

# 查看镜像内容
simg2img vendor.img vendor.raw.img
mkdir vendor_mnt && sudo mount -o loop vendor.raw.img vendor_mnt
ls vendor_mnt

构建系统首先根据 PRODUCT_COPY_FILES、PRODUCT_PACKAGES 以及各模块的 install 规则,把文件安装到 out/.../vendor/ 暂存目录;随后生成 installed-files.txt 记录文件清单;再调用 mkuserimg_mke2fs 或 mkuserimg_erofs 制作文件系统镜像;最后通过 avbtool 添加 AVB 签名与 dm-verity 哈希树。

在 Android 10 之后,vendor 分区通常启用 dm-verity 与 AVB2.0。这意味着任何对 vendor.img 的修改都会导致校验失败,设备可能无法启动。调试阶段可通过 adb disable-verity 临时关闭,但量产版本必须保持开启。

四、文件系统类型与挂载选项

vendor 分区常用的文件系统类型包括 ext4 和 erofs。ext4 兼容性好、支持可写挂载,适合开发调试;erofs 是只读压缩文件系统,空间占用小、读取性能好,已成为 Android 新版本的主流选择。

# fstab 中的典型挂载配置
/dev/block/bootdevice/by-name/vendor /vendor ext4 ro,barrier=1,discard wait,slotselect,avb=vbmeta_vendor,first_stage_mount

# erofs 示例
/dev/block/bootdevice/by-name/vendor /vendor erofs ro,check=no wait,slotselect,avb=vbmeta_vendor,first_stage_mount
  • ro:只读挂载,保证系统完整性。
  • barrier=1:ext4 日志屏障,提升数据安全。
  • discard:支持 TRIM,延长闪存寿命。
  • slotselect:A/B 分区场景下选择当前 slot。
  • avb=vbmeta_vendor:指定 AVB 校验元数据分区。
  • first_stage_mount:在 init 第一阶段挂载,供早期服务使用。

五、常见误区与复盘

误区一:把 system 的库直接放进 vendor。 这会造成 system/vendor 接口耦合,OTA 升级时容易冲突。正确做法是通过 HAL 接口暴露能力,而不是直接共享 .so。

误区二:忽略 VINTF 清单更新。 新增或升级 HAL 后,必须同步更新 vendor 的 manifest.xml,否则 system 侧无法发现该 HAL。

误区三:调试时关闭 verity 后忘记恢复。 量产前必须重新启用 dm-verity 与 AVB,否则安全启动链不完整。

排查 vendor 相关问题时,可以按以下顺序定位:先确认 /vendor 是否挂载成功,再检查 init.vendor.rc 中服务是否启动,然后查看 VINTF 兼容性日志,最后确认内核模块与固件是否加载。常用命令如下:

adb shell mount | grep vendor
adb shell dmesg | grep -i vendor
adb shell logcat | grep -i vintf
adb shell ls /vendor/lib/modules
adb shell getprop | grep vendor

掌握 vendor 分区的目录布局、关键文件、镜像生成流程与挂载选项,能够帮助你在系统集成阶段快速判断问题出在构建、打包还是运行时加载环节,从而缩短调试周期,提高集成效率。