日暮清林
日暮清林
发布于 2023-01-03 / 6 阅读 / 0 评论 / 0 点赞

Android 内核编译

Android 内核编译

环境准备

Ubuntu 20.02 及以上(本人使用的 Ubuntu 23.04)

使用下列命令安装编译所需的依赖和库:


sudo apt-get update && sudo apt-get install -y bc bison build-essential ccache curl flex g++-multilib gcc-multilib git gnupg gperf imagemagick lib32ncurses5-dev lib32readline-dev lib32z1-dev liblz4-tool libncurses libncurses-dev libsdl1.2-dev libssl-dev libxml2 libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc zip zlib1g-dev gnupg flex bison build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig

获取手机的名称、代号、当前最新原厂系统的内核版本,获取手机处理器的名称、架构、型号和代号。

例如红米 K40:

名称:`Redmi K40`

代号:`alioth`

最新原厂系统内核版本:`4.19.157`

处理器:高通骁龙 870

处理器架构:`arm64`(arm64-v8a)

处理器型号:`SM8250-AC`

处理器代号:`kona`

源码获取与合并的原则

从低版本开始,逐级合并高版本内核代码。例如(随便举的版本号):

4.19.157 的 OEM 内核代码

4.19.210 的 CLO 内核代码

4.19.269 的 ACK 内核代码

首先以 OEM 内核代码为基底,开始合并 CLO 的内核代码,随后合并 ACK 的内核代码,这样可以尽可能减少冲突,也可以防止旧的代码重新出现在新的版本里。

也可以以 Linux Kernel 4.19.157 内核代码为基底,合并 OEM 的内核代码,随后合并 CLO 的内核代码,随后合并 ACK 的内核代码。

下面的例子均是从各个内核代码的最新版本/分支合并,请自行检查对应内核代码的分支和版本号,从而确定合并顺序。

获取源码

对于 Android 设备而言,其内核往往包括至少三方的代码,首先是 Linux Kernel,也就是最核心和基本的代码,在此基础上会有来自 SoC 制造商的代码(如高通的 CAF/CLO),亦会有来自 Google Android Common Kernel (ACK) 的代码,对于大多数 OEM 来说,还包括 OEM 自己的内部代码(通常为设备硬件的驱动)。

通常我们无法获取到 OEM 自己的内部代码(Google 除外),所以我们只需要在 Linux Kernel 的基础上并入来自 SoC 制造商和 Google Android Kernel 的代码即可。前者为针对处理器/芯片发布的适配、优化代码,后者为为 Android 提供功能更新和安全修复的代码。

获取 Linux Kernel

一般情况下,ACK 的内核代码默认会合并最新的 Linux 内核代码,一次直接使用 ACK 内核进行后面的步骤即可,但是如果你想从 Linux 获取原汁原味的代码来进行,可以从 Linux Kernel 官方获取源代码,也可以从 Google 提供的镜像站(非 ACK 代码)获取。

使用代码从 Linux Kernel 官方获取代码:

git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

然后进入源码目录,此时默认选择的是 Linux 内核主线代码,这个肯定是不能用的,因此需要选择合适的分支。

Linux 的版本号为:“<主版本号>.<分支版本号>.<修正版本号>”
通常我们看到的是:“4.19.269”,我们必须选择和手机原厂系统内核版本号一样的分支(只需要主版本号和分支版本号相同即可)。

例如 Linux 4.19 内核,我们则输入下列命令切换到 4.19 分支:

git checkout linux-4.19.y

获取 Google Android Common Kernel 代码

git clone https://android.googlesource.com/kernel/common

随后切换到你需要的 Linux 版本的分支。

git checkout android-4.19-stable

获取 SoC 制造商代码(以高通为例)

首先获取手机处理器的名称、型号和代号,以高通骁龙 870 处理器为例。

名称为:高通骁龙 870

型号为:`SM8250-AC`

代号为:`kona`

随后我们在 CLO 的 Wiki 页面查找该处理器的内核代码:https://wiki.codelinaro.org/en/clo/la/release

从 Wiki 页面查找到:`LA.UM.9.12.r1-14900.01-SMxx50.0` 我们可以使用此 TAG 的代码。

在上面的源码目录输入命令:

git fetch https://git.codelinaro.org/clo/la/kernel/msm-4.19.git LA.UM.9.12.r1-14900.01-SMxx50.0

从高通内核项目的 msm-4.19 仓库获取 TAG 为 `LA.UM.9.12.r1-14900.01-SMxx50.0` 的代码。待源码下载完成后,合并代码。

git merge FETCH_HEAD

解决掉一大堆的冲突后便完成此项工作了。(不知道保留谁的代码或者怎么改可以直接抄作业,看看别人合并好的内核是怎么写的)

获取 OEM 代码

以小米为例,小米在 Github 的 MiCode 账号下开源其设备使用的内核代码(只有部分驱动等内容,MIUI 底层的东西肯定是没有的)

小米内核开源项目地址:https://github.com/MiCode/Xiaomi_Kernel_OpenSource/

根据设备代号,找到你的设备使用的最新内核代码。分支命名规则为:<设备代号>-安卓版本-oss,请选择该设备安卓版本最高的内核代码分支。

以 Redmi K40 为例:

git fetch https://github.com/MiCode/Xiaomi_Kernel_OpenSource.git alitoh-r-oss 

随后合并:

git merge FETCH_HEAD

解决冲突后,便完成了。

开始编译

进入内核源码目录,使用命令生成配置文件。

make ARCH=arm64 menuconfig

根据需要调整选项,保存配置文件(默认为源码目录下的`.config`文件,勿动),随后使用命令:

make ARCH=arm64 defconig

将生成的 defconfig 文件重命名,保存到 /arch/arm64/configs/ 目录下即可

随后在设备树中修改相应的变量使用对应名称的 defconfig 文件即可。


评论