首页
社区
课程
招聘
[原创]Pixel 2 (walleye) Android 10 手动集成 KernelSU 编译实战
发表于: 20小时前 270

[原创]Pixel 2 (walleye) Android 10 手动集成 KernelSU 编译实战

20小时前
270


> 设备: Google Pixel 2 (walleye) | Android 10 (QQ3A.200605.001) | Kernel 4.4.223 | KernelSU v0.9.5

>

> 编译环境: Ubuntu 22.04


## 背景


KernelSU 官方从 v1.0 开始不再维护非 GKI (Generic Kernel Image) 设备的支持。Pixel 2 使用的是 4.4 老内核,属于非 GKI 设备,只能通过**手动修改内核源码**的方式集成 KernelSU。


目前社区针对 Pixel 2 的 KernelSU 适配仅有 [AR-Project-Studio/kernel_google_wahoo](075K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6m8f1W2)9J5k6q4m8J5L8$3A6W2j5%4c8Q4x3X3c8e0N6s2g2V1K9h3!0Q4x3V1k6C8k6i4u0F1k6h3I4Q4y4h3k6Y4L8$3!0Y4L8r3g2Q4y4h3k6%4j5h3S2G2L8H3`.`.) 一个仓库,但它**只提供了 Android 14 分支的源码,没有预编译产物**,也没有对应的编译教程。而 Android 10 版本在整个社区中几乎没有可参考的资料。加上内核编译对磁盘空间(~15-20GB)和工具链版本的要求较高,想在 Android 10 上复现 KernelSU 基本只能从零摸索。


本文记录了在 Android 10 上完成这一过程的完整思路、踩坑经验和关键修复。


## 整体思路


```

获取 AOSP 内核源码 (4.4)

|

集成 KernelSU v0.9.5 源码

|

修改内核 fs/ 和 drivers/ 中的 6 个 Hook 点

|

使用 AOSP Clang + GCC 交叉编译

|

从工厂镜像提取 ramdisk + 新内核 → 打包 boot.img

|

fastboot 刷入

```


## 关键信息确认


在动手之前,需要先确认以下信息,任何一个搞错都会导致编不过或刷入后无法启动:


| 项目 | 值 | 确认方式 |

|---|---|---|

| 内核分支 | `android-msm-wahoo-4.4-android10-qpr3` | AOSP 官方文档 legacy kernel 表 |

| 内核版本 | 4.4.223 | 与工厂镜像 build 号 QQ3A.200605.001 对应 |

| KernelSU 版本 | v0.9.5 | 最后一个支持非 GKI 的版本,v1.0+ 明确不支持 |

| defconfig | `wahoo_defconfig` | walleye 和 taimen 共用 wahoo 平台 |

| 编译工具链 | AOSP Clang (clang-r370808) + GCC 4.9 | 需要 64 位和 32 位两套 GCC |


## 编译流程


### Step 1: 安装依赖


```bash

apt update

apt install -y build-essential bc bison flex libssl-dev libelf-dev \

   git curl wget python3 python-is-python3 zip unzip cpio mkbootimg \

   gcc-aarch64-linux-gnu gcc-arm-linux-gnueabi

```


### Step 2: 下载源码和工具链


```bash

WORK_DIR="$HOME/walleye_kernelsu"

mkdir -p "$WORK_DIR" && cd "$WORK_DIR"


# 内核源码

git clone 1beK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6S2L8X3c8J5L8$3W2V1i4K6u0W2k6$3!0G2k6$3I4W2M7$3!0#2M7X3y4W2i4K6u0W2j5$3!0E0i4K6u0r3K9$3g2J5L8X3g2D9i4K6u0r3L8i4y4E0 \

   -b android-msm-wahoo-4.4-android10-qpr3 --depth=1 kernel


# AOSP Clang

git clone 22cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6S2L8X3c8J5L8$3W2V1i4K6u0W2k6$3!0G2k6$3I4W2M7$3!0#2M7X3y4W2i4K6u0W2j5$3!0E0i4K6u0r3M7r3I4S2N6r3k6G2M7X3#2Q4x3V1k6H3M7X3g2T1N6h3W2D9N6s2y4Q4x3V1k6U0L8r3q4F1k6#2)9J5c8X3S2G2M7%4c8Q4x3V1k6D9K9h3&6#2P5q4)9J5k6s2R3^5y4R3`.`. \

   --depth=1 -b android10-release clang


# GCC 64位 (注意必须指定 -b android10-release)

git clone af3K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6S2L8X3c8J5L8$3W2V1i4K6u0W2k6$3!0G2k6$3I4W2M7$3!0#2M7X3y4W2i4K6u0W2j5$3!0E0i4K6u0r3M7r3I4S2N6r3k6G2M7X3#2Q4x3V1k6H3M7X3g2T1N6h3W2D9N6s2y4Q4x3V1k6Y4j5$3y4Q4x3V1k6D9K9h3&6#2P5q4)9J5k6s2R3^5y4W2)9J5c8X3q4S2M7X3y4Z5y4U0c8Q4x3V1k6S2j5i4u0U0K9o6j5@1i4K6u0V1L8r3W2F1N6i4S2Q4x3X3c8S2L8X3c8J5L8$3W2V1i4K6u0V1y4q4)9J5k6e0V1`. \

   --depth=1 -b android10-release gcc-aarch64


