MT6833 内核编译踩坑记:从 defconfig 到能开机

这篇不是教程,是踩坑记录。如果你也想给自己的机器编一个内核,下面这些顺序和报错大概率会原样出现在你屏幕上。

先看清风险

刷内核比刷 ROM 危险得多:ROM 挂了还能进 Recovery 重刷,内核挂了就是无限重启。所以在动手之前,务必做两件事:

  1. 确认 BL 已解锁,并且知道怎么进 fastboot;
  2. 用 fastboot getvar current-slot 确认当前槽位,然后把原厂 boot 分区完整 dump 出来备份。
1
2
3
4
adb reboot bootloader
fastboot getvar current-slot
fastboot getvar partition-size:boot
fastboot dump boot boot_stock.img # 具体命令取决于机型与工具链

备份文件请复制一份到电脑上。放在手机里等于没备份——刷失败之后你根本进不去系统。

环境准备

我用的是 Ubuntu 22.04。编译 aarch64 内核需要交叉编译器,MTK 的机器树通常还依赖 clang 和预编译的 dtbo/img 工具:

1
2
3
4
5
6
7
8
9
sudo apt install -y build-essential bc bison flex libssl-dev \
libelf-dev python3 git zip unzip

sudo apt install -y gcc-aarch64-linux-gnu

# 内核目录里通常自带 prebuilts,没有的话按 README 装
export ARCH=arm64
export SUBARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

比较坑的一点是:很多 MTK 内核树对 clang 版本极敏感,14 和 17 编出来的东西可能一个能开机一个不能。设备树里如果有 prebuilts/clang 目录,就老老实实用它自带的。

拉源码与 defconfig

1
2
3
4
5
git clone --depth=1 -b <分支名> <内核仓库地址> kernel
cd kernel

make O=out ARCH=arm64 <设备代号>_defconfig
make O=out ARCH=arm64 -j$(nproc)

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
2
3
4
5
6
cp out/arch/arm64/boot/Image.gz-dtb AnyKernel3/
cd AnyKernel3
zip -r9 kernel-test.zip * -x '*.git*' 'README.md'

# 推送到手机,用 Recovery 刷入
adb push kernel-test.zip /sdcard/Download/

第一次刷之前,先把备份好的 boot 分区也传进手机里,随时能救回来。

刷完不开机怎么办

别慌,按这个顺序排查:

  • 长按电源键 15 秒强制重启,确认是不是真的卡在开机动画;
  • 能进 fastboot 就刷回备份的 boot,一分钟恢复;
  • 进不了 fastboot,试试 fastbootd 或者 Recovery 里 restore;
  • 全都不行再考虑线刷全量包。

这次我大概编了 9 个版本才开机,前 8 次全是同一个原因:dtbo 没带全,内核起来了但显示驱动拿不到面板参数,于是黑屏。日志在 /proc/last_kmsg 或者 pstore 里,能看到驱动初始化的最后一行卡在哪。

小结

编内核这件事,80% 的时间花在环境和对齐上,写代码的部分反而最少。备份、看日志、一次只改一个变量——这三条比任何技巧都管用。