全志A40i Android 7.1固件编译实战手册:从源码到镜像的深度解析
第一次接触全志A40i平台时,我花了整整三天时间才成功编译出第一个可启动的Android镜像。期间经历了无数次Makefile报错、环境变量配置错误和路径问题,甚至一度怀疑是硬件兼容性问题。这份手册将系统性地梳理从U-boot到完整固件打包的全流程,特别针对那些官方文档没有明确说明的"坑点"给出解决方案。不同于常规教程只告诉你"怎么做",我们会深入分析"为什么这么做",帮助开发者建立完整的编译知识体系。
1. 开发环境搭建与前期准备
在开始编译之前,环境配置的完整性直接决定了后续流程的顺利程度。全志A40i的Android 7.1 BSP对编译环境有特定要求,任何版本偏差都可能导致难以排查的问题。
必须使用Ubuntu 16.04 LTS作为基础系统,这是经过验证最稳定的编译环境。新版本Ubuntu的glibc和工具链可能会引发兼容性问题。建议通过以下命令检查系统版本:
lsb_release -a安装必要的依赖包时,需要特别注意32位库的支持:
sudo apt-get install git-core gnupg flex bison gperf build-essential \ zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 \ lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache \ libgl1-mesa-dev libxml2-utils xsltproc unzip提示:建议分配至少200GB磁盘空间,Android源码编译过程中会产生大量中间文件,完整编译后占用空间约150GB。
配置Java环境时,Android 7.1需要OpenJDK 8:
sudo apt-get install openjdk-8-jdk验证Java版本时应显示类似如下信息:
openjdk version "1.8.0_292" OpenJDK Runtime Environment (build 1.8.0_292-8u292-b10-0ubuntu1~16.04.1-b10) OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)2. U-boot编译问题深度剖析
U-boot作为系统启动的第一阶段,其编译过程往往最先暴露环境配置问题。全志A40i使用的U-boot 2014.07版本在现代化编译环境中会遇到几个典型问题。
进入U-boot目录后:
cd a40i_android7/lichee/brandy执行编译命令时:
./build.sh -p sun8iw11p1最常见的Makefile报错表现为:
Makefile:1218: *** missing separator. Stop.这个问题源于Makefile中tags生成规则的语法兼容性问题。通过对比分析原始文件和修改后的差异,可以发现关键修改点:
diff --git a/lichee/brandy/u-boot-2014.07/Makefile b/lichee/brandy/u-boot-2014.07/Makefile index 21d8b03..6575687 100755 --- a/lichee/brandy/u-boot-2014.07/Makefile +++ b/lichee/brandy/u-boot-2014.07/Makefile @@ -1214,8 +1214,7 @@ tpl/u-boot-tpl.bin: tools prepare TAG_SUBDIRS := $(u-boot-dirs) include sunxi_spl FIND := find -FINDFLAGS := -L --R --c++-kinds=+p --fields=+iaS --extra=+q +FINDFLAGS := -L -R --c++-kinds=+p --fields=+iaS --extra=+q tags ctags: ctags -w -o ctags `$(FIND) $(FINDFLAGS) $(TAG_SUBDIRS) \ - -name '*.[chS]' -print`这个修改解决了两个问题:
- 移除了多余的
--前缀,使用标准的-R参数 - 修复了命令结尾多余的
\换行符
编译成功后,应该在lichee/brandy/u-boot-2014.07目录下生成以下关键文件:
u-boot.bin:主二进制文件u-boot-sunxi-with-spl.bin:带SPL的完整镜像
3. Kernel编译配置技巧
内核编译是全志平台最具挑战性的环节之一,正确的配置选择直接影响后续Android系统的稳定性。进入内核目录:
cd a40i_android7/lichee赋予编译脚本执行权限:
chmod 777 build.sh执行配置命令时,选择正确的平台类型至关重要:
./build.sh config配置界面会出现多个选项层级,对于A40i Android 7.1开发板,正确的选择路径是:
- 芯片选择:
sun8iw11p1 - 平台选择:
android(不是androidm) - 内核版本:
linux-3.10 - 开发板型号:
a40-p1
注意:平台类型必须选择android而非androidm,这个选择会直接影响后续extract-bsp和pack命令的行为。
编译内核时,可以使用多线程加速:
./build.sh -j64成功编译后,关键输出文件位于:
lichee/out/sun8iw11p1/android/common/ ├── bImage ├── lib/ │ └── modules/ └── sun8iw11p1_android_a40-p1.dtb4. Android系统编译与集成
Android部分的编译需要特别注意环境变量的设置和源码的同步。进入Android目录:
cd a40i_android7/android初始化编译环境:
source build/envsetup.sh选择正确的lunch组合:
lunch a40-p1extract-bsp阶段是最容易出错的环节之一。当出现如下报错时:
cp: cannot stat '/home/.../lichee/out/sun8iw11p1/androidm/common/bImage': No such file or directory问题根源在于vendorsetup.sh中错误的路径配置。需要修改:
diff --git a/device/softwinner/common/vendorsetup.sh b/device/softwinner/common/vendorsetup.sh index a3be43d..b825fce 100644 --- a/device/softwinner/common/vendorsetup.sh +++ b/device/softwinner/common/vendorsetup.sh @@ -65,7 +65,7 @@ function get_lichee_out_dir() LINUXOUT_DIR=$LICHEE_DIR/out/sun8iw11p1/androidm/common fi if [ "$TARGET_BOARD_PLATFORM" == "a40" ]; then - LINUXOUT_DIR=$LICHEE_DIR/out/sun8iw11p1/androidm/common + LINUXOUT_DIR=$LICHEE_DIR/out/sun8iw11p1/android/common fi LINUXOUT_MODULE_DIR=$LINUXOUT_DIR/lib/modules/*/* }这个修改确保系统从正确的android目录而非androidm目录查找内核镜像。
开始编译Android系统:
make -j64编译过程中可能遇到的内存问题可以通过以下方式缓解:
export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4096m" ./prebuilts/sdk/tools/jack-admin kill-server ./prebuilts/sdk/tools/jack-admin start-server5. 固件打包与验证
打包阶段是将所有组件集成为可烧写镜像的最后一步,也是最容易出现路径一致性问题的环节。
执行打包命令:
pack当遇到ERROR: build lichee before you pack错误时,需要检查package.sh中的平台配置:
diff --git a/device/softwinner/a40-p1/package.sh b/device/softwinner/a40-p1/package.sh index 6ad9395..60c8c34 100644 --- a/device/softwinner/a40-p1/package.sh +++ b/device/softwinner/a40-p1/package.sh @@ -3,7 +3,7 @@ cd $PACKAGE chip=sun8iw11p1 -platform=androidm +platform=android board=a40-p1 debug=uart0 sigmode=none成功打包后,生成的固件位于:
a40i_android7/out/target/product/a40-p1/a40-p1_android_xxx.img验证镜像完整性的快速方法:
file a40-p1_android_xxx.img应该显示类似以下信息:
a40-p1_android_xxx.img: DOS/MBR boot sector在实际项目中,我发现最稳定的编译流程是严格按照U-boot → Kernel → Android → Pack的顺序执行,每个阶段完成后立即验证输出文件是否存在。保持lichee和android目录的相对路径不变也非常关键,任何移动都可能破坏编译脚本中的相对路径引用。