# GCC 32位 (vDSO 编译需要,同样需指定分支)

git clone d56K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6S2L8X3c8J5L8$3W2V1i4K6u0W2k6$3!0G2k6$3I4W2M7$3!0#2M7X3y4W2i4K6u0W2j5$3!0E0i4K6u0r3M7r3I4S2N6r3k6G2M7X3#2Q4x3V1k6H3M7X3g2T1N6h3W2D9N6s2y4Q4x3V1k6Y4j5$3y4Q4x3V1k6D9K9h3&6#2P5q4)9J5k6s2R3^5y4W2)9J5c8X3q4J5L8g2)9J5c8X3q4J5L8g2)9J5k6r3I4A6L8Y4g2^5i4K6u0V1j5h3&6V1M7X3!0A6k6r3g2S2j5X3W2Q4x3X3b7@1i4K6u0W2z5b7`.`. \

   --depth=1 -b android10-release gcc-arm32

```


### Step 3: 下载工厂镜像,提取原始 boot.img


```bash

cd "$WORK_DIR"

wget -O factory.zip "e01K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1L8q4)9J5k6h3N6G2L8$3N6D9k6g2)9J5k6h3y4G2L8g2)9J5c8X3c8D9i4K6u0r3j5h3&6V1M7X3!0A6k6q4)9J5c8X3q4G2M7%4m8Q4x3V1k6%4j5h3I4D9k6i4W2W2i4K6u0V1M7i4p5K6j5g2)9J5k6e0t1H3x3o6j5H3y4g2)9J5k6e0l9H3x3g2)9J5k6r3k6S2j5%4c8G2M7Y4W2Q4x3X3b7$3y4X3f1^5k6o6V1@1k6g2)9J5k6i4A6A6M7q4)9J5y4Y4q4#2L8%4c8Q4x3@1t1`.

unzip factory.zip -d factory_extract

unzip factory_extract/walleye-qq3a.200605.001/image-walleye-qq3a.200605.001.zip boot.img -d factory_extract

cp factory_extract/boot.img boot_orig.img

rm -rf factory.zip factory_extract

```


### Step 4: 集成 KernelSU 并修改内核源码


```bash

cd "$WORK_DIR/kernel"


# 拉取 KernelSU v0.9.5

curl -LSs "fddK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6J5j5i4N6Q4x3X3g2Y4K9i4c8Z5N6h3u0#2M7$3g2J5j5$3!0F1N6r3g2F1N6q4)9J5k6h3y4G2L8g2)9J5c8Y4c8A6j5h3&6F1i4K6u0r3d9$3g2J5L8X3g2D9f1#2g2Q4x3V1k6E0j5h3W2F1i4K6u0r3K9$3g2J5L8X3g2D9i4K6u0r3M7$3g2@1N6i4m8Q4x3X3g2K6K9q4)9J5y4Y4q4#2L8%4c8Q4x3@1t1`. | bash -s v0.9.5


# 启用 CONFIG_KSU

echo -e "\n# KernelSU\nCONFIG_KSU=y" >> arch/arm64/configs/wahoo_defconfig

