MTK开发源码包全解析:从目录结构到编译调试实战
简介面向MediaTek芯片平台开发者的MTK开发源码包用于在MTK硬件上构建、调试和优化应用程序及系统级软件。压缩包共857个文件大小仅2.7MB主要包含Perl脚本pl/pm、Shell脚本sh、C头文件与源码h/c以及若干文档和配置文件另有AP638目录可能对应特定芯片型号涵盖驱动、固件、库文件、示例代码和构建脚本等关键内容。需要说明的是包内未集成MinGW与MSYS编译环境用户需自行准备以完成GCC编译和Makefile管理。借助这批源码开发者可以深入理解MTK平台的底层驱动与硬件交互逻辑参考示例代码快速完成环境配置、编译烧录与定制化开发目录结构清晰适合嵌入式工程师、系统移植人员以及希望掌握MTK方案原理的学习者。目前该资源已有731人学习下载。 做了这么多年MTK平台开发我越来越觉得“源码包”这三个字的分量往往是被很多人低估的。尤其是刚接手MTK项目或者从其他平台转过来的朋友拿到一个几十GB的MTK开发源码包光看目录结构就能看懵半天更别说里面那些vendor、kernel、preloader、TEE之间的耦合关系了。这篇文章就以“MTK开发源码包 source”为主线结合我自己在MT6765、MT7986等平台上踩过的坑把一个典型的MTK源码包从拿到手、搭环境、读代码、改驱动、追内存泄漏、看dump到最终出包的完整闭环捋一遍。内容偏工程实操适合正在做Android手机/平板、IoT设备、车载方案的底层开发、驱动开发、系统工程师参考也欢迎做上层应用但想了解源码结构的同学围观。1. MTK源码包到底装了什么1.1 先搞清楚一个大框架MTK的源码包通常不是单纯的Linux kernel也不是纯AOSP。它是一整套从bootrom到Android应用层都能编译链接的工程树。拿手机平台举例典型结构长这样android/ ├── kernel-4.19/ # MTK kernel含大量mediatek目录 ├── vendor/mediatek/proprietary/ # 闭源/半开源驱动与hal ├── device/mediatek/ # 平台device配置、sepolicy、init.rc ├── bootable/bootloader/ # lk、preloader相关 ├── out/ # 编译输出通常很大 ├── build/envsetup.sh # 每个开发者的老朋友老手拿到包第一件事不是编译而是先看vendor/mediatek/proprietary里到底放了哪些模块。这个目录是MTK开发的“灵魂”里面包含了camera hal、sensor hub、power、connectivity等几乎所有核心外设的适配层代码。你在设备树里看到的某个i2c设备节点最终能不能工作往往取决于这个hal层有没有对应的实例加载。另外别忽略preloader和lk。preloader是上电后的第一段代码负责初始化DDR和启动lk坏了机器直接变砖且不好救。lk是bootloader负责拉起kernel。很多底层问题比如ddr频率配置、充电开机、fastboot异常都跟这两段代码有关。1.2 源码包的三种常见形态实际工作中我见过的MTK源码包基本分三种。第一种是全量发布包一般由芯片代理商或方案公司IDH提供里面同时包含Android、Kernel、Bootloader、preloader、modem的完整代码和预编译镜像。这是开发的主力起点。第二种是增量工程包只包含某个版本的改动或针对某个项目的定制代码通常在已有全量包的基础上打patch。老项目升级、多项目维护时很常见。第三种是纯BSP包只提供内核和少量设备驱动配合客户自己的系统框架使用。比如做Linux网关、路由器这类产品时很多团队根本不跑Android要的就是这份精简BSP。判断一个包能不能用我习惯先翻vendor/mediatek/proprietary/README以及build/target/product/下的mk文件。如果mk文件里引用的模块在vendor下找不到对应目录这个包十有八九是被裁剪过的后面编译时会随机报错。1.3 版本识别不能只靠文件名MTK的版本管理喜欢用“ALPS”和“SW.VERSION”来表示。比如文件名里带ALPS0651、ALPS0520对应的就是某个release tag。注意这只是软件版本号不直接等于Android版本。我见过有人拿Android 12的包刷了Android 11的preloader结果一开机就panic。所以在动代码之前最好先确认三件事Android版本对应framework和vendor接口Kernel版本是4.14还是4.19还是5.xModem版本关系到打电话、数据业务这三个版本一旦对不上后面哪怕只是一行dts改动也可能引发连锁故障。2. 搭环境别在第一步就劝退自己2.1 硬件配置别拿8G内存开玩笑编译MTK全源码不是闹着玩。我自己的主力机是32G内存、8核CPU、1T NVMe SSD编译Android完整镜像稳定需要40到60分钟。如果你的机器是16G内存且没有SSD建议先别编译整包只编kernel或单个模块会现实很多。另外out目录预留100GB空间只是底线我一般留200GB才安心。经常有同事问能不能用Windows编译。MTK官方一般只支持Ubuntu不建议在Windows上绕路。原因不复杂MTK的工具链、符号链接、shell脚本大多依赖Linux环境即使强行用WSL也会因为inotify和文件系统权限问题遇到一堆幺蛾子。老老实实装个Ubuntu后面省心。2.2 Ubuntu选desktop还是server不少朋友纠结这个。我的建议很直接如果这台机器只跑编译选Ubuntu Server省内存省图形资源SSH远程操作方便。如果还要用来读代码、看文档、日常办公选Ubuntu Desktop因为Source Insight、VSCode、烧录工具这些图形程序装起来更方便。版本上注意MTK老代码Android 9/10那一代对Ubuntu 20.04支持最好新平台Android 13/14用22.04问题也不大。至于24.04除非你确定工具链齐全否则不建议当主力。网上大家都在问“ubuntu24 desktop和server哪个版本适合AI开发”那个场景另说MTK编译这里我更保守。2.3 编译前必须跑通的三个命令假设你把源码包解压到了~/mtk_project。cd ~/mtk_project source build/envsetup.sh lunchlunch会列出所有可选的工程配置比如full_xxx-userdebug。选userdebug而不是user原因很简单userdebug自带root权限后续抓log、改属性都方便。等你真正要做量产包的时候再单独编user版本。选完配置后直接执行make -j16第一次编译要耐心等。如果中途报错先看是不是缺少依赖库。常见缺的库有libssl-dev、libncurses5-dev、flex、bison等。我的习惯是先把这些开发包一次性装齐避免反复中断sudo apt install -y git-core gnupg flex bison build-essential zip curl zlib1g-dev gcc-multilib g-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig2.4 编译提速的实用技巧MTK源码包支持编译加速。我的做法是启用ccacheexport USE_CCACHE1 export CCACHE_COMPRESS1 ccache -M 50G这几行可以写进~/.bashrc里以后每次source环境自动生效。配置好ccache之后第二次编译的速度能快30%以上改动频繁的模块能快更多。另外注意编译时不要用sudo。MTK的构建脚本对当前用户和目录权限有要求一旦用sudo生成了一些root权限的文件后面普通用户再编译会莫名其妙出现Permission denied。3. 典型开发场景从改一行dts到真正跑起来3.1 把一颗新sensor点亮MTK平台调试摄像头比如你在项目里拿到一颗GC5025第一步不是写驱动而是确认sensor硬件使用的i2c总线、电源和reset引脚。然后在kernel-4.19/arch/arm64/boot/dts/对应的dtsi中增加或修改节点。GC5025这类传感器驱动MTK通常放进vendor/mediatek/proprietary/custom/xxx/kernel/imgsensor/目录下。添加新sensor的步骤比较固定在imgsensor目录下新建gc5025_mipi_raw文件夹把驱动源文件放进去。修改该目录下的cfg_setting和对应的project配置文件把sensor id和访问地址写对。修改kd_imgsensor_list.c注册新的sensor。检查dts中的i2c地址与实际硬件保持一致。这一串流程最容易出错的就是“地址对不上”和“sensor id读错”。如果i2c地址错了驱动probe阶段直接失败如果sensor id错了枚举sensor时会被跳过。排错时最直接的方式是抓i2c读写log确认能否读到sensor的chip id。3.2 手势双击唤醒的原理与改法热词里有个“MTK 手势双击唤醒”这其实不只是framework层的活底层链路比较长。双击唤醒的本质是TP在睡眠状态下仍然保持低功耗扫描检测到双击手势后给AP发一个中断把系统从suspend状态唤醒。在MTK平台上你需要检查三层kernel层TP驱动是否实现了gesture模式。一般双击唤醒的key code是KEY_GESTURE_DOUBLE_TAP在驱动的suspend/resume回调里设置手势开关。framework层Settings里的“双击唤醒”开关会通过InputManager下行到底层最终写入TP寄存器。lk/内核唤醒源某些平台需要配置EINT唤醒源否则即使TP发出了中断系统也醒不过来。我踩过最深的坑是TP驱动上报了事件但系统没有启用wakeup source结果整机睡死。排查方法很简单在中断回调里加打印看suspend后有没有中断进来。如果中断进来了仍不醒就查kernel/msmMTK对应平台目录里的wakeup_ctrl配置。3.3 WiFi MAC地址丢失“联发科mtk wifimac地址丢失”这个问题在量产出货时经常遇到直接表现是设备重启或恢复出厂设置后WiFi MAC变成00:00:00:00:00:00无法正常连接路由。MTK的WiFi MAC通常存在nvram分区或者factory分区里。恢复出厂设置会擦掉用户数据分区但factory属于“出厂保留区”不应该被擦。如果MAC丢失基本是两种情况factory/custom_mac分区本身损坏或flash上根本没烧录有效MAC。软件读取逻辑错误读到了无效的efuse值。处理时先看nvram目录里的cfg文件。MTK的WiFi驱动一般在/vendor/firmware/或/vendor/nvram下有一份默认配置文件正常使用时会加载。如果发现读取位置有误需要检查驱动或hal层的nvram加载路径。注意MAC这类参数软件上可以临时改但量产一定要走工厂校准不能靠代码里写死。写死会导致同一个镜像出去的所有设备MAC冲突连路由器都串线。3.4 只编一个模块的偷懒大法全量编译慢但日常开发基本不需要每次都编整包。我常用的几个编译目标# 只编kernel make bootimage # 只编kernel并生成boot.img make kernel # 编某个具体模块并push进镜像 make vendor.mediatek.proprietary.hardware.camera -j16这里的模块名怎么确定去对应的目录下看Android.bp或Android.mk里面有LOCAL_MODULE或name字段。拿这个名字直接makeMTK的构建系统会自动处理依赖。有一点要提醒改了kernel dts或驱动后只编kernel是不够的还得生成新的bootimage并烧进去单独编ko文件有时不会自动打包。所以我的习惯是make bootimage一条命令走天下。4. 读MTK源码Source Insight 4.0确实能续命4.1 为什么还在用Source Insight现在VSCode、CLion很流行但做MTK这种体量的代码阅读Source Insight依然有自己的生态位。原因主要有三个全局符号索引速度快几十G的代码库也能扛住。查找函数调用关系极其顺手看camera pipeline、power状态机这类逻辑时效率极高。对老工程师来说肌肉记忆很难改。网上搜“source insight 4.0使用教程”“source insight4.0中文安装破解”的朋友不少我建议有能力就入正版本身价格不贵而且省去破解的折腾。4.2 导入MTK源码包的正确姿势新建工程时Project Name写项目名源码路径指向源码根目录。关键点在第三步选择文件时别傻乎乎把out目录和中间产物都加进去。我的过滤规则是勾选Exclude填out;.git;*.o;*.cmd这样同步时间能少一半。MTK源码里有很多软链接Source Insight默认会尝试展开。在Options - Preferences - Files里可以关闭“Follow symbolic links”否则会出现大量重复文件索引极慢。另一个常见痛点是大量代码文件编码不统一。MTK的代码有UTF-8也有GBK老项目尤其明显。Source Insight 4.0在Document Options里可以设置默认编码为UTF-8遇到GBK文件手动切View-Encoding即可。如果不管编码直接看注释里中文全是乱码很容易误导理解。4.3 同步慢、卡顿、崩溃的排查思路热词里有句很吓人的报错“LowLevelFatalError [File:D:\buildUE5\Sync\Engine\Source\Runtime\Core\Private...]”这虽然更像是UE5引擎崩溃但Source Insight用久了也会出现类似现象。遇到SI打开大文件或同步时崩溃我一般先做两件事删除工程目录下的.si_working目录让SI重新建立全量索引。升级到4.0最新patch版本老版本对大文件兼容性确实差。如果还崩考虑是不是杀毒软件实时扫描在拦截SI的文件锁。把源码目录加入白名单通常能解决。4.4 什么时候回归VSCodeSI强在跳转但不适合写代码。我的组合拳是SI看源码、VSCode写代码。VSCode装好C/C插件后配合compile_commands.json在MTK工程里也能有不错的补全和跳转体验特别是改kernel驱动时VSCode的Git集成和格式化功能比SI好太多。不过VSCode对超大工程的索引内存消耗很夸张如果机器只有16G内存开两个VSCode窗口基本就开始卡了。这种情况下还是优先用SI。5. 内存泄漏和dump解析是MTK开发的分水岭5.1 MTK平台内存泄漏排查套路MTK设备上的内存泄漏往往表现为内存持续增长、系统慢慢变卡、最后lowmemorykiller杀后台。排查思路和Android原生类似但MTK有自己的绕法。第一步看/proc/meminfoadb shell cat /proc/meminfo重点关注MemFree、MemAvailable、Slab、CmaTotal这几个值。如果Slab持续上涨一般是内核对象泄漏比如kmalloc没释放。第二步开kmemleakecho scan /sys/kernel/debug/kmemleak cat /sys/kernel/debug/kmemleakMTK的内核默认开了kmemleak的可能性不大需要在kernel config里开启CONFIG_DEBUG_KMEMLEAK。不过开启后性能有损耗线上机器不能随便开只能Debug版本用。第三步看ION/DMA buffer。MTK的camera、GPU、VPU大量使用连续物理内存。如果某个进程在不停申请ION buffer又不释放很可能是native层的graphics相关模块泄漏。此时用adb shell dumpsys meminfo看各进程的PSS再配合malloc debug或者AddressSanitizer定位就基本有方向了。5.2 解析dump文件的实操流程设备死机后MTK平台会在内部存储或SD卡上生成db文件dump.bin、db.bin一个完整的mtk ram dump几GB都正常。解析dump的经典姿势是先拿到符号表# 在源码根目录下 source build/envsetup.sh lunch your_project adb pull /sdcard/dump.bin # 用vendor/mediatek/proprietary/scripts里的解析脚本 python3 vendor/mediatek/proprietary/scripts/parse_dump.py -i dump.bin -o out_dump解析完主要看这几个文件sysrq.txt内核日志尾部能看到panic现场。threads/core_xxx.log各CPU核的backtrace。memory.txt内存布局。我一般先看sysrq里的异常调用栈再看ps信息和/proc/*/stack。如果是kernel panic调用栈里直接能看到出问题的函数如果是用户态crash需要配合coredump和符号化脚本进一步定位。5.3 一个典型的死机现场有次排查一个DDR不稳定引起的系统重启解析dump后发现每次panic位置都一样都在某个memcpy里。但memcpy本身没问题问题在源地址对应的内存被释放了。顺着backtrace往前查发现是某个外设驱动在中断上下文里使用了vmalloc分配的不连续内存物理地址在DDR训练失败后失效一访问就触发异常。这类问题不看dump根本找不出来。所以我对团队的硬性要求是遇到重启问题先抓dump再说话别靠猜。6. 常见问题与避坑速查现象可能原因解决思路编译报错“No rule to make target”源码包被裁剪或路径不对检查mk文件引用的模块是否存在kernel编译后设备无显示lk/preloader版本与kernel不匹配确认lk和bootimage一起更新WiFi MAC全部为00:00:00:00nvram/factory分区异常重新烧写出厂分区检查驱动读取路径TP双击唤醒无效内核没配置wakeup sourceEINT唤醒源和suspend回调排查SI同步卡死out目录和软链接未过滤排除out关闭软链接跟踪内存持续上涨内核对象或ION泄漏kmemleak dumpsys meminfo定位设备反复重启DDR/电源不稳定或驱动非法访问抓dump看panic现场ubuntu下编译报Python版本错误老代码依赖Python2装python2或使用软链接兼容表格里的每一条我都实打实踩过或看过同事踩过。尤其是“lk和kernel版本不匹配导致黑屏”很多新手把时间花在显示屏驱动上实际上是最上层的bootloader就已经起不来。7. 最后分享一点个人习惯做了这么多MTK项目我个人的习惯是拿到源码包之后先花半天时间把dts、init.rc、mk文件过一遍搞清楚这个包的基本骨架再动手改代码。很多人上来就编译、就跑demo结果环境没搭好、目录结构没搞明白后期问题全爆发出来。还有个小技巧源码包解压后第一时间做一次checksum记录或者用git初始化一个本地仓库。这样一旦改坏了随时能对照原版。MTK的工程脚本有时会直接改动源码目录里的out产物污染源文件有版本管理兜底会安全很多。如果你刚开始接触MTK开发不要被几十个G的源码包吓到。先学会看目录再学会编译单个模块最后熟悉dts和log抓取。这个链路走通之后MTK平台开发基本就入门了。剩下的细节就是在一个个具体问题里磨出来的经验。本文还有配套的精品资源点击获取
