第二章 开发环境搭建:SDK获取与配置、交叉编译工具链、ADB调试、串口日志分析

好,咱们直接进入正题。做MTK平台的车机调优,第一步就是把开发环境搭稳了。我见过太多人,代码写得挺溜,结果环境没配好,一编译就报错,一调试就黑屏。说白了,环境搭建是地基,地基不稳,后面全是白忙活。

2.1 SDK获取与配置

MTK的SDK不像开源项目那样随便下载。你需要先和MTK签NDA,拿到授权。我个人习惯是,拿到SDK压缩包后,第一件事不是解压,而是先校验MD5。为什么?因为SDK动辄几十个GB,网络传输中容易出错。我曾经有一次,解压到一半报CRC错误,结果发现是下载时丢包了,白白浪费了半天。

解压后,你会看到一个类似这样的目录结构:

mt8678_android_sdk/
├── kernel-5.10/
├── device/mediatek/
├── vendor/mediatek/
├── hardware/
├── out/
└── build/

嗯,这里要注意:千万不要在Windows上解压。MTK的SDK里有很多符号链接,Windows的NTFS文件系统对符号链接支持很差。我建议直接在Ubuntu 20.04或22.04 LTS上操作。

核心配置步骤:

  1. 安装依赖包:sudo apt install 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 fontconfig
  2. 设置Python版本:MTK 8678要求Python 3.8+,我习惯用update-alternatives管理多版本
  3. 初始化编译环境:source build/envsetup.sh
  4. 选择目标:lunch,然后选对应的车机产品型号

我的小技巧:每次拉取新SDK后,我会先跑一次make clean,再执行make -j$(nproc) 2>&1 | tee build.log。把日志存下来,万一编译失败,方便回溯。

2.2 交叉编译工具链

交叉编译,说白了就是你在x86的电脑上,编译出能在ARM架构的车机芯片上跑的程序。MTK 8678用的是ARMv8.2-A架构,64位。

MTK SDK里自带了一套预编译的工具链,路径一般在:

prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/

但我个人更推荐用Clang。为什么?因为MTK从Android 12开始,官方推荐用Clang编译内核和用户空间程序。Clang的错误信息比GCC友好得多,而且编译速度更快。

设置交叉编译环境,我一般这样写:

export PATH=$PATH:你的SDK路径/prebuilts/clang/host/linux-x86/clang-r450784d/bin
export CROSS_COMPILE=aarch64-linux-gnu-
export CC=clang
export ARCH=arm64

你想想看,如果这些环境变量没设对,编译出来的程序要么跑不起来,要么跑起来就段错误。我曾经在调试一个音频DSP驱动时,就是因为用了错误的工具链版本,导致浮点运算结果全错,查了整整两天。

避坑指南:千万不要用系统自带的gcc去编译车机程序。系统gcc是给x86用的,编译出来的ARM程序根本跑不了。我曾经见过一个同事,编译了一个hello world,放到车机上执行,直接报"Exec format error"。嗯,就是工具链没选对。

2.3 ADB调试

ADB是Android Debug Bridge的缩写。做车机开发,ADB就是你的瑞士军刀。MTK 8678的车机,一般通过USB或者网络连接ADB。

USB连接时,要注意:车机的USB口可能被配置为仅充电模式。你需要先在车机的开发者选项中,开启USB调试。如果车机屏幕不可用(比如系统还没起来),那就得用串口去改配置了。

网络ADB是我最常用的方式:

# 在车机上(通过串口或已有ADB)
adb tcpip 5555

# 在电脑上
adb connect 192.168.1.100:5555

为什么我偏爱网络ADB?因为车机装在中控台里,USB线插拔很不方便。而且网络ADB的传输速度,对于传输日志和小的调试文件来说,完全够用。

常用的ADB调试命令,我列几个:

命令 用途 我的经验
adb logcat -b all 抓取所有缓冲区日志 车机死机时,这个命令能帮你找到最后一条日志
adb shell dumpsys 查看系统服务状态 调优性能时,我经常看dumpsys cpuinfo
adb shell cat /proc/meminfo 查看内存使用 内存泄漏排查必备
adb shell top -n 1 -b 查看进程CPU占用 哪个进程在偷吃CPU,一目了然

提示:如果ADB连接不稳定,试试adb kill-server然后adb start-server。我遇到过好几次,ADB服务卡死了,重启一下就好。

2.4 串口日志分析

串口,是车机开发的最后一道防线。当系统还没起来、ADB连不上、屏幕黑着的时候,串口是你唯一的眼睛。

MTK 8678的串口,一般是UART0,波特率921600。连接方式很简单:用USB转TTL模块,接上TX、RX和GND。注意,千万不要接VCC,车机的串口电平是1.8V或3.3V,接错会烧芯片。我曾经就烧过一个开发板,血的教训。

在电脑上,我用的是screen命令:

sudo screen /dev/ttyUSB0 921600

如果觉得screen不好用,也可以用minicom或者putty。我个人习惯用screen,因为它轻量,而且可以配合Ctrl+A, :hardcopy保存日志。

串口日志怎么看?我总结了一个套路:

  1. 看启动流程:从BootROM到Preloader,再到LK,最后到Linux内核。每一步都有标志性打印。如果卡在某一步,就说明那一步有问题。
  2. 看错误关键字:比如panicOopskernel BUGsegfault。这些是系统崩溃的信号。
  3. 看时间戳:MTK的串口日志默认带时间戳。如果两个时间戳之间间隔过长,说明系统在那个时刻卡住了。

实战案例:有一次,车机在启动时反复重启。串口日志显示,在Preloader阶段打印了"DRAM init failed"。我一看就知道,是内存初始化失败了。检查硬件,发现DDR供电电压不对。嗯,这就是串口日志的价值——直接定位到硬件问题。

最后,说一个我常用的技巧:把串口日志重定向到文件,然后用grep过滤。比如:

sudo screen -L -Logfile boot.log /dev/ttyUSB0 921600
# 启动车机,等它跑完
# 然后分析日志
grep -i "error\|fail\|panic" boot.log

这样,你就不用盯着屏幕一行一行看了。效率高很多。

好了,环境搭建这部分就讲到这里。下一章,我们会深入MTK 8678的硬件架构,看看它的CPU、GPU和DSP是怎么协同工作的。到时候,你会对性能调优有更深的理解。