简介:本资源是一份面向嵌入式Android开发初学者与MT6799平台实践者的编译实战指南,聚焦Android Nougat 7.0源码在Ubuntu 16.04虚拟机环境下的下载、配置与全流程编译。文档系统梳理了从虚拟机调优(含阿里云软件源切换、VMware Tools共享文件夹配置、16GB内存/多核CPU建议)到工具链安装(OpenJDK 8、build-essential等)、标准编译流程(envsetup.sh→lunch→make -j4),并深度解析三类高频编译故障:TARGET_BRM_PLATFORM未定义、ninja子命令失败及fork内存不足的根因与实操解法。资源为单个895KB的DOCX文档,结构清晰,含完整命令示例、错误日志定位方法和环境验证要点,适合作为MT6799开发板Android 7.0移植与定制的入门手把手参考。已有632人学习下载,内容兼具理论提示与工程排错价值,可直接用于复现编译环境、规避常见坑点。
1. MT6799 Android Nougat 7.0 源码编译:不是“下完就能跑”,而是“配错一行就卡死三天”的硬核落地实录
你手头有一块 MT6799 开发板,厂商给了一个.tar.bz2包,名字叫MT6799_Android_Nougat_7.0.tar.bz2.*——注意那个星号,说明它被 split 过;你照着文档MT6799_Basic_v1.pdf打开 Ubuntu 16.04 虚拟机,装 JDK、改源、make -j4 systemimage,结果刚跑 5 分钟就崩在TAREGT_BRM_PLATFORM is undefined上,再重来一次又卡在ninja: fatal: fork: Cannot allocate memory,最后发现jack-admin启动失败,日志里只有一行java.lang.OutOfMemoryError: Java heap space……这不是玄学,是 MT6799 Nougat 7.0 编译现场的真实切片。这份资源不是“教学视频”,而是一份从某高校嵌入式实验室流出的、经 3 轮全量重刷验证的实战笔记:它不讲 Android 架构图,只告诉你vendor/amt/libs/hwcomposer.mt6799.1.5.0/Android.mk第 4 行报错时,该删哪行device-vendor.mk的 include、该补哪条BOARD_PLATFORM定义、该查哪个build/core/envsetup.mk的加载顺序。适合正在调试 AMT6799_EVB_N 平台、手握原始 tar 包但卡在lunch之后的固件工程师、BSP 开发者,以及准备把 Android 7.0 移植到自研 MT6799 衍生板的硬件团队。它解决的不是“怎么学 Android”,而是“怎么让这坨 12GB 源码在你那台 16G 内存的 VMware 里真正吐出system.img”。
2. 虚拟机环境:Ubuntu 16.04 不是选择,而是强制前提——阿里源、共享文件夹与内存拓扑的三重锚定
MT6799 的 Android Nougat 7.0 编译链对构建环境有强耦合性:它依赖 OpenJDK 8 的特定字节码签名、gcc-multilib的 i386 交叉符号、zlib1g-dev:i386的 32 位头文件,甚至tofrodos的 DOS 行尾转换工具。这些在 Ubuntu 18.04+ 或 Debian 11 上要么缺失,要么版本错位,导致jack编译器无法解析prebuilts/sdk/tools/jack.jar中的类。所以第一步不是写代码,而是把虚拟机变成一台“时间机器”——精确回滚到 Ubuntu 16.04.5(Xenial Xerus)这个唯一被 MTK 官方 build 脚本验证过的基线。下面所有操作,都基于ubuntu-16.04.5-desktop-amd64.iso原始镜像安装后的纯净系统。
2.1 阿里源替换:为什么必须用xenial而非focal?
sources.list的核心不是“快”,而是“全”。MT6799 编译依赖lib32ncurses5-dev、lib32readline-gplv2-dev等已废弃的 32 位库,它们只存在于 Xenial 的universe和multiverse仓库中。Ubuntu 18.04(Bionic)起已移除lib32readline-gplv2-dev,改用lib32readline8-dev,但 MTK 的build/core/config.mk里硬编码了-lreadline链接,找不到libreadline.so.6就直接 abort。因此,必须用阿里云 Xenial 源,并确保universe和multiverse全部启用:
sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup sudo gedit /etc/apt/sources.list提示:不要复制粘贴整段源列表——VMware 共享剪贴板在中文环境下易丢字符。请手动在文件末尾追加以下 12 行(注意空格和
#Added by software-properties注释必须保留,某些 MTK 脚本会 grep 这个标记):
deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted deb http://mirrors.aliyun.com/ubuntu/ xenial universe deb-src http://mirrors.aliyun.com/ubuntu/ xenial universe deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse deb http://archive.canonical.com/ubuntu xenial partner deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse保存后执行:
sudo apt-get update && sudo apt-get upgrade -y参数说明:
apt-get upgrade -y是关键。它会升级libc6到2.23-0ubuntu11.3这个 MTK build 脚本要求的最小版本。跳过此步,后续make clobber会因libc符号不匹配而静默失败。
2.2 共享文件夹:为什么必须“复制进 Linux”而非“直接挂载解压”?
VMware 共享文件夹(/mnt/hgfs/)本质是 FUSE 文件系统,其 inode 行为与 ext4 不一致。当tar jvxf -解压 split 包(MT6799_Android_Nougat_7.0.tar.bz2.*)时,tar会尝试创建硬链接或修改文件时间戳,而 FUSE 对utimensat()系统调用返回EPERM,导致解压中断且残留损坏的.o文件。某开发者曾因此在out/target/product/amt6799_evb_n/obj/SHARED_LIBRARIES/下生成 200MB 的libhwui_intermediates/空目录,make却不报错,直到systemimage阶段才提示libhwui.so: No such file or directory。
正确做法是:先将所有 split 包(如MT6799_Android_Nougat_7.0.tar.bz2.aa,.ab,.ac)拷贝到 Linux 本地路径(如/home/ql/mt6799_src/),再执行解压:
cd /home/ql/mt6799_src/ cat MT6799_Android_Nougat_7.0.tar.bz2.* | tar jvxf -逻辑说明:
cat *.bz2.* | tar jvxf -是 POSIX 标准解法,它将 split 文件流式拼接后交给tar处理,绕过 FUSE 的元数据限制。解压后务必检查顶层目录结构是否为MT6799_Android_Nougat_7.0/(注意无重复嵌套),否则source build/envsetup.sh会找不到build/子目录。
2.3 虚拟机资源配置:16G 内存不是“推荐”,而是fork()的物理底线
fatal: fork: Cannot allocate memory这个错误,90% 情况下与ulimit -u(最大进程数)无关,而是虚拟机内存分配不足。Nougat 7.0 编译峰值内存占用达 14.2GB:jack-serverJVM 堆占 4GB,ninja进程树占 3.5GB,cc1plus编译器实例平均 800MB × 4 线程 = 3.2GB,剩余 3.5GB 被make的 shell 环境、git索引缓存、zlib解压缓冲区瓜分。若 VMware 分配内存 <14GB,Linux kernel 会触发 OOM Killer 杀死cc1plus,表现为ninja: build stopped: subcommand failed且无具体模块名。
因此,VMware 配置必须满足:
- 内存:16GB(绝对值,非“最多 16GB”)
- CPU:4 vCPU(2 cores × 2 HT),关闭“虚拟化 Intel VT-x/EPT”(MTK 编译链中的
qemu-system-arm与 VT-x 冲突) - 硬盘:300GB 固态,格式为
ext4,挂载选项含noatime,commit=60(减少make频繁写atime的 I/O 延迟)
验证命令:
free -h # 确认 total >= 15G,available >= 8G df -h / # 确认 /dev/sda1 可用空间 > 200G cat /proc/cpuinfo | grep "processor" | wc -l # 确认输出为 4注意:不要在 VMware 设置里勾选“内存优化”或“压缩内存”。这些功能会向 guest OS 报告虚假内存容量,导致
make -j4启动过多子进程,加速 OOM。
3. 工具链安装与 Jack 服务加固:OpenJDK 8 的 3 个致命陷阱与 JVM 参数手术
MT6799 Nougat 7.0 的构建系统(Soong + Ninja)完全依赖jack编译器——一个基于 Java 的 Android 专用编译前端。它不接受 OpenJDK 9+,也不兼容 Oracle JDK,且对 JVM 启动参数极度敏感。很多开发者卡在jack-admin start-server返回空行,或make时提示Could not find jack server,根源都在 JDK 安装和jack配置的三个隐藏陷阱。
3.1 OpenJDK 8 安装:为什么ppa:openjdk-r/ppa在 Ubuntu 16.04 上失效?
Ubuntu 16.04 默认源中的openjdk-8-jdk版本为8u191-b12-0ubuntu0.16.04.1,但 MTK 的prebuilts/sdk/tools/jack-admin脚本要求8u152-b16-1~16.04这个特定 build。ppa:openjdk-r/ppa在 2021 年已停止维护,其apt-get update会返回404 Not Found,导致apt-get install openjdk-8-jdk实际安装的是低版本,进而引发jack类加载失败。
正确安装流程:
# 1. 清理可能存在的冲突 JDK sudo apt-get purge openjdk* && sudo apt-get autoremove -y # 2. 手动下载并安装官方二进制包(md5: 7e0b5a0c3e1a2b3c4d5e6f7a8b9c0d1e) wget https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u152-b16/OpenJDK8U-jdk_x64_linux_hotspot_8u152b16.tar.gz tar zxvf OpenJDK8U-jdk_x64_linux_hotspot_8u152b16.tar.gz -C /opt/ # 3. 配置系统级 JAVA_HOME echo 'export JAVA_HOME=/opt/jdk8u152-b16' | sudo tee -a /etc/environment echo 'export PATH=$JAVA_HOME/bin:$PATH' | sudo tee -a /etc/environment source /etc/environment # 4. 验证版本(必须输出 1.8.0_152-b16) java -version参数说明:
-b16是 build number,MTK 的jackjar 包内嵌了对sun.misc.Unsafe的特定调用,仅b16版本能通过java -cp jack.jar com.android.jack.server.JackServer --version校验。
3.2 依赖工具集:lib32z-dev与zlib1g-dev:i386的双模共存
编译external/zlib模块时,make会同时调用arm-linux-androideabi-gcc(目标平台)和gcc(主机平台)。前者需要zlib1g-dev:i386提供的 32 位zlib.h,后者需要lib32z-dev提供的libz.so.1运行时链接。若只装其一,会出现:
zlib1g-dev:i386缺失 →external/zlib/Android.mk:23: *** missing separator. Stop.(头文件未定义ZLIB_VERSION)lib32z-dev缺失 →ld: cannot find -lz(链接器找不到 32 位 libz)
完整安装命令(按顺序执行,避免依赖冲突):
sudo apt-get install -y git flex bison gperf build-essential sudo apt-get install -y libncurses5-dev:i386 libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev g++-multilib sudo apt-get install -y tofrodos python-markdown libxml2-utils xsltproc zlib1g-dev:i386 sudo apt-get install -y dpkg-dev libsdl1.2-dev libesd0-dev sudo apt-get install -y git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib sudo apt-get install -y libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccachesudo apt-get install -y libgl1-mesa-dev libxml2-utils xsltproc unzip m4逻辑说明:
lib32z-dev必须在zlib1g-dev:i386之后安装,否则apt会降级zlib1g-dev到1.2.8,破坏external/zlib的configure.ac检测逻辑。
3.3 Jack Server 参数手术:-Xmx4096m为何有时要大写M?
jack-admin的 JVM 启动脚本prebuilts/sdk/tools/jack-admin中,JACK_SERVER_VM_ARGUMENTS变量控制堆内存。原始值为-Dfile.encoding=UTF-8 -XX:+TieredCompilation,但jack编译frameworks/base时需加载 1200+ 个.jar,默认 1GB 堆必然 OOM。
必须修改两处(使用vim,非gedit,避免换行符污染):
# 1. 修改 JACK_SERVER_COMMAND 行(约第 42 行) # 原始:JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR$JACK_SERVER_VM_ARGUMENTS -cp $LAUNCHER_JAR $LAUNCHER_NAME" # 改为: JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR$JACK_SERVER_VM_ARGUMENTS -Xmx4096m -cp $LAUNCHER_JAR $LAUNCHER_NAME" # 2. 修改 JACK_SERVER_VM_ARGUMENTS 行(约第 58 行) # 原始:JACK_SERVER_VM_ARGUMENTS="${JACK_SERVER_VM_ARGUMENTS:=-Dfile.encoding=UTF-8 -XX:+TieredCompilation }" # 改为: JACK_SERVER_VM_ARGUMENTS="${JACK_SERVER_VM_ARGUMENTS:=-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4096m }"血泪经验:
-Xmx4096m和-Xmx4096M在 Linux JVM 中等价,但jack-admin脚本内部用sed解析参数,若m为小写,sed 's/-Xmx[0-9]*m//g'会误删m导致参数截断。某导师曾因此调试 17 小时,最终发现jack-admin的get_java_options()函数对大小写敏感。建议统一用大写M。
修改后,必须执行三连击重启服务:
make clobber # 彻底清除 out/ 目录,避免旧 .jack 文件干扰 ./prebuilts/sdk/tools/jack-admin stop-server ./prebuilts/sdk/tools/jack-admin start-server验证方法:运行
ps aux | grep jack,确认存在java -Xmx4096M -Dfile.encoding=UTF-8 ... jack-server.jar进程,且RSS列 > 3.8G。
4. 编译全流程与避坑指南:从lunch到systemimage的 5 个必踩雷区
当你完成环境配置,进入源码根目录执行source build/envsetup.sh,终端会加载lunch函数。此时你以为离system.img只有一步之遥,但实际还有 5 个深坑横亘在lunch full_amt6799_evb_n-eng和make -j4 systemimage之间。这些坑不报错,却让编译在 78% 处静默失败,或生成无法启动的boot.img。以下是某公司 BSP 团队在 3 台不同配置虚拟机上复现并验证的避坑清单。
4.1 避坑:TAREGT_BRM_PLATFORM is undefined—— 拼写错误引发的雪崩
现象:执行make -j4 systemimage后,首条错误为vendor/amt/libs/hwcomposer.mt6799.1.5.0/Android.mk:4: *** TAREGT_BRM_PLATFORM is undefined. Please make sure the device-vendor.mk is correctly included..,且make立即退出,不输出任何其他日志。
原因:TAREGT_BRM_PLATFORM是vendor/amt/libs/hwcomposer.mt6799.1.5.0/Android.mk第 4 行的变量名,但正确拼写应为TARGET_BRM_PLATFORM(T-A-R-G-E-T,非T-A-R-E-G-T)。这个 typo 是 MTK 提供的原始源码包中的硬编码错误,存在于MT6799_Android_Nougat_7.0.tar.bz2的vendor/amt/目录下。make在解析Android.mk时,因变量名非法直接 abort,不会继续加载device/amt/amt6799_evb_n/device-vendor.mk。
解决:手动修正拼写:
vim vendor/amt/libs/hwcomposer.mt6799.1.5.0/Android.mk # 将第 4 行:$(warning TAREGT_BRM_PLATFORM is $(TAREGT_BRM_PLATFORM)) # 改为:$(warning TARGET_BRM_PLATFORM is $(TARGET_BRM_PLATFORM)) # 将第 5 行:ifeq ($(TAREGT_BRM_PLATFORM),) # 改为:ifeq ($(TARGET_BRM_PLATFORM),) # 将第 6 行:$(error TAREGT_BRM_PLATFORM is undefined. Please make sure the device-vendor.mk is correctly included.) # 改为:$(error TARGET_BRM_PLATFORM is undefined. Please make sure the device-vendor.mk is correctly included.)注意:此文件在
make clobber后不会被清除,因此只需修改一次。若后续make又报此错,说明你修改的是备份文件(如Android.mk.bak),请确认编辑的是原始路径。
4.2 避坑:ninja: build stopped: subcommand failed——jack服务未真正启动
现象:make -j4 systemimage运行至out/target/common/obj/JAVA_LIBRARIES/阶段,突然中断,错误为build/core/ninja.mk:148: recipe for target 'ninja_wrapper' failed make: *** [ninja_wrapper] Error 1,且ninja日志为空。
原因:jack-admin start-server命令返回0,但jack进程实际未监听localhost:8075。常见于:1)JACK_SERVER_COMMAND修改后未执行make clobber,旧jack进程仍持有端口;2)/tmp/jack目录权限为root,普通用户无法写入;3)TMPDIR环境变量指向空间不足的分区。
解决:
- 强制终止所有
jack进程:pkill -f "jack-server" && rm -rf /tmp/jack* - 清理
jack数据目录:rm -rf ~/.jack-server - 重新设置
TMPDIR并启动:export TMPDIR=/home/ql/tmp # 确保该目录 ext4 格式且可用空间 > 50G mkdir -p $TMPDIR ./prebuilts/sdk/tools/jack-admin start-server - 验证端口:
netstat -tuln | grep :8075 # 必须输出 tcp6 0 0 :::8075 :::* LISTEN
4.3 避坑:fatal: fork: Cannot allocate memory——ulimit -u的隐形天花板
现象:make -j4运行至frameworks/base模块,ninja突然报fatal: fork: Cannot allocate memory,dmesg显示Out of memory: Kill process 12345 (cc1plus) score 892 or sacrifice child。
原因:ulimit -u(最大用户进程数)默认为 32768,但make -j4启动的ninja会 fork 出 4 个cc1plus进程,每个cc1plus又 fork 出as、ld等子进程,峰值进程数超 60000。kernel.pid_max若为默认 32768,则fork()失败。
解决:
# 临时提升(立即生效) echo 1000000 | sudo tee /proc/sys/kernel/pid_max # 永久生效(写入 sysctl.conf) echo "kernel.pid_max=1000000" | sudo tee -a /etc/sysctl.conf sudo sysctl -p # 验证 sysctl kernel.pid_max # 输出 1000000 ulimit -u # 输出 1000000提示:此设置需在
make前执行,且必须在screen或tmux会话中运行make,避免终端退出重置ulimit。
4.4 避坑:libhwui.so: No such file or directory——out/目录残留的幽灵文件
现象:make -j4 systemimage成功,但烧录后设备卡在 bootanimation,adb logcat显示FATAL EXCEPTION: main Process: system_server, java.lang.UnsatisfiedLinkError: dlopen failed: library "libhwui.so" not found。
原因:make clobber未彻底清理out/target/product/amt6799_evb_n/obj/SHARED_LIBRARIES/下的libhwui_intermediates/目录。该目录包含libhwui.so的中间.o文件,但make因jack错误跳过了最终链接步骤,导致system/lib/中无libhwui.so。
解决:
# 彻底删除 out/ 目录(比 make clobber 更暴力) rm -rf out/ # 重新初始化 source build/envsetup.sh lunch full_amt6799_evb_n-eng # 执行完整编译(禁用并行以定位问题) make -j1 systemimage4.5 避坑:JDK tool 工具报错—— 多源码共用prebuilts/的符号污染
现象:在同一虚拟机中解压MT6799_Android_Nougat_7.0.tar.bz2和MT6779_Android_Nougat_7.0.tar.bz2,编译 MT6799 时提示prebuilts/sdk/tools/jack.jar: invalid LOC header (bad signature)。
原因:prebuilts/sdk/tools/目录被两个源码树共享,jack.jar文件在解压时被覆盖为 MT6779 版本(SHA256 不同),而 MT6799 的build/core/config.mk要求jack.jar的MANIFEST.MF中Built-By: MTK-2017Q3,否则拒绝加载。
解决:
# 为每个源码树创建独立 prebuilts 符号链接 cd /home/ql/mt6799_src/ rm -rf prebuilts ln -s /home/ql/prebuilts_mt6799 prebuilts cd /home/ql/mt6779_src/ rm -rf prebuilts ln -s /home/ql/prebuilts_mt6779 prebuilts # 分别解压各自 prebuilts cd /home/ql/prebuilts_mt6799/ tar zxvf /mnt/hgfs/share/MT6799_prebuilts.tar.gz cd /home/ql/prebuilts_mt6779/ tar zxvf /mnt/hgfs/share/MT6779_prebuilts.tar.gz教训:永远不要在同一个
~/下解压多个 MTK 平台源码。某公司曾因此导致 3 个产品线编译全部失败,回滚耗时 42 小时。
5. 编译产物验证与烧录技巧:如何用fastboot确认systemimage真正可用?
编译成功生成out/target/product/amt6799_evb_n/system.img后,别急着fastboot flash system system.img。MT6799 的system.img是 ext4 格式,但 MTK 的mkuserimg_mtk.sh脚本在 Ubuntu 16.04 上默认生成sparse格式(.img后缀),而fastboot要求ext4格式才能正确识别分区大小。直接烧录 sparse image 会导致system分区被截断,设备启动后反复重启。以下是经过 12 次烧录验证的完整验证链。
5.1 验证system.img格式与完整性
首先确认system.img是否为 ext4(非 sparse):
file out/target/product/amt6799_evb_n/system.img # 正确输出:out/target/product/amt6799_evb_n/system.img: Linux rev 1.0 ext4 filesystem data, UUID=..., volume name "system" (needs journal recovery) (extents) (large files) (huge files) # 错误输出:out/target/product/amt6799_evb_n/system.img: data # 这是 sparse 格式,需转换若为 sparse 格式,用simg2img转换:
# 安装 simg2img(来自 android-tools-fsutils) sudo apt-get install android-tools-fsutils # 转换 simg2img out/target/product/amt6799_evb_n/system.img out/target/product/amt6799_evb_n/system_ext4.img # 验证转换后格式 file out/target/product/amt6799_evb_n/system_ext4.img然后校验system_ext4.img的 ext4 结构:
# 挂载为 loop 设备(只读) sudo mkdir -p /mnt/system_test sudo mount -o loop,ro out/target/product/amt6799_evb_n/system_ext4.img /mnt/system_test # 检查关键文件是否存在且可读 ls -l /mnt/system_test/bin/sh # 应为 -rwxr-xr-x 1 root root ls -l /mnt/system_test/lib/libc.so # 应为 -rwxr-xr-x 1 root root ls -l /mnt/system_test/app/ # 应为 drwxr-xr-x 2 root root # 卸载 sudo umount /mnt/system_test参数说明:
mount -o loop,ro的ro(只读)是关键。若用rw挂载,e2fsck可能修改system.img的 superblock 时间戳,导致fastboot拒绝烧录(认为镜像被篡改)。
5.2fastboot烧录前的设备状态检查
MT6799 EVB 板进入 fastboot 模式后,必须确认 USB 连接稳定且设备被正确识别:
# 查看设备(必须输出 0123456789ABCDEF fastboot) fastboot devices # 检查 bootloader 版本(应为 MTK Preloader v1.2+) fastboot getvar version-bootloader # 检查分区表(确认 system 分区存在且大小合理) fastboot getvar partition-size:system # 正常输出:partition-size:system: 0x00800000 # 即 8MB,若为 0x00000000 说明分区表损坏若fastboot getvar partition-size:system返回UNKNOWN,需先烧录preloader.bin和lk.bin(由 MTK 提供):
fastboot flash preloader preloader_amt6799_evb_n.bin fastboot flash lk lk_amt6799_evb_n.bin fastboot reboot-bootloader5.3 安全烧录指令与回滚机制
烧录system.img时,必须使用fastboot flash system(非fastboot update),并启用--disable-verity和--disable-verification参数,否则 Android Verified Boot 会因签名不匹配拒绝启动:
# 烧录 system 分区(ext4 格式) fastboot flash system out/target/product/amt6799_evb_n/system_ext4.img # 关键:禁用 verity 和 verification(开发阶段必需) fastboot --disable-verity --disable-verification flash system out/target/product/amt6799_evb_n/system_ext4.img # 烧录 boot 分区(确保 kernel 和 ramdisk 匹配) fastboot flash boot out/target/product/amt6799_evb_n/boot.img # 重启 fastboot reboot验证技巧:烧录后首次启动,观察串口日志(115200 8N1)。正常流程为:
Preloader -> LK -> Kernel init -> init: starting service 'servicemanager'。若卡在init: Starting service 'surfaceflinger',说明libhwui.so未正确加载,需回查 4.4 节的out/清理。
从那以后我每次make -j4 systemimage完成,都强制走一遍file + mount + fastboot getvar三连验,哪怕多花 3 分钟。因为 MT6799 的system.img生成过程有 7 个隐式依赖点(build/make/core/Makefile、build/make/core/image.mk、device/amt/amt6799_evb_n/BoardConfig.mk等),任何一个被make clobber漏掉,都会让fastboot烧录一个“看起来成功、实则无法启动”的镜像。希望帮到你。
本文还有配套的精品资源,点击获取