2、开发环境搭建:Ubuntu环境配置、交叉编译工具链安装、源码下载与编译、ADB与Fastboot调试

说实话,做MTK座舱HAL开发,环境搭建这一步要是没弄好,后面全是坑。我见过太多同事,代码写得挺溜,结果编译环境配了三天还没跑通。今天我就把我在8676项目上积累的经验,一步步拆给你看。

2.1 Ubuntu环境配置——别小看这一步

我个人习惯用Ubuntu 20.04 LTS。为什么?因为MTK官方对20.04的支持最成熟,18.04有些包太老,22.04又太新,容易踩坑。

核心依赖包安装:

sudo apt-get update
sudo apt-get install -y git-core gnupg flex bison build-essential \
  zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 \
  libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev \
  lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip \
  python3 python3-pip python3-venv

嗯,这里要注意——千万别漏了libncurses5。我在项目中遇到过,有同事装完所有包,编译到一半报错,查了半天发现是ncurses库版本不对。说白了,MTK的编译脚本对32位库依赖很重,64位系统上必须手动装这些兼容包。

我的小技巧:装完依赖后,跑一下 dpkg --list | grep lib32 确认所有32位库都到位了。别偷懒,这一步能省你后面两小时。

2.2 交叉编译工具链安装——MTK的"独门武器"

MTK 8676用的是ARM Cortex-A系列内核,所以我们需要ARM交叉编译工具链。但注意,MTK官方推荐的是他们自己定制的工具链,不是开源的gcc-arm-none-eabi。

为什么会这样?因为座舱芯片要处理音视频、图形、通信等多任务,MTK在工具链里做了很多针对性的优化。你想想看,用通用工具链编译出来的HAL层代码,性能可能差30%以上。

安装步骤:

  1. 从MTK官方获取工具链压缩包(通常是 mtk_toolchain_xxx.tar.bz2
  2. 解压到 /opt/mtk_toolchain 目录
  3. 配置环境变量
# 解压
sudo tar -xjf mtk_toolchain_8676.tar.bz2 -C /opt/

# 配置环境变量(建议写到 ~/.bashrc 里)
export PATH=/opt/mtk_toolchain/bin:$PATH
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm

避坑指南:我曾经因为环境变量没写对,编译出来的so库在板子上跑起来就段错误。检查方法很简单——跑一下 arm-linux-gnueabihf-gcc --version,确认版本号和MTK文档一致。另外,CROSS_COMPILE 变量名不能写错,MTK的Makefile就认这个。

2.3 源码下载与编译——从零到第一个镜像

MTK 8676的源码分两部分:BSP层源码HAL层源码。BSP层是MTK闭源的,通过他们的Git仓库分发;HAL层是我们自己开发的,放在公司的GitLab上。

下载流程:

# 1. 下载BSP源码(需要MTK授权账号)
git clone git://mediatek.com/mtk8676_bsp.git -b mtk8676_android12

# 2. 下载HAL层源码
git clone git@gitlab.company.com:hal/mtk8676_hal.git

# 3. 初始化编译环境
source build/envsetup.sh
lunch mtk8676-userdebug

这里我多说一句——lunchuserdebug 还是 eng?我个人习惯用 userdebug。为什么?因为 eng 版本会打开很多调试日志,影响性能;而 userdebug 既有root权限,又接近release版本,调试起来最顺手。

编译命令:

# 全编译(第一次编译必须全编)
make -j$(nproc) 2>&1 | tee build.log

# 单独编译HAL模块(后续开发用这个)
mmm packages/services/Car/audio/  # 以音频HAL为例

编译时间参考:

编译类型 机器配置 预估时间
全编译 32核/64GB内存 40-60分钟
全编译 16核/32GB内存 90-120分钟
单模块编译 任意 2-5分钟

我记得第一次全编译时,等了快一个小时,结果最后报了个链接错误。查了半天,是某个头文件路径写错了。所以我的建议是——第一次编译前,先检查所有依赖的头文件路径,别傻等。

2.4 ADB与Fastboot调试——板子上的"眼睛"

环境搭好了,镜像也编出来了,怎么烧到板子上?怎么调试?这就靠ADB和Fastboot了。

Fastboot烧录:

# 进入Fastboot模式(板子上电时按住音量减键)
fastboot devices  # 确认设备连接

# 烧录镜像
fastboot flash boot out/target/product/mtk8676/boot.img
fastboot flash system out/target/product/mtk8676/system.img
fastboot flash vendor out/target/product/mtk8676/vendor.img

# 重启
fastboot reboot

注意:千万别在烧录过程中断电!我曾经有一次烧到一半USB线松了,板子直接变砖。后来用串口线才救回来。所以,烧录前检查USB线是否牢固,最好用带锁扣的线

ADB调试:

板子启动后,用ADB连接:

adb devices  # 查看设备列表
adb root     # 获取root权限
adb remount  # 重新挂载分区为可读写

# 推送HAL库到板子
adb push out/target/product/mtk8676/vendor/lib/hw/audio.primary.mtk8676.so /vendor/lib/hw/

# 查看日志
adb logcat -s AudioFlinger  # 只看音频相关的日志

嗯,这里有个坑——adb remount 有时候会失败,提示 remount of the / superblock failed。别慌,这是因为system分区是只读的。解决办法是:

adb disable-verity  # 关闭dm-verity校验
adb reboot
adb root
adb remount  # 这次就能成功了

我的调试习惯:我会开三个终端窗口——一个跑 logcat,一个跑 shell 交互,一个用来推送文件。这样调试效率最高。另外,logcat -b all 可以看所有buffer的日志,排查问题时很有用。

2.5 环境验证——确认一切就绪

最后,跑一个简单的HAL测试程序,验证整个环境是否正常:

# 在板子上执行
adb shell
cd /vendor/bin/hw/
./android.hardware.audio@2.0-service  # 启动音频HAL服务

# 如果看到 "Service started successfully" 说明环境OK

如果报错,多半是库文件没推完整,或者权限不对。检查一下 /vendor/lib/hw/ 目录下有没有对应的 .so 文件,以及 chmod 755 有没有设置。

好了,环境搭建就到这里。说白了,这一步就是"磨刀不误砍柴工"。把环境配稳了,后面写HAL代码才能顺风顺水。下一章我们开始真正写HAL层的代码,到时候你会感谢今天认真配环境的自己。