从零开端的内核编译
本教程将根据小米 10S 的内核源码进行实例,其他类型的手机请自行寻觅内核源码。具体内容能够参阅我的内核编译项目。
手机类型查询
1. 获取设备(手机)代号
在安卓设备终端(adb shell
)上履行:
getprop | grep device
并寻觅带有 ro.xx.device
这一行,里边的内容即为你的手机代号,例如:
# 手机代号为 thyme
[ro.product.device]: [thyme]
2. 获取设备架构
在安卓设备终端(adb shell
)上履行:
uname -m
我的设备显现为 aarch64
, 即可判别我的设备架构为 aarch64
。
3. 获取设备内核版别
在安卓设备终端(adb shell
)上履行:
uname -r
输出内容的格局为:
- [版别].[补丁版别].[子版别号]-[内核标识]-[提交记录]
例如我的设备显现为 4.19.157-Margatroid-gb1b98c3d4fd0
内核源码获取
内核源码的一般格局为 [android_]kernel_设备厂商_cpu/代号
,例如,小米 10S(thyme)的代号为 thyme
, CPU 类型为 sm8250
,生产厂商为 xiaomi
,则搜索格局应为下面几种:
kernel_xiaomi_thyme
kernel_xiaomi_sm8250
android_kernel_xiaomi_thyme
android_kernel_xiaomi_sm8250
以下是我搜集的一些小米 10S(thyme)的源码库房:
- Lynnrin-Studio/android_kernel_xiaomi_thyme: 这是我现在编译内核所运用的内核源码。
-
UtsavBalar1231/kernel_xiaomi_sm8250: CLO 内核升级为 CAF 标签
LA.UM.9.12.r1-14700-SMxx50
,AOSP 源码同步上游android-4.19-stable
。 -
WeeAris/RK-KSU-mi-kernel-SM8250: 支撑
KernelSU
的 Rohail33/RealKing-kernel-SM8250 分支。 -
Rohail33/RealKing-kernel-SM8250: 根据
LA.UM.9.12.r1-08000-SMxx50.0
标签的内核。
当然除此之外还有很多源码,但这些源码对于我来说是我前期学习的一个途径,因而在这里列出给咱们。
途径 | 具体介绍 |
---|---|
各厂商开源 |
小米内核开源 华为开源代码 |
去手机社区找源码 | XDA 论坛 |
获取编译东西链
强烈引荐您学习[内核向] 穿插编译器的挑选以及[白话文版] ClangBuiltLinux Clang 的运用来学习东西链的装备。
一起能够合作 Neutron-Clang 的阐明文档来进行编译参数装备。
现在比较引荐的几个预编译东西链如下:
东西名称 | 简介 |
---|---|
Neutron-Clang | 这是为内核开发构建的 LLVM 和 Clang 编译器东西链。构建始终是从最新的 LLVM 源代码而不是安稳版别构建的, |
阿菌•未霜 Clang/LLVM Toolchain with Binutils | 这是一个预构建的东西链,构建始终来自最新的 LLVM 和 Binutils 源而不是安稳版别,因而无法确保彻底的安稳性。它是用 Full LTO、PGO 和 BOLT 构建的,以尽可能削减编译时刻。 |
ClangBuiltLinux/tc-build | 相似前两个东西,但是这个东西需求自己在本地从 LLVM 的源码进行构建,但编译时刻较长。 |
除此之外,一个比较保险的办法是从预编译内核机器的 /proc/config.gz
提取`,需求对应版别的穿插编译器以及 Clang,自行挑选合适版别下载即可,通过这种办法编译出来的内核一般是不会存在过错的。
1. Neutron-Clang 运用介绍
这是为内核开发构建的 LLVM 和 Clang 编译器东西链。构建始终是从最新的 LLVM 源代码而不是安稳版别构建的,因而不能确保彻底的安稳性。现在该编译链东西运用 AntMan
来同步东西,具体运用办法如下:
mkdir -p "$HOME/toolchains/neutron-clang"
cd "$HOME/toolchains/neutron-clang"
bash <(curl -s "https://raw.githubusercontent.com/Neutron-Toolchains/antman/main/antman") -S
一些更多的 AntMan
指令:
功用 | 对应指令 |
---|---|
同步最新的东西链构建 |
./antman -S 或 ./antman -S=latest
|
同步特定的东西链版别 | ./antman -S=<release tag> |
查看更新 | ./antman -U |
查看更新和同步更新 | ./antman -Uy |
同步特定更新 | ./antman -S=<release tag> |
删除同步构建 | ./antman -D |
显现有关同步构建的信息 | ./antman -I |
同步特定的东西链版别 | ./antman -S=<release tag> |
假如需求更多细节介绍,请运转
./antman --help
获取。
2. ClangBuiltLinux
假如您想要运用这个东西链的话,那么其间的编译东西则需求你自行编译,对应的编译脚本为 ClangBuiltLinux/tc-build。
固然,自行编译确实是一件造轮子且费时吃力的办法,但是通过这种办法编译出来的东西是最适合您的体系的,不会发生其他的编译中的关于 glibc
等方面的过错。
3. 阿菌•未霜 Clang/LLVM Toolchain with Binutils
这是一个预构建的东西链,构建始终来自最新的 LLVM 和 Binutils 源而不是安稳版别,因而无法确保彻底的安稳性。它是用 Full LTO、PGO 和 BOLT 构建的,以尽可能削减编译时刻。
其编译链东西存储在:
- GitHub:仅用于发布预构建的压缩文件(*.7z)
- Gitea:仅用于存储预构建的二进制文件(Current AR Archive、ELF 64-bit LSB shared object 存储在 LFS)
编译脚本编写
内核编译流程其实只要两步:
- 生成对应设备的装备文件
make <theDefConfig>
- 开端编译内核
make
您能够直接履行这些指令进行编译(参数设置一定要正确),或参阅我下面的编译流程:
1. 设置编译链环境
最简略的设置环境办法便是将编译链东西的途径添加到体系途径中,例如:
export PATH="<absolute/path/to/ur/toolchains>/bin:$PATH"
# 例如,您正在运用 neutron-clang
# export PATH="home/user/toolchains/neutron-clang/bin:$PATH"
# 其间的途径必须为绝对途径
假如您在运用
gcc
,可能还需求将gcc
东西链的途径加入到环境变量中。
2. 简易装备脚本
首先给出一个最基础的装备脚本:
#!/bin/bash
args="-j$(nproc --all) \
O=out \
ARCH=arm64 \
CROSS_COMPILE=aarch64-linux-gnu- \
CC=clang \
CROSS_COMPILE_COMPAT=arm-linux-gnueabi- "
make ${args} <config name>
make ${args}
该脚本是在运用上一节的三个东西时才能够正常运用的,假如您运用其他东西能够需求进行其他装备。
下面是一些参数对应的阐明:
参数 | 阐明 | 一般参数 |
---|---|---|
CC |
指定运用的编译器,因为 make 默认运用 gcc ,因而实际上只要你在运用 clang 进行编译的时分才会运用该参数 |
clang |
CROSS_COMPILE |
您的主要穿插编译链东西,假如你在运用谷歌的 gcc 4.9,请指定参数为 aarch64-linux-android- ,32 位同理 |
aarch64-linux-gnu- |
CLANG_TRIPLE |
只在运用 clang 进行编译的时分才需求运用,用于指定当 clang 不收效时分运用的东西链,但在运用上一节咱们提到的东西中根本不必设置该参数 |
aarch64-linux-gnu- |
CROSS_COMPILE_ARM32 |
只在编译 32 位内核或许带 vdso 补丁的内核时需求指定该参数 | arm-linux-gnueabi- |
CROSS_COMPILE_COMPAT |
相似于参数 CROSS_COMPILE_ARM32 ,但内核版别为 4.19 及更新版别应运用本参数而非 CROSS_COMPILE_ARM32
|
arm-linux-gnueabi- |
更多参数介绍能够参阅一下 Neutron-Clang 的编译阐明,里边对于一些参数的阐明比较具体。
正常情况下,clang 是无法独立完结内核编译的,需求 gcc 的辅佐。但运用上一节介绍的几种东西并不需求并不需求独自指定
gcc
来辅佐编译。
3. 部分参阅脚本
- DogDayAndroid/KSU_Thyme_BuildBot:我自己编译的内核运用的本地编译脚本。
- UtsavBalar1231/Drone-scripts:一个很多人运用的编译脚本,我的部分代码也是参阅自这里。
- EndCredits/kernel_xiaomi_sm7250:相同的一个编译脚本,但并未供给编译链,但是其间的脚本流程我也有参阅。
-
xiaoleGun/KernelSU_Action:
KernelSU
的编译脚本,相同有参阅。
制作刷机包镜像
内核编译完结后的打包请参阅文章[内核向] 论怎么高雅的刷入内核,现在最流行的办法是运用 osm0sis/AnyKernel3 来完结整个内核的打包刷入工作。
假如您更喜欢自己着手,那么请参阅文章内的其他办法。
值得注意的是,不同版别的内核编译出来的内容并不相同,因而需求差异他们之间的打包,详情请参阅文章:关于 Image.xx-dtb 和 Image.xx + dtb 的差异。
来自文章的谈论区:_对应芯片组的。比如 865 只需求 kona-v2.1.dtb。假如弄不清楚,能够运用 cat 指令将多个 dtb 连接在一起,bootloader 会自动识别。
编译常见问题
本教程将根据小米 10S 的内核源码进行实例,其他类型的手机请自行寻觅内核源码。具体内容能够参阅我的内核编译项目。
1. -Werror=implicit-int
/arch/arm64/kernel/smp.c:834:8: error: type defaults to ‘int’ in declaration of ‘in_long_press’ [-Werror=implicit-int]
您能够修改 extern in_long_press
为 extern int in_long_press
;或许去除MakeFile 中对应过错限制。
参阅
- 自己编译定制一个牛逼的安卓内核
- 让 Android 手机更省电流畅,你能够试试「刷内核」
- [内核向] 穿插编译器的挑选
- [白话文版] ClangBuiltLinux Clang 的运用
- Neutron-clang 的编译阐明
- [内核向] 论怎么高雅的刷入内核