1. 问题现象与背景解析
最近在基于Amlogic平台编译Android 9.0系统镜像时,遇到了一个典型问题:编译过程中提示system分区空间不足(常见报错如Error: out of space in system partition)。这种情况在嵌入式设备开发中尤为常见,特别是当厂商提供的分区表(partition table)配置与系统实际需求不匹配时。
Amlogic方案常见于电视盒子、智能投影仪等设备,其硬件配置往往比较精简。原厂提供的分区方案通常按照最小化需求设计,而当我们添加自定义应用、服务或功能模块后,很容易突破默认的system分区限制。我在S905X3平台上的实测数据显示,原始system分区大小通常为1.2GB左右,而完整编译AOSP 9.0后镜像体积可达1.5GB以上。
关键提示:分区不足问题通常出现在
make otapackage或img_from_target_files阶段,此时系统会校验各分区大小是否足够容纳生成的镜像文件。
2. 根本原因深度分析
2.1 分区表机制剖析
Amlogic平台使用aml_sdc_burn.ini或parameter.txt定义分区布局,其中关键参数包括:
partition_size:分区物理大小(单位通常为MB)file_size:镜像文件最大限制start_address:分区起始地址
在Android编译流程中,build/core/Makefile会调用build/tools/releasetools/build_image.py生成system.img,此时会严格校验以下条件:
python复制if actual_size > partition_size:
raise ValueError("system image size exceeds partition size")
2.2 空间占用主要因素
通过du -sh out/target/product/[设备]/system/分析,发现主要空间消耗来自:
- 预装应用:如GMS套件平均占用300MB+
- 库文件:
/system/lib/和/system/lib64/下的.so文件 - 框架资源:
/system/framework/中的jar和资源包 - 厂商定制:Amlolgic特有的
/system/vendor/驱动和配置
实测数据对比表:
| 组件类型 | 默认大小 | 定制后大小 | 增长比例 |
|---|---|---|---|
| 系统应用 | 450MB | 620MB | +38% |
| 原生库文件 | 320MB | 410MB | +28% |
| 框架资源 | 280MB | 350MB | +25% |
| 厂商驱动 | 150MB | 220MB | +47% |
3. 解决方案与实操步骤
3.1 调整分区表参数
找到设备对应的分区配置文件(通常位于device/amlogic/[设备]/):
- 修改
BoardConfig.mk中的系统分区大小:
makefile复制BOARD_SYSTEMIMAGE_PARTITION_SIZE := 2147483648 # 2GB
- 同步更新烧录工具配置(如
aml_sdc_burn.ini):
ini复制[partition]
name = system
size = 2048 # 单位MB
- 对于OTA升级包,还需修改
releasetools.py中的校验阈值:
python复制system_size = image_utils.GetSimgSize(system_img)
assert system_size <= 2147483648, "system image too large"
3.2 精简系统镜像方案
如果硬件限制无法扩大分区,可采用以下精简策略:
3.2.1 移除非必要组件
在device.mk中添加:
makefile复制PRODUCT_PACKAGES := \
$(filter-out LiveWallpapers PhotoTable, $(PRODUCT_PACKAGES))
3.2.2 启用文件系统压缩
修改BoardConfig.mk:
makefile复制BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE := ext4
BOARD_SYSTEMIMAGE_EXTFS_INODE_COUNT := -1
WITH_DEXPREOPT := true
3.2.3 符号链接优化
将大体积静态文件移入vendor分区:
makefile复制PRODUCT_PACKAGES += \
libamcodec.symlink \
libamavutils.symlink
3.3 动态分区方案(Android 9+)
对于支持动态分区的设备:
- 启用
super分区:
makefile复制BOARD_AMLOGIC_DYNAMIC_PARTITIONS_ENABLE := true
BOARD_BUILD_SUPER_IMAGE_BY_DEFAULT := true
- 配置分区大小上限:
makefile复制BOARD_AMLOGIC_DYNAMIC_PARTITIONS_SIZE := 4294967296 # 4GB
BOARD_SUPER_PARTITION_GROUPS := amlogic_dynamic_partitions
4. 验证与调试技巧
4.1 镜像大小预检查
编译前预估镜像体积:
bash复制prebuilts/build-tools/linux-x86/bin/fs_config -s out/target/product/[设备]/system
4.2 分区表烧录验证
通过Amlogic烧录工具检查实际分区:
bash复制adb shell cat /proc/partitions
adb shell ls -l /dev/block/by-name/
4.3 常见错误排查
- 大小校验失败:
log复制AssertionError: system image size exceeds partition size
解决方法:检查BoardConfig.mk与parameter.txt的大小是否一致
- 烧录时报错:
log复制[0x10105002]Romcode/初始化DDR/下载数据/读取镜像失败
解决方法:确认aml_sdc_burn.ini中的start_address与大小匹配
- 启动时卡LOGO:
log复制avc: denied { read } for pid=xxx
解决方法:检查file_contexts中的文件路径是否正确
5. 进阶优化建议
5.1 文件系统级优化
- 使用
e2fsck -f检查ext4文件系统碎片 - 调整inode数量(默认每16KB一个inode):
bash复制make_ext4fs -l 2G -i 8192 system.img system
5.2 厂商定制技巧
对于Amlogic平台特有优化:
- 精简
/system/vendor/amlogic/下的测试组件 - 替换大体积的
libomx.so为轻量版 - 使用
strip裁剪调试符号:
bash复制arm-linux-androideabi-strip --strip-unneeded lib/*.so
5.3 编译系统hack
临时绕过大小校验(仅调试用):
python复制# 修改build_image.py
def BuildImage(in_dir, ...):
try:
CheckSize(in_dir, ...)
except ValueError as e:
print("WARNING: " + str(e))
pass
6. 实测案例分享
以Amlogic S905X4平台为例,原始配置:
system分区:1.5GB- 实际需求:1.8GB
优化方案实施步骤:
- 修改
device/amlogic/g12-common/BoardConfig.mk:
makefile复制BOARD_SYSTEMIMAGE_PARTITION_SIZE := 2147483648 # 2GB
- 更新烧录配置
aml_sdc_burn.ini:
ini复制[partition]
name = system
size = 2048
start_address = 0x1000000
- 执行编译验证:
bash复制make -j12 otapackage 2>&1 | tee build.log
- 烧录后通过
df -h确认:
bash复制/dev/block/by-name/system 2.0G 1.7G 300M 85% /system
7. 经验总结
在多次处理Amlogic平台分区问题后,我总结出几个关键点:
- 提前规划:在项目启动阶段就根据功能清单预估
system分区需求 - 安全边际:建议预留至少15%的余量应对后期需求变更
- 版本控制:将
parameter.txt纳入git管理,避免不同版本混淆 - 工具链验证:使用
aml_upgrade_package_gen.sh提前校验分区配置
一个实用的调试技巧是:当遇到难以定位的空间异常增长时,可以:
bash复制cd out/target/product/[设备]/system/
du -sh * | sort -h
这能快速定位到具体哪个目录出现了异常占用。