安卓自定义内核编译
近期想尝试一下安卓 kernel 的 kgsl 模块编译以及模拟。
实验环境
基于 Debian 12,clone 了 android-kernel repo 来进行试验。
由于Android 14以后不再支持 ./build.sh,我们这里集中学习如何使用 Bazel 来进行定制化编译。
编译
实际上高通有自己维护的 manifest 开源仓库,直接在 pull 下来全量编译即可(不过最新版的芯片型号是缺了一些库的)。
建立ddk工作区
ddk 工作区是 (Driver Development Kit),用于内核模块开发编译的工作区。
该工作区的目录结构为:
1 | .repo |
以下命令是创建一个 ddk 工作区的命令,会在目录下创建 MODULE.bazel, device.bazelrc, tools/bazel 等文件
1 | curl https://android.googlesource.com/kernel/build/bootstrap/+/refs/heads/main/init.py?format=TEXT | base64 --decode | python3 - [flags] |
基于以上命令的 flags 分为几种情况:
注意,以下的命令中 python3 init.py 都指代了上面的 curl 命令。
Local sources
提供完整的本地 android kernel 源码分支(ACK, Android Common Kernel),对应参数 --kleaf_repo /path/to/ddk/workspace/external/kleaf。
此时命令为:
1 | python3 init.py --local \ |
Local sources + prebuilts
提供了内核源码以及 prebuilts 目录(只包含ABI, headers, symbols list, 编译产物)
此时命令为:
1 | python3 init.py --local \ |
注意 –kleaf_repo 的路径必须是 ddk/workspace 下
从 prebuilts 中进行编译
确保目录结构:
1 | ddk/workspace |
在 workspace 下执行 repo init 命令。
我这里直接使用了 Local sources 方法。在本地建立了工作区。
注意 repo 初始化可能需要 init_ddk 以及 bazel,这时候可以先添加 –branch 参数从远程下载初始环境下来
编译自定义内核
利用 build_kernel 宏,这里我们暂不考虑
编译内核模块以及 DTB
in tree kernel modules
需要在内核 BUILD.bazel 的 kernel_build 中设置添加 modules_outs 属性。
external kernel modules
需要额外定义 kernel_module 。要为 build.config 中的 EXT_MODULES 变量中的每一个模块创建 kernel_module 编译目标kernel_module 中 kernel_build 属性为 自定义内核,或者 common 通用内核 //common:kernel_aarch64
outs 目录可以在编译过程中根据报错提示来进行更改。
设置 kernel_module 的 visibility 从而 kernel_modules_install 可以看到
如果 模块 依赖于其他模块,设置 kernel_module_deps。
如果模块依赖于其他路径的头文件,需要添加 filegroup,然后向 srcs 添加 headers。
定义 depmod 目标
定义 kernel_modules_install 目标。其包含所有 external kernel modules。其等价于 make modules_install 。
定义目标来构建所有启动镜像
kernel_image 宏会制作可刷写的分区镜像。
定义发行版目标
定义 pkg_files 和 pgk_install 目标,其包含了想要放置在 distribution 目录的目标。