Build KernelSU for Pixel Device

Note: This article is only available for devices without GKI (Pixel 5 and below, which Google calls Legacy Pixel) or MSM Project
Requirement
Pixel Device (recommend last oldest version, in this article is Pixel 3XL, image used
image-crosshatch-qq3a.200805.001
)Ubuntu machine (With 8-16 cores CPU, RAM higher than 16Gb, Hard Disk available at least 150Gb)
Pull it!
The first thing you need to do is ensure that the kernel you build can run basic functionalities such as touch, Wi-Fi, etc. Based on the kernel to be determined branch name of kernel
The commid id we are looking for is “dee0d123b122”. In my experience, I will go to Kernel MSM and find device_name-versionKernel-androidx
(in my case is crosshatch-4.9-android10
) then check all of branch to find matched. I found android-msm-crosshatch-4.9-android10-qpr3 have commit id is dee0d123b122058c6eeeee7cec14548e2c037131 matched with my kernel running on my Pixel device
Normally, projects from Google like AOSP will use repo
to manage the project instead of git
, so firstly, install repo
first, we also need to install requirement liked make
or g++
‘s library
sudo apt-get install sudo apt-get install make python-is-python3 gcc libssl-dev git-core gnupg flex bison build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig make
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/repo
chmod a+x ~/repo
sudo mv ~/repo /usr/bin/repo
Create kernel
folder and clone kernel
# Config git is necessary
git config --global user.name "<your name>"
git config --global user.email "<your name>"
# Create and clone with repo
mkdir kernel && cd kernel
repo init -u https://android.googlesource.com/kernel/manifest -b android-msm-crosshatch-4.9-android10-qpr3
repo sync
It will take your time (~10 mins)
Sync is done and your kernel on the device
Build it
We have many ways to build but in my experience, we should extract ramdisk on original image and build kernel from that to make sure that touch and wifi can work. In this article, I will follow that methods.
Prepare for build
Modify build code
At this time, build
tool (it will pull when you use repo to clone kernel source) only support for BOARD_HEADER_VERSION
3 so our devices is BOARD_HEADER_VERSION
2 will out of scope, we also need to rollback
cd build
git checkout ec7e1bc932f45518c6368bf0275b99639b904001
To make sure that we correct build tool, please check conditional logic code in build.sh
cat build.sh | grep "-eq \"3\""
Extract boot.img
When we get firmware from Google, we will see .zip
folder, let unpack it and get boot.img
file
Use Android Image Kitchen to extract boot.img
. We will get something like build parameters, randisk file, etc. Put boot.img
inside AIK-Linux
folder, then extract boot.img
git clone https://github.com/draekko/AIK-Linux.git && cd AIK-Linux
# Move boot.img inside AIK-Linux
./unpackimg.sh boot.img
Android Image Kitchen - UnpackImg Script
by osm0sis @ xda-developers
Supplied image: boot.img
Setting up work folders...
Image type: AOSP
Signature with "AVBv2" type detected.
Splitting image to "split_img/"...
ANDROID! magic found at: 0
BOARD_KERNEL_CMDLINE console=ttyMSM0,115200n8 androidboot.console=ttyMSM0 printk.devkmsg=on msm_rtb.filter=0x237 ehci-hcd.park=3 service_locator.enable=1 cgroup.memory=nokmem lpm_levels.sleep_disabled=1 usbcore.autosuspend=7 loop.max_part=7 androidboot.boot_devices=soc/1d84000.ufshc androidboot.super_partition=system buildvariant=user
BOARD_KERNEL_BASE 0x00000000
BOARD_NAME
BOARD_PAGE_SIZE 4096
BOARD_HASH_TYPE sha1
BOARD_KERNEL_OFFSET 0x00008000
BOARD_RAMDISK_OFFSET 0x01000000
BOARD_SECOND_OFFSET 0x00f00000
BOARD_TAGS_OFFSET 0x00000100
BOARD_OS_VERSION 10.0.0
BOARD_OS_PATCH_LEVEL 2020-08
BOARD_HEADER_VERSION 2
BOARD_HEADER_SIZE 1660
BOARD_DTB_SIZE 862396
BOARD_DTB_OFFSET 0x01f00000
Unpacking ramdisk (as root) to "ramdisk/"...
Compression used: gzip
40878 blocks
Done!
Please note this log, after unpacking have new ramdisk
and split_img
folders. We found split_img\boot.img-ramdisk.cpio.gz
is ramdisk, unzip it and move to kernel root folder
gzip -dk split_img/boot.img-ramdisk.cpio.gz
mv split_img/boot.img-ramdisk.cpio ../kernel/ # Move to root kernel
Get mkbootimg
Inside root folder of kernel get mkbootimg.py
. Here I will manual copy mkbootimg.py
Analyse build code
This part can skip, but please modify build/build.sh
first. Please add below before Files copied to…
line
if [ -f "${VENDOR_RAMDISK_BINARY}" ]; then
cp ${VENDOR_RAMDISK_BINARY} ${DIST_DIR}
fi
echo "========================================================"
echo " Files copied to ${DIST_DIR}"
Now you can skip to next part 😔, or see my analyse build code to know how to build the kernel
My target here is use BUILD_BOOT_IMG
to create boot.img
. This will help me avoid compatibility during create boot.img
. In the note of build code mentioned we need some information
# - MKBOOTIMG_PATH=<path to the mkbootimg.py script which builds boot.img>
# (defaults to tools/mkbootimg/mkbootimg.py)
# - GKI_RAMDISK_PREBUILT_BINARY=<Name of the GKI ramdisk prebuilt which includes
# the generic ramdisk components like init and the non-device-specific rc files>
# - VENDOR_RAMDISK_BINARY=<Name of the vendor ramdisk binary which includes the
# device-specific components of ramdisk like the fstab file and the
# device-specific rc files.>
# - KERNEL_BINARY=<name of kernel binary, eg. Image.lz4, Image.gz etc>
# - BOOT_IMAGE_HEADER_VERSION=<version of the boot image header>
# (defaults to 3)
# - KERNEL_CMDLINE=<string of kernel parameters for boot>
# - KERNEL_VENDOR_CMDLINE=<string of kernel parameters for vendor boot image,
# vendor_boot when BOOT_IMAGE_HEADER_VERSION >= 3; boot otherwise>
# - VENDOR_FSTAB=<Path to the vendor fstab to be included in the vendor
# ramdisk>
# If the BOOT_IMAGE_HEADER_VERSION is less than 3, two additional variables must
# be defined:
# - BASE_ADDRESS=<base address to load the kernel at>
# - PAGE_SIZE=<flash page size>
So we need
MKBOOTIMG_PATH => We already have inside kernel root folder
GKI_RAMDISK_PREBUILT_BINARY => We can skip because inside code, it only use if
BOOT_IMAGE_HEADER_VERSION
is more than 3 => We 2 nowVENDOR_RAMDISK_BINARY => Path of
boot.img-ramdisk.cpio
file extracted from.gz
fileKERNEL_BINARY => Used default name Image.lz4, lz4 is compress type of pixel image
BOOT_IMAGE_HEADER_VERSION => It is 2 (get from AIK)
KERNEL_CMDLINE => From AIK
KERNEL_VENDOR_CMDLINE => Can skip (
BOOT_IMAGE_HEADER_VERSION
> 3)VENDOR_FSTAB => Can skip (
BOOT_IMAGE_HEADER_VERSION
> 3)BASE_ADDRESS => From AIK
PAGE_SIZE => From AIK
Build
To build it compare all and use build/build.sh
. I will use private/msm-google/build.config.common
config to avoid bug
BUILD_CONFIG=private/msm-google/build.config.bluecross BUILD_BOOT_IMG=1 MKBOOTIMG_PATH=mkbootimg.py VENDOR_RAMDISK_BINARY=boot.img-ramdisk.cpio KERNEL_BINARY=Image.lz4 BOOT_IMAGE_HEADER_VERSION=2 KERNEL_CMDLINE="console=ttyMSM0,115200n8 androidboot.console=ttyMSM0 printk.devkmsg=on msm_rtb.filter=0x237 ehci-hcd.park=3 service_locator.enable=1 cgroup.memory=nokmem lpm_levels.sleep_disabled=1 usbcore.autosuspend=7 loop.max_part=7 androidboot.boot_devices=soc/1d84000.ufshc androidboot.super_partition=system buildvariant=user" BASE_ADDRESS=0x00000000 PAGE_SIZE=4096 build/build.sh
Choose BUILD_CONFIG
affects whether your device has touch or not. My recommend its use BUILD_CONFIG inside private/msm-google
.
Some repo have a confuse name like build.config.bluecross
and build.config.bonito
, like Pixel 3, bluehatch and crosshatch is Pixel 3 and Pixel 3XL; bonito is Pixel 3a, if we build bonito config and flash to 3XL its can make device not working. One point is check DEFCONFIG inside build.config
file. Like my config blue.config.bluecross
use DEFCONFIG=b1c1_defconfig b1c1
is name of Pixel 3/3XL (I found this information inside android-info.txt, inside .zip file in firmware)
It will stuck at LTO vmlinux.o
, if stuck its maybe work 😂
After build boot.img
placed in out/android-msm-pixel-4.9/dist/boot.img
We will try to boot
this file via fastboot. This only boot its mean if you reboot, its will disappear. You can revert to your kernel by restart device
adb reboot bootloader
fastboot boot out/android-msm-pixel-4.9/dist/boot.img
After boot, make sure that touch and wifi work, you can check to make sure that you running on custom kernel by below command. Original kernel will have (abfarm) but custom build can be customize username, hostname
adb shell cat /proc/version
# Linux version 4.9.210 (build-user@build-host) (Android (5484270 based on r353983c) clang version 9.0.3 (https://android.googlesource.com/toolchain/clang 745b335211bb9eadfa6aa6301f84715cee4b37c5) (https://android.googlesource.com/toolchain/llvm 60cf23e54e46c807513f7a36d0a7b777920b5881) (based on LLVM 9.0.3svn)) #1 SMP PREEMPT 2020-06-08 23:19:21
If everything work, you can be applied by fastboot flash boot
or continue to patch KernelSU
Patch KernelSU Next
Firstly, running the script
cd private/msm-google
curl -LSs "https://raw.githubusercontent.com/KernelSU-Next/KernelSU-Next/next/kernel/setup.sh" | bash -
Patch Manual
On non-GKI device, we will have 2 ways to use KernelSU are KPROBES_HOOK
and Manually way. Fun fact, Pixel 3 XL is older than Pixel 4 XL but running on Kernel newers than (Pixel 3 is 4.9 but 4.14 on Pixel 4). I do not know why but KPROBES is unstable and I do not know exactly what happends, so I will disabled KSU hook by KPROBES_HOOK
and patch manually (Now I know why, please check on next part) Find private/msm-google/KerneSU-Next\kernel\Kconfig
Change default y
to default n
to disable it
If you want to know we changed successful to Manual, just rebuild and boot to kernel
Follow on Manually modify the kernel source part on KernelSU to patch Kernel
Depends on you kernel, patch is different, on my kernel like this
open.c
exec.c
read_write.c
stat.c
Just rebuild and flash again.
Why if config not persistence?
Config not persistence because keyring its have bug, its appear on 4.14 kernel version (Pixel 4XL) and can fix by this patch. I recommended that you need to read and patch manually and rebuild and flash
Why still cannot install module?
A strange thing happened is I cannot enable the modules on my Pixel 3. First idea is because KPROBES hook not working but I’m wrong, its will happend even through I patched manually. Try to get log and I see error
Do not permission mean something block it execute system folder :/ What is this? I think its SELinux. After 1-2 hours to research I found issue on Github of KernelSU. And bingo I think my problem here because I used 4.9 kernel
Try to patch security/selinux/hooks.c
and waiting to build :d
It worked!!!!!!!!!!!!!!!!!!! In next time if patch can be used hook dont need patch manual for supported kernel
Flash
If everything is work, we need patch persistent to device by
fastboot flash boot boot-new.img
Then install KernelSU Next, please use latest version in tags to compatible with kernel
Subscribe to my newsletter
Read articles from sn00py z0r0 directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
