分区布局详解:boot、system、vendor、product、odm、userdata 分区的作用与挂载点
各位同学,咱们今天聊聊 Android Automotive 的分区布局。说实话,这块内容我刚开始接触时也觉得有点绕,尤其是车载系统比手机多了不少定制分区。但搞懂了这些分区各自管什么、挂在哪,你排查存储问题就能快人一步。
我个人习惯把分区布局比作一个房子的功能区划分——客厅、卧室、厨房各司其职。Android 的分区设计也是这个道理,每个分区都有明确的职责,不能乱放东西。
1. boot 分区:系统的启动引擎
boot 分区存的是什么?说白了就是 Linux 内核和 ramdisk。系统上电后,bootloader 第一个找的就是它。
挂载点: 不直接挂载到文件系统,由 bootloader 读取后加载到内存。
大小: 通常 32MB~64MB,车载项目里我见过最大的也就 128MB。
核心内容:
- Linux 内核镜像(zImage/Image.gz)
- 设备树文件(DTB/DTBO)
- initramfs(早期根文件系统)
我的经验: 有一次我在车载项目里改了内核配置,编译后刷机发现起不来。查了半天,原来是 boot 分区空间不够,内核镜像被截断了。从那以后,我每次改内核都会先确认分区剩余空间。
2. system 分区:系统的核心躯干
system 分区承载了整个 Android 框架。所有系统级应用、库文件、服务都在这里。在 Automotive 里,它通常挂载为只读。
挂载点: /system
文件系统: 早期用 ext4,现在主流是 EROFS(增强型只读文件系统)。
| 属性 | 说明 |
|---|---|
| 权限 | 只读(ro) |
| 典型大小 | 1GB~4GB(车载项目通常 2GB 起步) |
| 包含内容 | /system/app, /system/framework, /system/lib 等 |
你想想看,如果 system 分区是可写的,那用户随便删个系统文件,车机可能就变砖了。所以 Google 从 Android 10 开始强制要求 system 分区只读。
注意: 在 Automotive 里,system 分区通常和 vendor 分区解耦。这意味着你升级系统镜像时,不需要同时刷 vendor 分区。这个设计我在做 OTA 方案时深有体会——省了不少事。
3. vendor 分区:硬件厂商的专属领地
vendor 分区存放的是硬件相关的二进制文件。比如显示驱动、传感器 HAL、Wi-Fi 固件等。这个分区由芯片厂商或硬件制造商维护。
挂载点: /vendor
为什么需要它? 因为 system 分区是通用的 Android 框架,而 vendor 分区是硬件专属的。两者分开后,Google 可以单独更新 system 分区,厂商可以单独更新 vendor 分区,互不干扰。
典型内容:
- /vendor/lib/hw/(硬件 HAL 库)
- /vendor/etc/(硬件相关配置文件)
- /vendor/firmware/(固件文件)
- /vendor/bin/(硬件相关守护进程)
我记得有个项目,客户要求把某个传感器驱动放到 system 分区里。我直接拒绝了——这不符合 Treble 架构的设计理念。后来客户自己试了,结果 OTA 升级时驱动不兼容,折腾了两周才改回来。
4. product 分区:产品定制的舞台
product 分区是 Android 10 引入的,专门给设备制造商做产品级定制。比如车载厂商的特定 UI、预装应用、品牌资源等。
挂载点: /product
和 system 的区别: system 是 Google 维护的通用代码,product 是厂商自己加的定制内容。这样 Google 发新版系统时,厂商的定制内容不会冲突。
| 分区 | 维护方 | 更新频率 |
|---|---|---|
| system | 随 Android 版本更新 | |
| product | 设备制造商 | 随产品迭代更新 |
| vendor | 芯片/硬件厂商 | 随 BSP 更新 |
避坑指南: 我曾经在 product 分区里放了一个很大的 3D 模型资源,结果导致分区空间不足,OTA 升级失败。后来我养成了习惯——每次往 product 分区加东西前,先算算剩余空间,再评估一下是否真的需要放在这里。
5. odm 分区:原始设计制造商的秘密花园
ODM(Original Design Manufacturer)分区,说白了就是给 ODM 厂商留的定制空间。比如一家 ODM 同时给多个品牌做车机,每个品牌的差异化配置就可以放在 odm 分区里。
挂载点: /odm
和 vendor 的关系: vendor 是芯片级定制,odm 是板级定制。举个例子——同一款高通芯片,A 厂商用 4GB 内存,B 厂商用 6GB 内存,内存相关的配置就放 odm 分区。
常见用途:
- 板级设备树覆盖(DTBO)
- 外设配置(如摄像头模组参数)
- 特定硬件校准数据
嗯,这里要注意:odm 分区不是必须的。如果你的产品没有 ODM 定制需求,完全可以不用这个分区。我在一些低端车载项目里就没见过 odm 分区。
6. userdata 分区:用户数据的仓库
userdata 分区是唯一一个用户可读写的分区。所有用户安装的应用、下载的文件、系统设置、账号信息都存在这里。
挂载点: /data
文件系统: F2FS 或 ext4,现在主流是 F2FS(针对闪存优化)。
| 子目录 | 用途 |
|---|---|
| /data/app/ | 用户安装的应用 |
| /data/data/ | 应用私有数据 |
| /data/system/ | 系统设置和配置 |
| /data/media/ | 用户媒体文件(照片、音乐等) |
重要提醒: 在 Automotive 里,userdata 分区通常需要支持多用户。因为一辆车可能有多位驾驶员,每位都有自己的配置。我做过一个项目,要求支持 8 个用户账户,每个账户 2GB 空间配额。分区规划时就得提前算好总容量。
分区挂载顺序与依赖关系
这些分区不是同时挂载的,有严格的先后顺序。我画个简单的流程给你看:
bootloader → 加载 boot 分区内核
↓
内核启动 → 挂载 system 分区(只读)
↓
init 进程 → 挂载 vendor 分区
↓
→ 挂载 product 分区
↓
→ 挂载 odm 分区(如果存在)
↓
Zygote 启动 → 挂载 userdata 分区(读写)
为什么会这样?因为 system 分区里的 init 进程需要先启动,然后才能加载 vendor 的 HAL 服务。而 userdata 分区要等到系统框架准备好后才能挂载——否则用户数据还没解密,挂载了也没用。
我的调试技巧: 如果系统启动卡住了,我通常会先检查挂载日志。用 dmesg | grep mount 看看哪个分区挂载失败了。有一次我发现 vendor 分区挂载超时,原因是分区表被意外修改了。这种问题不看日志根本想不到。
分区大小规划建议
最后,我根据实际项目经验,给出一份 Automotive 分区大小的参考值:
| 分区 | 建议大小 | 备注 |
|---|---|---|
| boot | 64MB | 留够冗余,内核越来越大 |
| system | 2GB~4GB | 取决于 Android 版本和 GMS 大小 |
| vendor | 1GB~2GB | 硬件 HAL 和固件占大头 |
| product | 512MB~1GB | 定制内容多就大一点 |
| odm | 128MB~512MB | 非必需,按需分配 |
| userdata | 剩余全部 | 至少 8GB,多用户建议 32GB+ |
记住,分区大小不是拍脑袋定的。我一般会在项目初期用 du -sh 统计每个目录的实际大小,再乘以 1.5 的安全系数。这样既不会浪费空间,也不会出现分区不够用的尴尬。
好了,分区布局这块就讲到这里。下一章咱们聊聊存储性能优化,到时候我会分享一些实际调优的案例。