Android 内核编译踩坑记录

最后更新于 23/9/18

Action 编译

Android-Kernel-Builder
这个项目已经配置好了 actions,可以直接拿来编译

官方问题

官方的内核源码好像不能通过编译,可能和这个项目使用的编译器有关。这个项目用的是叫 proton clang 的没听说的编译器
经过尝试,会出现两个错误

  1. redefinition of yyloc
  2. error "Unsupported NR_CPUS for lb tracepoint."
    第一个可以通过添加 export 来解决
    第二个是因为没有配置好 defconfig
    这个文件在 arch/ 你的架构 /configs 下面
    一般小米都是 型号_user_defconfig 这样

但是还是编译不了
ld.lld: error: target emulation unknown: -m or at least one .o file required
这我还真不知道怎么解决,网上也没有给出解决办法

尝试第三方内核

https://github.com/LineageOS/android_kernel_xiaomi_msm8998
使用了 lineage 的内核
builder 使用了 git 来 clone source
然后需要输入 brand,可以通过 build.prop 来查看
填好之后还需要修改 AnyKernel

AnyKernel

这个项目的 AnyKernel 需要修改
简单来说,kernel 在 boot 里,如果想在 recovery 模式下刷入 boot,而不是 fastboot 刷入 boot 分区,需要创建一个刷机包。这个工具就是用来创建这样一个刷机包的
经过尝试,需要修改 anykernel.sh 里的 boot 后面的参数为 auto
不然会找不到 boot 分区

run

然后在 actions 里面 run Build kernels 就可以了
这个尝试了一下大概要编译四十分钟
之后就会在 release 里面看到 build 好的刷机包了

疑问

照理来说内核和系统不一定要完全匹配,但是我刷入之后卡开机
我也不知道为什么,现在手机 miui12

8/31 更新

GKI

还是准备上 GKI
对于比较新的手机,推荐使用 GKi。也就是说,对于支持 GKI 的内核,只要 KMI 相同就可以刷入内核。那么我们不需要编译小米的内核,只需要取编译 Google 提供的 AOSP 内核就可以了,而编译这个内核会非常简单,一般全部使用推荐工具再执行 build.sh 就可以了

KMI

KMI 全称 Kernel Module Interface,相同 KMI 的内核版本是兼容的 这也是 GKI 中“通用”的含义所在;反之,如果 KMI 不同,那么这些内核之间无法互相兼容,刷入与你设备 KMI 不同的内核镜像可能会导致死机。

具体来说,对 GKI 的设备,其内核版本格式应该如下:

KernelRelease :=
Version.PatchLevel.SubLevel-AndroidRelease-KmiGeneration-suffix
w      .x         .y       -zzz           -k            -something

其中,w.x-zzz-k 为 KMI 版本。例如,一个设备内核版本为 5.10.101-android12-9-g30979850fc20,那么它的 KMI 为 5.10-android12-9;理论上刷入其他

所以,只要找对 kmi 然后编译就可以了

引入 KSU

虽然我编译内核的目的不只是 KSU, 但是 KSU 有的话还是很方便的

然后这个就不需要使用上面那个 Builder 了,我找到了个更好的 Action,也就是 KSU 的官方 action
https://github.com/tiann/KernelSU
然后找到.github 目录,这其中 workflows 中使用了 build-kernel-axx.yml 这样的 action
我使用的 Pixel 刷入了 a13,然后可以发现使用了 repo 工具下载了 Android 内核源码,具体位于 gki-kernel.yml 内
也就是我们如果想要修改,可以先自己使用 repo 下载源码,修改后上传 git,然后再 git clone 下来,去掉原来使用 repo 的命令就可以编译自己的内核啦

实测成功
Android 内核编译踩坑记录
这样就获得了一个 AnyKernel 的刷机包,然后 rec 刷入即可

编译 Pixel 内核

我用的是 pixel 6p ,android13 内核版本 5.10,适配 Project Tremble

pixel 设备拥有 google 为其准备的 build/build.sh
但是对于 Pixel 6+ 的设备,Google 进一步简化了他们的 build 流程,并提供了 build_slider.sh

BUILD_KERNEL=1 build_slider.sh

但是仅仅使用这个脚本编译出的内核并不能运行

dtb 与 ramdisk,GKI

在解决这个问题之前首先要了解一下这个概念
有的人可能会听过 GKI 概念,但是 GKI 实际上是分离出了部分驱动,不需要在构建内核的时候包含他
https://zhuanlan.zhihu.com/p/523839332

但是 dtb 和 ramdisk 仍然是需要的

https://source.android.com/docs/core/architecture/bootloader/partitions/vendor-boot-partitions?hl=zh-cn

ramdisk 则是设备启动前必须要的,而且需要保证一致性,也就是说一旦与 Android 一起构建就不能修改,否则 Android 系统的 selinux 机制会拒绝启动
具体可以看这个 https://www.bilibili.com/read/cv19927488/
但是 Google 为 Pixel7,这样的一个出厂即为 Android13 系统的手机设定了 init_boot 分区,设定了 ramdisk 的储存,保证刷入 boot 时 ramdisk 不变
但是对于之前的手机,由于上面提到的 selinux 保护,我们需要 ramdisk

这个获得方法就是解包原装 boot。而 Google 为我们提供了这样一个脚本

$KERNEL_REPO_ROOT/tools/mkbootimg/unpack_bootimg.py
先提取 vendor_boot, 然后用上面的东西解包
至于要如何提取呢,可以使用用户空间的 fastbootd(注意不是 fastboot!https://source.android.com/docs/core/architecture/bootloader/fastbootd
如果不支持 fetch,那就只能使用 payload dumper go 了
https://developers.google.com/android/images#raven
从这里下载进行 dump(不过这好像违反用户调例?不管了草)

将得到的 ramdisk 放到
$KERNEL_REPO_ROOT/prebuilts/boot-artifacts/ramdisks/vendor_ramdisk

UPDATE
我发现 Google 自带了,我是傻逼

多种编译

对于比较新的机型,即 Pixel5+ 等使用 Tensor 的机型,google 提供了一个更加傻瓜式的脚本,build_slider.sh
但是秉承其优良传统,没有写进文档(

BUILD_AOSP_KERNEL=1 ./build_slider.sh

注意,BUILD_AOSP_KERNEL 是 Android13 引入的,之下的需要 BUILD_KERNEL=1

然后就一键结束了。。。

然后想要编译 Google 官方的内核,需要执行这个

BUILD_CONFIG=private/gs-google/build.config.slider build/build.sh

如果想编译 GKI2 内核(自行百度),可以这样

BUILD_CONFIG=aosp/build.config.gki.aarch64 build/build.sh

刷入

对于官方内核,刷入 dtbo boot vendor_boot vendor_dlkm 才能开机
但是 gki 的话刷 boot 就行

这个是官方的

fastboot flash boot boot.img
fastboot flash dtbo dtbo.img
fastboot flash vendor_boot vendor_boot.img
fastboot reboot fastboot
fastboot flash vendor_dlkm vendor_dlkm.img
fastboot reboot
正文完
 0
评论(一条评论)
wdwd
2023-08-21 21:01:27 回复

太强啦

 Windows  Chrome  中国香港