注:此处内容总结自google官网:AOSP 编译内核。编译完成后刷机部分参考自其他大佬的文章。文中末尾提供了上传至CSDN的msm内核和Aarch64gcc工具 的下载链接,不想从官网下载的可以直接使用这个资源。
一.简介
1. 环境
手机:pixel
Android 版本:8.1.0
内核版本:3.18.70-g520f6eb
编译内核的Ubuntu:20.04.2
2. 编译内核流程概要
简单分为以下流程:
(1)下载源码,并拉取对应分支的源码;
(2)配置Ubuntu中编译所需要的环境(主要是aarch64-linux-android-gcc安装);
(3)参照google官网中的步骤编译;
(4)将内核刷到手机中。
二.编译过程
官网中给出了一个编译案例,是hikey版本的。本篇文章中测试机为pixel,需要通过pixel和hikey做对比,然后做相应修改。
Google官网中给出了一张表,表中列出了内核源代码和二进制文件的名称及所在位置,方便我们选择内核,这里只拷贝出了hikey和sailfish以及hammerhead版本的内容,方便对比:
设备 | 二进制文件所在的位置 | 源代码所在的位置 | 编译配置 |
---|---|---|---|
sailfish | device/google/marlin-kernel | kernel/msm | marlin_defconfig |
hikey | device/linaro/hikey-kernel | kernel/hikey-linaro | hikey_defconfig |
hammerhead | device/lge/hammerhead-kernel | kernel/msm | hammerhead_defconfig |
hikey编译过程如下: |
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-android-
cd hikey-linaro
git checkout -b android-hikey-linaro-4.1 origin/android-hikey-linaro-4.1
make hikey_defconfig
make
后面的拉取分支和编译代码都会参考hikey的编译过程。
1. 下载内核源码
需要编译安装msm的内核。可在官网中查看如下:
# msm 项目包含适用于 ADP1、ADP2、Nexus One、Nexus 4、Nexus 5、Nexus 6、Nexus 5X、Nexus 6P、Nexus 7 (2013)、Pixel 和 Pixel XL 的源代码,可用作在 Qualcomm MSM 芯片组上开展相关工作的着手点。
git clone https://android.googlesource.com/kernel/msm
下载内核源码不能直接通过以上命令下载,需要翻墙或者从清华源和科大源或其它国内源下载。本人是从vultr上购买了一个国外vps,使用命令行登录,然后使用以上的git命令下载源码,然后压缩打包并回传到本地(尝试了1G内存的vps下载时会报因为内存不够的问题,后面使用了4G内存的vps下载,下载完打包回传后,再将vps删除,以免再收费。vps上下载很快,但回传到本地很慢)。下载完成后,拉取分支代码的过程放到本地就可以,此过程不需要翻墙。
2. 拉取相应的手机对应的代码分支
首要的问题就是需要拉取哪个分支,官网中如下拉取,分支是“origin/android-hikey-linaro-4.1”:
git checkout -b android-hikey-linaro-4.1 origin/android-hikey-linaro-4.1
(1)通过手机型号及系统版本选择需要的代码分支
可以通过 git branch -a 查看到所有的分支,但因为分支太多,一次性会显示不全,所以可以用命令 git branch -a > branches.txt,然后从 file.txt中查看所有分支,或筛选性的查看某些分支。
因为sailfish 对应的二进制文件所在的位置是device/google/marlin-kernel,所以以marlin来筛选分支,另外因为使用的Android源码版本是8,即oreo,所以有理由相信我们需要拉取的分支就是以下包含 “marlin-3.18-oreo” 字符串的分支。
git branch -a > branches.txt
cat branches.txt | grep marlinremotes/origin/android-msm-marlin-3.18-android10...remotes/origin/android-msm-marlin-3.18-o-mr1-preview1remotes/origin/android-msm-marlin-3.18-o-preview-1remotes/origin/android-msm-marlin-3.18-o-preview-2remotes/origin/android-msm-marlin-3.18-o-preview-3remotes/origin/android-msm-marlin-3.18-o-preview-4remotes/origin/android-msm-marlin-3.18-oreoremotes/origin/android-msm-marlin-3.18-oreo-m2remotes/origin/android-msm-marlin-3.18-oreo-m4remotes/origin/android-msm-marlin-3.18-oreo-mr1-preview2remotes/origin/android-msm-marlin-3.18-oreo-r3remotes/origin/android-msm-marlin-3.18-oreo-r6remotes/origin/android-msm-marlin-3.18-p-preview-1remotes/origin/android-msm-marlin-3.18-p-preview-2...
(2)从设备信息上查找需要的代码分支
另外,通过当前手机上的内核版本号,拉取相同分支的代码。首先是查找当前手机的内核版本,Google官网提供的方法如下:
dd if=kernel bs=1 skip=$(LC_ALL=C grep -a -b -o $'\x1f\x8b\x08\x00\x00\x00\x00\x00' kernel | cut -d ':' -f 1) | zgrep -a 'Linux version'
# 对于 Nexus 5 (hammerhead),请运行以下命令:
dd if=zImage-dtb bs=1 skip=$(LC_ALL=C od -Ad -x -w2 zImage-dtb | grep 8b1f | cut -d ' ' -f1 | head -1) | zgrep -a 'Linux version'
但在运行以上命令时,可能因为缺少某些命令,导致获取内核版本失败。所以可以用如下方法:
cat /proc/version
Linux version 3.18.52-gf69ee35-dirty (tom@ubuntu) (gcc version 4.9.x 20150123 (prerelease) (GCC) ) #2 SMP PREEMPT Tue Nov 19 04:50:45 PST 2019
# 3.18.52-gf69ee35-dirty 便是当前的内核版本
当然也可以通过查找手机设置获取内核版本信息。
此时,可以通过内核版本信息中“f69ee35”检索分支,如下:
git checkout f69ee35
也可以通过如下命令查找到对应的分支(跑这天命令要很久。比较慢),然后再下载:
git branch -r --contains f69ee35
命令的结果如下:
...origin/android-msm-marlin-3.18-o-mr1-preview1origin/android-msm-marlin-3.18-oreoorigin/android-msm-marlin-3.18-oreo-m2origin/android-msm-marlin-3.18-oreo-m4origin/android-msm-marlin-3.18-oreo-mr1-preview2origin/android-msm-marlin-3.18-oreo-r3...
在找到和确定了某一分支时,通过类似如下的命令将远程分支拉取到本地:
git checkout -b android-hikey-linaro-4.1 origin/android-hikey-linaro-4.1
# 如:
git checkout -b android-msm-marlin-3.18-oreo origin/android-msm-marlin-3.18-oreo
3. 下载并配置交叉编译用的aarch64-linux-android-gcc
如果是已经下载过Android源码,在 prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9 下包含该工具,可以直接使用或将该工具拷出来使用。如果没有下载Android源码,可以在清华源或其它源上下载。
编译命令如下:
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-android-
export PATH=$PATH:/***/aarch64/aarch64-linux-android-4.9/bin # 配置交叉编译链工具的环境变量,这里是64位的工具,如果32位,则需配置32位的工具
cd msm
git checkout -b android-msm-marlin-3.18-oreo origin/android-msm-marlin-3.18-oreo # 如果已经拉取过分支,这一步可以跳过,也根据设备及Android系统版本拉取相应的其它分支
make marlin_defconfig # marlin_defconfig 是从 官网上查到。对比 hikey 的 hikey_defconfig 可知是salfish对应的是marlin_defconfig
make #也可以用多线程跑,如 make -j8 ,线程数可随Ubuntu系统的线程数更改
MODPOST 0 modulesDTC arch/arm64/boot/dts/htc/msm8996pro-htc_sailfish-xa.dtbDTC arch/arm64/boot/dts/htc/msm8996pro-v1.1-htc_marlin-xd.dtbDTC arch/arm64/boot/dts/htc/msm8996pro-htc_marlin-xc.dtbDTC arch/arm64/boot/dts/htc/msm8996-v3-htc_t50-xa.dtbDTC arch/arm64/boot/dts/htc/msm8996-v3-htc_sailfish-xb.dtbDTC arch/arm64/boot/dts/htc/msm8996-v3-htc_t50-xb.dtbDTC arch/arm64/boot/dts/htc/msm8996pro-htc_sailfish-xb.dtbDTC arch/arm64/boot/dts/htc/msm8996pro-htc_marlin-a.dtbDTC arch/arm64/boot/dts/htc/msm8996pro-v1.1-htc_sailfish-xd.dtbDTC arch/arm64/boot/dts/htc/msm8996-v3-htc_t50-xc.dtbDTC arch/arm64/boot/dts/htc/msm8996pro-v1.1-htc_marlin-xc.dtbDTC arch/arm64/boot/dts/htc/msm8996pro-htc_marlin-xa.dtbDTC arch/arm64/boot/dts/htc/msm8996pro-htc_sailfish-xc.dtbLZ4 arch/arm64/boot/Image.lz4CAT arch/arm64/boot/Image.lz4-dtb # arch/arm64/boot/Image.lz4-dtb 可最终用来刷机,但不能直接刷机,还需要编译一下
4. 进一步处理编译出的镜像并刷机
官网中也有给出处理方法,如下:
- 映像会输出到 arch/arm64/boot/Image 目录;内核二进制文件会输出到 arch/arm64/boot/dts/hisilicon/hi6220-hikey.dtb 文件。请将 Image 目录和 hi6220-hikey.dtb 文件复制到 hikey-kernel 目录。
以上第一个方法意思是将编译出来的arch/arm64/boot/Image.lz4-dtb替换Android源码中预置的内核文件,然后再对Android源码进行编译,预置的内核镜像位置类似在:android-8.0.0_r1/device/lge/bullhead-kernel/,不同的设备存放的位置会不同,但通过内核文件名还是不难找到。 - 您可以在使用 make bootimage(或编译启动映像的任何其他 make 命令行)时添加 TARGET_PREBUILT_KERNEL 变量。所有设备均支持该变量,因为它是通过 device/common/populate-new-device.sh 进行设置的。例如:export TARGET_PREBUILT_KERNEL=$your_kernel_path/arch/arm/boot/zImage-dtb 。
该方式是将编译好的 Image.lz4-dtb 存放到某个位置,然后将其设为环境变量,然后通过 make bootimage 编译获取boot.img。boot.img再通过fastboot命令刷机即可。如:source build/envsetup.sh lunch 23 export TARGET_PREBUILT_KERNEL=***/Image.lz4-dtb make bootimage
后面正常刷boot.img,或刷整机即可。
这里是使用第二种方法进一步处理Image.lz4-dtb,再刷机。刷入编译前后的内核版本截图如下(编译版本中一般带有内核编译时间,说明刷入成功):
网上也查到方法,可以先将boot.img从手机中导出,然后通过工具替换boot.img中的zImage文件。
三.小结
网上有很多文章介绍怎么编译和刷内核,但个人觉得这些无非也是从官网AOSP 编译内核上参考总结的,所以个人觉得首次要看的还是google官方文档,如果有问题,再搜索查看其他人的总结文档。如果有不对的地方,也欢迎批评指正。
msm内核代码和Aarch64gcc的工具一起上传到了:
android-msm-kernel-code-and-aarch64gcc-multi.zip.001
android-msm-kernel-code-and-aarch64gcc-multi.zip.002
android-msm-kernel-code-and-aarch64gcc-multi.zip.003
代码占空间比较大,压缩时分了三个包。如果有需要,将三个包下载放在同一目录下,解压即可。
参考
AOSP 编译内核
三、Android系统内核编译及刷机实战 (修改反调试标志位)
Android 系统编译之内核编译
android 内核源码编译到刷机