```


然后修改 6 个内核源文件,添加 KernelSU Hook(详见 KernelSU 官方文档"修改内核源码"章节):


| 文件 | Hook 函数 | 4.4 内核注意点 |

|---|---|---|

| `fs/exec.c` | `do_execveat_common` | -- |

| `fs/open.c` | `do_faccessat` | 4.4 可能没有此函数,需改 `SYSCALL_DEFINE3(faccessat,...)` |

| `fs/read_write.c` | `vfs_read` | -- |

| `fs/stat.c` | `vfs_fstatat` | 4.4 没有 `vfs_statx`,必须用 `vfs_fstatat`,且参数名是 `flag` 不是 `flags` |

| `drivers/input/input.c` | `input_handle_event` | 安全模式,音量键救砖 |

| `fs/devpts/inode.c` | `devpts_get_priv` | 修复 pm 命令 |


### Step 5: 编译


```bash

cd "$WORK_DIR/kernel"


export ARCH=arm64

export SUBARCH=arm64


make CC=clang \

   CLANG_TRIPLE=aarch64-linux-gnu- \

   CROSS_COMPILE=$WORK_DIR/gcc-aarch64/bin/aarch64-linux-android- \

   CROSS_COMPILE_ARM32=$WORK_DIR/gcc-arm32/bin/arm-linux-androideabi- \

   wahoo_defconfig


make CC=clang \

   CLANG_TRIPLE=aarch64-linux-gnu- \

   CROSS_COMPILE=$WORK_DIR/gcc-aarch64/bin/aarch64-linux-android- \

   CROSS_COMPILE_ARM32=$WORK_DIR/gcc-arm32/bin/arm-linux-androideabi- \

   -j12 Image.lz4-dtb

```


### Step 6: 打包 boot.img


```bash

cd "$WORK_DIR"


# 解包原始 boot.img 获取 ramdisk

python3 mkbootimg_tools/unpack_bootimg.py --boot_img boot_orig.img --out boot_unpack


# 使用正确的 cmdline 和 header_version 重新打包

mkbootimg \

   --kernel kernel/arch/arm64/boot/Image.lz4-dtb \

   --ramdisk boot_unpack/ramdisk \

   --cmdline "androidboot.hardware=walleye androidboot.console=ttyMSM0 lpm_levels.sleep_disabled=1 user_debug=31 msm_rtb.filter=0x37 ehci-hcd.park=3 service_locator.enable=1 swiotlb=2048 firmware_class.path=/vendor/firmware loop.max_part=7 raid=noautodetect usbcore.autosuspend=7 androidboot.dtbo_idx=3 buildvariant=user" \

   --base 0x00000000 \

   --pagesize 4096 \

   --os_version 10.0.0 \

   --os_patch_level 2020-06 \

   --header_version 0 \

   -o boot-kernelsu.img

```


### Step 7: 刷入


```bash

adb reboot bootloader

fastboot flash boot boot-kernelsu.img

fastboot reboot


# 救砖(如果无法启动)

# fastboot flash boot boot_orig.img

```


---


## 踩坑记录与原始脚本问题分析


以下是初版编译脚本中的问题,通过 diff 对比和实际编译过程发现并修复。


### 坑 1: AOSP prebuilt 仓库不指定分支会克隆到空内容


**现象**: `git clone ... --depth=1 gcc-aarch64` 后目录内只有一个 `OWNERS` 文件,没有 `bin/` 目录。


**原因**: AOSP prebuilt 仓库的默认分支可能是空的或只有元数据文件。必须指定 `-b android10-release` 才能拉到正确的工具链二进制。


**修复**:

```bash

# 错误写法

git clone $GCC_REPO --depth=1 gcc-aarch64


# 正确写法

git clone $GCC_REPO --depth=1 -b android10-release gcc-aarch64

```


> 64 位和 32 位 GCC 都存在同样的问题。


### 坑 2: Ubuntu 22.04 没有 `python` 命令


**现象**: `make defconfig` 时报 `/usr/bin/env: 'python': No such file or directory`


**原因**: Ubuntu 22.04 默认只有 `python3`,不提供 `python` 软链接。老内核的 Makefile/scripts 中调用的是 `python`


**修复**: 安装 `python-is-python3` 包。


### 坑 3: 缺少 32 位交叉编译器 (`CROSS_COMPILE_ARM32`)


**现象**: `arch/arm64/Makefile:48: *** CROSS_COMPILE_ARM32 not defined or empty, the compat vDSO will not be built. Stop.`


**原因**: wahoo 内核的 compat vDSO (32位兼容层) 需要一个 ARM 32 位的交叉编译器。初版脚本完全漏掉了这个。


**修复**: 额外克隆 `arm-linux-androideabi-4.9` 并在 make 时传入 `CROSS_COMPILE_ARM32=` 参数。


### 坑 4: GCC 10+ `yylloc` 重复定义


**现象**: `multiple definition of 'yylloc'` 链接错误。


**原因**: GCC 10 开始默认 `-fno-common`,而老内核 dtc 工具的 `dtc-lexer.lex.c``YYLTYPE yylloc;` 会在多个编译单元中产生重复定义。


**修复**:

```bash

