MT6833 内核编译踩坑记:从 defconfig 到能开机
MT6833 内核编译踩坑记:从 defconfig 到能开机
CoolJuvenlie这篇不是教程,是踩坑记录。如果你也想给自己的机器编一个内核,下面这些顺序和报错大概率会原样出现在你屏幕上。
先看清风险
刷内核比刷 ROM 危险得多:ROM 挂了还能进 Recovery 重刷,内核挂了就是无限重启。所以在动手之前,务必做两件事:
- 确认 BL 已解锁,并且知道怎么进 fastboot;
- 用
fastboot getvar current-slot确认当前槽位,然后把原厂 boot 分区完整 dump 出来备份。
1 | adb reboot bootloader |
备份文件请复制一份到电脑上。放在手机里等于没备份——刷失败之后你根本进不去系统。
环境准备
我用的是 Ubuntu 22.04。编译 aarch64 内核需要交叉编译器,MTK 的机器树通常还依赖 clang 和预编译的 dtbo/img 工具:
1 | sudo apt install -y build-essential bc bison flex libssl-dev \ |
比较坑的一点是:很多 MTK 内核树对 clang 版本极敏感,14 和 17 编出来的东西可能一个能开机一个不能。设备树里如果有 prebuilts/clang 目录,就老老实实用它自带的。
拉源码与 defconfig
1 | git clone --depth=1 -b <分支名> <内核仓库地址> kernel |
defconfig 的名字一定要和机型对上。同芯片平台的不同机型,defconfig 可能有好几份,选错的表现是「能编过,但屏幕不亮 / 触摸没反应」。
编译最常卡住的三个地方
1. 编译器版本不匹配
典型报错是 invalid instruction 或者某条内联汇编直接过不去。这不是代码写错了,是编译器太新。降级到内核树声明的版本,问题通常立刻消失。
2. 缺少 prebuilt 的 dtbo
MTK 的 dts 会引用一批二进制 dtbo,体积小、不影响 git 历史,很多 fork 就直接没带上。报错长这样:No rule to make target 'xxx.dtbo'。去原厂或者同机型的完整仓库里把 prebuilts 目录补回来即可。
3. 打包工具找不到
内核编完了不代表能刷,还要 mkbootimg / dtbtool。这些工具通常在内核树的 tools/ 下,如果 PATH 里没有,打包会静默失败——得到一个 0 字节的 boot.img,刷进去就是变砖。
打包 boot.img
我用的方式是 AnyKernel3:不自己拼 boot 镜像,而是把内核塞进一个 zip 里,由 Recovery 在设备上完成解包和替换。这样 slate/槽位、header 版本这些细节都由脚本处理,出错概率低很多。
1 | cp out/arch/arm64/boot/Image.gz-dtb AnyKernel3/ |
第一次刷之前,先把备份好的 boot 分区也传进手机里,随时能救回来。
刷完不开机怎么办
别慌,按这个顺序排查:
- 长按电源键 15 秒强制重启,确认是不是真的卡在开机动画;
- 能进 fastboot 就刷回备份的 boot,一分钟恢复;
- 进不了 fastboot,试试 fastbootd 或者 Recovery 里 restore;
- 全都不行再考虑线刷全量包。
这次我大概编了 9 个版本才开机,前 8 次全是同一个原因:dtbo 没带全,内核起来了但显示驱动拿不到面板参数,于是黑屏。日志在 /proc/last_kmsg 或者 pstore 里,能看到驱动初始化的最后一行卡在哪。
小结
编内核这件事,80% 的时间花在环境和对齐上,写代码的部分反而最少。备份、看日志、一次只改一个变量——这三条比任何技巧都管用。
