type
status
date
slug
summary
tags
category
icon
password
如果是虚拟机编译内存要求18G及以上(或交换分区
32G
),防止内存不够杀掉编译进程,为什么是18呢,因为试过16G会死(
link-vmlinux.sh
:行 101: 609008 已杀死 ${LD} ${KBUILD_LDFLAGS} -r -o ${1} $(l) …
。如果使用WSL配合docker1. 拉取官方内核
- 安装必要依赖
- 通过
cat /proc/version
查看内核信息
Linux version 4.19.202-g5fbe36ea56f7-ab8008033 (build-user@build-host) (Android (7284624, based on r416183b) clang version 12.0.5 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee), LLD 12.0.5 (/buildbot/src/android/llvm-toolchain/out/llvm-project/lld c935d99d7cf2016289302412d708641d52d2f7ee)) #1 SMP PREEMPT Thu Dec 16 06:08:11 UTC 2021
- 在https://source.android.com/docs/setup/build/building-pixel-kernels中查看pixel5设备对应的内核分支信息,这里是最新的分支所以后缀是
android14
,在编译内核时根据自己的系统在https://android.googlesource.com/kernel/manifest/+refs 中寻找对应的内核分支,例如这里选择android-msm-redbull-4.19-android12
- 进入具体的分支,查看其中的
default.xml
,重点关注<project path="build" name="kernel/build"
,如果revision
的值为main
,请千万不要下载,否则你就会发现下载下来之后根本无法build!!,这是由于build仓库和内核源码仓库不同步导致的
- 进行内核编译,在这之前需要配置好repo,并且最好配置全局的源为清华源,这部分参照源码编译部分 。
- 等待完成(大概需要60G以上的磁盘空间,耗时两小时左右)后需要进行
checkout
。这里的分支是依据Linux version 4.19.224-gf75e15ae64d0-ab8115056 (build-user@build-host)
中g
后的字符串决定的。
拉取后的源码
git
仓库分为三部分:android-kernel
是拉取源码的根目录,然后是msm-google
以及build
,其中msm-google
是内核源码仓库,任何对内核的更改提交位于该仓库,build
的负责编译的仓库,任何对编译配置等提交位于该仓库。android-kernel
无需add
内容或者提交commit
,msm-google
以及build
在修改后需要进行提交commit
,否则编译的内核会是dirty
的。2. 提取boot.img-ramdisk.cpio.lz4
- 获取当前系统的
rom
包,从中提取boot.img
,进一步通过https://forum.xda-developers.com/attachments/android-image-kitchen-v3-8-win32-zip.5300919/ 对boot.img
进行解包
这里需要使用官方的factory包,并且要找较低版本的包,例如
Android11
的出场包,因为对于pixel5而言Android12的包中的boot中移除了ramdisk
,所以无法提取到任何内容,这里使用rq3a.211001.001
这个包,正常情况下在解包后查看ramdisk会有很多文件夹,如果没有的话就有问题。- 解压得到的
boot.img-ramdisk.cpio.lz4
并将其放入android-kernel
目录中,低版本的内核可能没有mkbootimg
独立下载http://aospxref.com/android-11.0.0_r21/xref/system/tools/mkbootimg/mkbootimg.py 到android-kernel
- 然后需要修改编译参数
GKI_RAMDISK_PREBUILT_BINARY
,使得ramdisk
被打包进入boot.img
.手动指定private/msm-google/build.config.redbull.common
中的
GKI_RAMDISK_PREBUILT_BINARY=${ROOT_DIR}/boot.img-ramdisk.cpio.lz4
这样才会把boot
的ramdisk
打包进入boot.img
具体见第六节3. 嵌入rwProcMem33
- 下载https://github.com/abcz316/rwProcMem33 并将文件夹复制到
android-kernel/private/msm-google/drivers/
中
- 修改
rwProcMem33
中的ver_control.h
将MY_LINUX_VERSION_CODE
切换到对应的安卓内核版本,这里本来就是4.19.224
,与4.19.113
接近所以不需要更改了。
- 在
Linux 4.11
前,Linux内核把页表分为4级 - 页全局目录(Page Global Directory,PGD)
- 页上层目录(Page Upper Directory,PUD)
- 页中间目录(Page Middle Directory,PMD)
- 直接页表(Page Table,PT)
所以对于
Linux version 4.11
以下的内核版本,并不支持五级页表,选择启用读取pagemap文件来计算物理内存的地址
,同时注释掉启用页表计算物理内存的地址
Linux version 4.11
版本把页表扩展到五级,在页全局目录和页上层目录之间增加了页四级目录(Page 4th Directory,P4D)。所以对于Linux version 4.11
及以上的内核版本,选择启用页表计算物理内存的地址
,同时注释掉启用读取pagemap文件来计算物理内存的地址
。这里是默认情况,所以不进行更改。- 在
rwProcMem33/linux_kernel_api
文件夹中新建一个头文件linux_kernel_api.h
写入
- 为了包含
linux_kernel_api.h
头文件,在api_proxy.h
的前几行中加入#include "linux_kernel_api/linux_kernel_api.h"
- 在
private/msm-google/drivers/Makefile
的开头加入下列命令
- 在编译
rwProcMem33
内核模块时,由于内核编译时会将警告视为错误导致编译内核停止,所以我们要修改Makefile
来忽视warning
。在private/msm-google/Makefile
找到如下位置,在-Wno-format-security
后加上一个-w
参数
4. 编译内核
在安卓内核源码的根目录打开终端使用如下命令开始编译
命令的参数为使用android-image-kitchen解包boot.img之后,控制台所打印的参数请务必替换为相对应的参数!!!
编译命令如下
生成的
img
在android-kernel/out
中注意,任何对于kernel源码的改动均需
commit
,如果不进行commit
将会导致内核版本带有dirty
或+
等字样,可能影响环境检测。这里添加了新的rwProcMem33
并且在其内部进行了修改,那么就进入private
目录先add
新内容,再进入rwProcMem33
文件夹手动提交内部模块的commit
,然后在外部进行commit
,直到git status
不出现其他信息5. Magisk修补
将
boot.img
复制到设备中,然后使用设备中的Magisk APP
选择安装修补6. 刷入内核
在不修改编译参数
GKI_RAMDISK_PREBUILT_BINARY
之前刷入编译好的内核一直无法正常开机刷了整整两天
Pixel5
的内核,包括尝试刷入编译生成的vendor_boot.img
等各种方案,但是很不幸,不是卡google
就是一直循环bootloader
重启。后来看到了参考2中
Droid SMU
的回复。他提示先执行根目录下的build_redbull.sh
进行编译,然后将编译后的kernel/out/android-msm-pixel-4.19/dist/
中的Image.lz4
, Image.lz4-dtb
, kernel-uapi-headers.tar.gz
and all the *.ko kernel modules
从kernel/out/android-msm-pixel-4.19/dist/
复制到 aosp/device/google/redbull-kernel
中(建议先创建该文件夹备份),然后make -j8
编译aosp
。编译完成后将kernel/out/android-msm-pixel-4.19/dist/
中的vendor_boot.img
复制到AOSP目录下out/target/product/redfin
中。然后通过fastboot flashall -w
刷写即可。但是这样是需要编译AOSP的,如何不使用AOSP直接编译内核并替换是个问题,实际经过解img可以发现,
vendor_boot.img
在单独编译和放入aosp编译得到的文件结构是基本一致的,但是boot.img
确有很大差别如下图所示,左侧为内核独立编译后
boot.img
解包后的文件结构,右侧为使用AOSP
编译的内核。通过查看
MKBOOTIMG
的参数可以发现--ramdisk /android-kernel/prebuilts/boot-artifacts/ramdisks/ramdisk-aosp_arm64.img
指定了一个奇怪的img。再查看
private/msm-google/source/build.config.redbull.common
发现就是GKI_RAMDISK_PREBUILT_BINARY=${ROOT_DIR}/prebuilts/boot-artifacts/ramdisks/ramdisk-aosp_arm64.img
指向的内容,从而使其认为ramdisk
实际是这个img提供的,再看LZ4_RAMDISK=1
那么将GKI_RAMDISK_PREBUILT_BINARY
指向提取的boot.img-ramdisk.cpio.lz4
即可。正确的做法:手动指定
private/msm-google/build.config.redbull.common
中的GKI_RAMDISK_PREBUILT_BINARY=${ROOT_DIR}/boot.img-ramdisk.cpio.lz4
这样才会把boot
的ramdisk
打包进入boot.img
。下面的内容为介绍内容,并不在编译操作步骤之内
在不使用
init_boot
的情况下为设备构建启动映像对于没有init_boot
分区的设备来说,您需要一个 ramdisk 二进制文件,该二进制文件可以通过下载 GKI 启动映像后解压缩来获取。关联的 Android 版本中的任何 GKI 启动映像都可以使用。目标文件夹是内核树的顶级目录(当前的工作目录)。如果您使用 AOSP master 进行开发,则可以从 ci.android.com 上的 aosp_arm64 build 中下载ramdisk-recovery.img
构建工件,并将其用作 ramdisk 二进制文件。当您拥有 ramdisk 二进制文件并将其复制到内核 build 的根目录中的gki-ramdisk.lz4
时,可以通过执行以下命令来生成启动映像:如果您使用的是基于 x86 的架构,请将Image
替换为bzImage
,将aarch64
替换为x86_64
:该文件位于工件目录$KERNEL_ROOT/out/$KERNEL_VERSION/dist
中。启动映像位于out/<kernel branch>/dist/boot.img
。
还有人提到另外的解决方案,但是很显然,在实际测试过程中发现编出的
ko
文件已经被打包进入vendor_boot.img
所以不是这个问题。但是鉴于可能以后会有这样的问题,先把答案留在这。李大锐This is the script I use to launch a custom kernel which is working on pixel 4a. The key isflashing boot.img twice after sending *.ko.I think the the root cause is that the ko file built by the kernel does not enter the boot.img built by aosp. To fundamentally solve this problem a correct boot.img might be needed.
在这一切完成后需要先后刷入boot.img和vendor_boot.img,然后开机
7. 编译HwBpClient客户端
首先在VS installer中安装MFC支持
拉取项目进入
rwProcMem33\hwBreakpointProcModule\testHwBpClient
文件夹,使用vs
打开进行项目编译
在testHwBpClientDlg.cpp
的这个位置进行修改,将这个位置的llX
改为I64X
%zu
改成I64d
,否则将无法正确输入内容。即修改677 - 701
行内容,替换成下面的代码。使用
ctrl-B
生成exe
8. 编译HwBpServer服务端
编译HwBpServer服务端需要NDK,并将NDK引入环境变量中
NDK可以在
android studio
中进行安装,依次点击File->Project Structure->SDK Location
,找到Android NDK location
,点击Download
即可开始安装,我这里使用的ndk的版本为ndk25.2.9519653
如果没有安装Android studio
,NDK的安装方法可以在谷歌上找到NDK安装完成后,进入到
rwProcMem33\hwBreakpointProcModule\testHwBpServer\jni
,打开cmd运行命令ndk-build
。如果没有添加到环境变量可以直接找到ndk
文件夹中ndk-build.cmd
拖到cmd
或者powershell
中,在jni
目录下执行。编译后的文件在
rwProcMem33\hwBreakpointProcModule\testHwBpServer\libs
中,选择对应手机架构的ELF,push
到手机中运行即可#参考
- 作者:LLeaves
- 链接:https://lleavesg.top//article/pixel5-kernel-build
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章