sed -i 's/^YYLTYPE yylloc;/extern YYLTYPE yylloc;/' scripts/dtc/dtc-lexer.lex.c

```


### 坑 5: vDSO 32 位汇编器路径传递失败


**现象**: `/..//bin/as: unrecognized option '-EL'` — 路径中出现 `/..//` 说明变量为空。


**原因**: `CROSS_COMPILE_ARM32` 通过 `export` 设置环境变量,但 vdso32 子 Makefile 没有正确继承。


**修复**: 将 `CROSS_COMPILE_ARM32` 作为 **make 命令行参数** 直接传入,而不是依赖环境变量:

```bash

make CC=clang ... CROSS_COMPILE_ARM32="$GCC32" -j12

```


### 坑 6: make 目标不明确


**初版脚本**: `make -j12`(不指定目标)


**修复版**: `make -j12 Image.lz4-dtb`


显式指定编译目标可以避免编译不必要的模块,加快速度并减少出错概率。


### 坑 7: boot.img cmdline 和 header_version 不正确


**初版脚本**:

```bash

--cmdline "console=ttyMSM0,115200,n8 androidboot.console=ttyMSM0 ..."

--header_version 1

```


**修复版**:

```bash

--cmdline "androidboot.hardware=walleye androidboot.console=ttyMSM0 lpm_levels.sleep_disabled=1 ..."

--header_version 0

```


**原因**:

- cmdline 必须与工厂镜像中的完全一致,否则可能导致启动异常。初版是一个不完整的猜测值。

- Pixel 2 Android 10 使用的是 boot header **version 0**,不是 1。header version 不匹配会导致 bootloader 解析失败。


---


## 资源消耗实测


| 项目 | 实测 |

|---|---|

| 内核源码 (depth=1) | ~3 GB |

| Clang 工具链 | ~5 GB |

| GCC 64 + 32 | ~2 GB |

| 编译产物 | ~1.5 GB |

| 工厂镜像下载 | ~1.5 GB |

| **总计** | **~13 GB** |

| 编译时间 (16核 -j12) | ~10 分钟 |

| 内存峰值 | ~6 GB |


## 最终效果


刷入后 KernelSU 正常运行,内核版本 4.4.210,Manager 版本 v0.9.5:



- **Status**: Working

- **Kernel**: 4.4.210-g9cb5a881-dirty

- **Fingerprint**: google/walleye/walleye:10/QQ3A.200605.001/6392402:user/release-keys

- **SELinux**: Enforcing

- **Superusers**: 1 | **Modules**: 1


## 附件


附件中提供了 Ubuntu 环境下的一键编译脚本 `build_kernelsu_walleye_fix.sh`,在 Ubuntu 22.04 上可直接以 root 权限运行:


```bash

chmod +x build_kernelsu_walleye_fix.sh

sudo ./build_kernelsu_walleye_fix.sh

```


脚本涵盖从依赖安装、源码下载、KernelSU 集成、内核编译到 boot.img 打包的全部流程,支持单步调试(如 `./build_kernelsu_walleye_fix.sh build` 只执行编译步骤)。


## 总结


在现代 Linux (Ubuntu 22.04, GCC 11) 上编译 4.4 老内核,最大的挑战不在于 KernelSU 本身的集成,而在于**工具链兼容性**。核心教训:


1. **AOSP prebuilt 仓库必须指定分支**,默认分支可能是空的

2. **新旧编译器不兼容**是最常见的编译错误来源 (`python` / `-fno-common` / `CROSS_COMPILE_ARM32`)

3. **boot.img 参数必须精确匹配原始镜像**,尤其是 `cmdline``header_version`

4. **make 参数优先于 export 环境变量**,确保子 Makefile 能正确接收

5. KernelSU 非 GKI 集成最后支持的版本是 **v0.9.5**,不要用 v1.0+




[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 270
活跃值: (789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2

ubuntu一键编译脚本在这

上传的附件:
20小时前
0
雪    币: 104
活跃值: (8112)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
tql
3小时前
0
游客
登录 | 注册 方可回帖
返回