如何在 Raspberry Pi 上部署一个最小化的 Android 系统?
解读
面试官问“最小化 Android 系统”并不是让你背 AOSP 源码行数,而是考察三件事:
- 你对 AOSP 编译链路的熟悉度——能否把 120 G 的源码裁到能在树莓派 4(4 GB RAM)上 30 s 内启动。
- 你对国内合规环境的敏感度——能否在不带 GMS 的前提下,把基本功能(Wi-Fi、蓝牙、GPU、音视管道)跑通,并给后续 OTA 留出接口。
- 你对嵌入式性能与维护成本的权衡——能否用一张 16 GB SD 卡交付,后续还能通过 adb 无线调试、fastboot 更新 bootimg,满足量产级维护。
一句话:面试官想看“你会砍、会改、会跑、会维护”。
知识点
- AOSP 源码管理:repo 清单、local_manifest、remove-project 机制,国内镜像清华/中科大源。
- 产品分区裁剪:
- 关闭编译模块:在 device.mk 中删除 Calendar、Email、Launcher3QuickStep、Markup 等。
- 关闭系统服务:在 system/core/rootdir/init.rc 中注释掉 statsd、incidentd、updatable 组件。
- 关闭 Dalvik 优化:PRODUCT_ART_TARGET_INCLUDE_DEBUG_BUILD := true,节省 preopt 空间 400 MB+。
- BoardConfig 级配置:
- TARGET_ARCH := arm64,KERNEL_DEFCONFIG := bcm2711_defconfig + android-base.cfg + android-recommended.cfg。
- BOARD_KERNEL_CMDLINE 去掉 quiet splash,加入 console=serial0,115200 方便串口调试。
- BOARD_BOOTIMAGE_PARTITION_SIZE := 67108864(64 MB),system 分区压缩到 1.2 GB 以下,vendor 400 MB。
- HAL 适配:
- 图形:drm_hwcomposer + mesa3d v3d 驱动,关闭 gralloc4 改用 gralloc.default 减少依赖。
- 音频:usb_audio HAL,树莓派无板载音频 codec,直接走 3.5 mm 或 HDMI。
- 摄像头:legacy mm-camera-v4l2 兼容层,或直接用 external/v4l2_camera HAL。
- 国内合规:
- 不预装 GMS,用 Mopria/开源打印服务替代 PrintSpooler;用 F-Droid 作为应用市场占位。
- 关闭 GSF 相关接口,避免应用拉取 Google 服务导致空指针。
- 启动优化:
- 关闭 bootanimation,改单帧静态 logo,节省 2 s。
- 把 zygote 启动提前到 class_start core,并行启动 surfaceflinger。
- 用 dex2oat-filter=quicken,首次启动牺牲 5 % 性能,换 40 s 启动时间。
- 调试与维护:
- adb over USB-OTG:在 init.usb.configfs.rc 中配置 usb_gadget 的 adb 功能。
- 无线 adb:系统属性 persist.adb.tcp.port=5555,配合 wpa_supplicant 开机自连测试路由。
- OTA 方案:编译生成 brillo update_payload,用 recovery 模式 sideload,或自研 AB 系统差分包。
答案
分五步落地,全部命令在 Ubuntu 20.04 主机上完成,目标设备 Raspberry Pi 4B(4 GB)。
第一步:准备国内源码环境
mkdir ~/bin && curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o ~/bin/repo
chmod +x ~/bin/repo
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
repo init -u https://mirrors.tuna.tsinghua.edu.cn/aosp/platform/manifest -b android-13.0.0_r41 --depth=1
repo sync -c -j8
第二步:拉取树莓派设备树
git clone https://github.com/raspberry-vanilla/android_device_brcm_rpi4 device/brcm/rpi4 --depth=1
git clone https://github.com/raspberry-vanilla/android_kernel_brcm_rpi kernel/brcm/rpi4 --depth=1
在 .repo/local_manifests/rpi4.xml 中写入 remove-project 把默认 phone、telephony 相关仓库剔除,节省 10 GB。
第三步:配置最小化产品
在 device/brcm/rpi4/rpi4.mk 末尾追加:
PRODUCT_NAME := rpi4_min
PRODUCT_DEVICE := rpi4
PRODUCT_SYSTEM_SERVER_JARS := \
services \
wifi-service
砍掉所有非核心 apk
PRODUCT_PACKAGES += \
Settings \
SystemUI \
F-DroidPrivilegedExtension
PRODUCT_SYSTEM_PROPERTIES += \
ro.config.avoid_gfx_accel=false \
ro.kernel.qemu=0 \
persist.sys.disable_rescue=true
第四步:编译
source build/envsetup.sh
lunch rpi4_min-userdebug
make -j$(nproc) 2>&1 | tee build.log
首次编译约 90 min,生成 out/target/product/rpi4/super.img 1.1 GB,vendor.img 380 MB,boot.img 58 MB。
第五步:烧录与启动
sudo apt install android-tools-fsutils
img2simg out/target/product/rpi4/super.img super_raw.img
sudo dd if=super_raw.img of=/dev/mmcblk0p2 bs=1M
sudo dd if=out/target/product/rpi4/boot.img of=/dev/mmcblk0p1 bs=1M
插入 SD 卡上电,串口 115200 下 28 s 进入 Launcher,空闲内存 1.8 GB,系统占用 4.3 GB SD 空间,达成最小化目标。
拓展思考
- 如果客户后续要加人脸识别门禁,需要 Camera2 HAL + TEE,如何在现有 drm_hwcomposer 之上把 Trusty OS 裁进去?
- 国内项目常要求“关机充电画面”,但树莓派无 PMIC,如何用 GPIO 模拟电池事件并改写 healthd?
- 若走量产,SD 卡寿命不足,需 eMMC 模块;如何迁移到 UFS 并打开 Android 的 AB 无缝更新,同时保持 16 ms 帧率?
- 最小化系统往往把 Settings 也裁掉,结果无法开 Wi-Fi;如何用命令行 wpa_supplicant 生成初始配置,并在首次启动向导里用 Flutter 写 2 MB 的极简设置 APK?
- 面试官可能追问“为什么不用 Android Things”,需准备一句话:Android Things 已停止维护,AOSP 13 + 自裁方案才是长期可控路线。