Caution
By using this guide, you accept all risks - including potential device bricking, failed boots, or other issues. We take no responsibility for any damage.
Questions will only be considered if you've read the full documentation and done your own research first.
What You'll Learn:
- Understanding the kernel root & choosing the right compilers for compilation
- Customizing the kernel and applying kernel patches.
- Remove Samsung's anti-root protections.
- Creating a signed boot image from the compiled kernel
Requirements:
- A working π§
- Linux based PC/Server (Debian-based recommended.)
- Basic knowledge in Linux commands and Bash Script.
- Patience
- The command below only for Debian-based distros like Ubuntu, Linux Mint, Debian and etc.
- You can compile kernel with other distros, like Arch-based
(pacman)and CentOS/RHL-based(yay)/(dnf). However, we won't provide it here. Please search related packages below that match with your distro! - Paste the code below in your terminal to start installation:
sudo apt update && sudo apt install -y git device-tree-compiler lz4 xz-utils zlib1g-dev openjdk-17-jdk gcc g++ python3 python-is-python3 p7zip-full android-sdk-libsparse-utils erofs-utils \
default-jdk git gnupg flex bison gperf build-essential zip curl libc6-dev libncurses-dev libx11-dev libreadline-dev libgl1 libgl1-mesa-dev \
python3 make sudo gcc g++ bc grep tofrodos python3-markdown libxml2-utils xsltproc zlib1g-dev python-is-python3 libc6-dev libtinfo6 \
make repo cpio kmod openssl libelf-dev pahole libssl-dev libarchive-tools zstd --fix-missing && wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb && sudo dpkg -i libtinfo5_6.3-2ubuntu0.1_amd64.deb
βThe video Guide for this tutorial can be found here (outdated): Open in Telegram
- π Downloading the kernel source code for your device
- π§ Understanding the Kernel root
- π§ Understanding non-GKI & GKI kernels
- π Preparing for the Compilation
- βοΈ Customizing the Kernel (Temporary Method)
- βοΈ Customizing the Kernel (Permanent Method)
βοΈ How to nuke Samsung's anti-root protections?- π’ Additional Patches
- β Compiling the Kernel
- π₯ Fixing the Known compiling issues
- π‘ Building a Signed Boot Image from the Compiled Kernel
β οΈ If your device is Samsung,
01. Download the kernel source from here: Samsung Opensource
02. Extract the Kernel.tar.gz from the source zip, unarchive it using this command and please do not use any apps to do this:
tar -xvf Kernel.tar.gz && rm Kernel.tar.gzNote: It's a good idea to give the entire kernel directory 755 permission to remove those read-only error from files and folders. This prevents issues when editing files and upstreaming the kernel.
Run this command to fix it:
chmod +755 -R /path/to/extracted/kernel/
The following video demonstrates all the steps mentioned above:
π₯ Extracting Samsung's Kernel.tar.gz & granting required permissions
-
β οΈ For other devices, You can find them by your OEM's sites or from your OEM's official GitHub repos:
- Generic Kernel Image, or GKI, is an Android's project that aims for reducing kernel fragmentation, (and also improving Android stability), by unifying kernel core and moving SoC and Board support out of the core kernel into loadable vendor modules.
| Pre-GKI | GKI 1.0 | GKI 2.0 |
|---|---|---|
| 3.10 | 5.4 | 5.10 |
| 3.18 | 5.15 | |
| 4.4 | 6.1 | |
| 4.9 | 6.6 | |
| 4.14 | ||
| 4.19 |
-
pre-GKI or non-GKI:
- The oldest Android kernel branch, likely starts from Linux version 2.x.
- These kernels are device-specific because its often heavily modified to accommodate SoCs and OEMs needs.
- Starting to get deprecated in ACK, since
linux-4.19.ybranch already reaching EoL (End of Life) state, with last Linux 4.19.325
-
GKI 1.0:
- Android's first generation of the Generic Kernel Image, starting with kernel version 5.4.
- This first generation of GKI only have android11-5.4 and android12-5.4 branch and Google announced that GKI 1.0 is deprecated.
- The first generation of GKI is not yet matured as second generation of GKI, as its failed to reach GKI project goals.
- These kernels are considered as device-specific, but more commonized, depends on how OEMs and SoCs Manufacturer treat them.
- SoC Manufacturers often modify GKI 1.0 kernel to add their SoC features. From this modifications, the term Mediatek GKI (mGKI) and Qualcomm GKI (qGKI) exist.
-
GKI 2.0:
- Android's second generation of the Generic Kernel Image, starting with kernel version 5.10.
- In this second generation, GKI project starting to get matured properly.
- This kernel is considered as "universal", since you can boot a GKI kernels that builded with Google's GKI kernel source on some devices, if correct and match.
- LTS = Long-Term Support: These kernels are stable, well-maintained, and receive long-term updates.
- GKI = Generic Kernel Image: A unified kernel framework introduced by Google to standardize the kernel across Android devices.
- SoC = System on Chip
- ACK = Android Common Kernel: An Android's linux LTS kernel branch, modified to accommodate Android needs.
- OEMs like Samsung may still modify GKI 2.0 kernels to accommodate their needs, and can cause some issues like broken SD Card and broken Audio.
- So, use their GKI kernel source instead if possible.
-
As you can see in the above screenshot, it's the Linux kernel source code.
-
It must have those folders, highlighted in blue in the terminal.
-
In GKI kernels, the kernel root is located in a folder named "common".
-
If you have a GKI Samsung kernel, you should use the "common" kernel instead of "msm-kernel" for the compilation.
01. After downloading or cloning the Kernel Source, we should have a build script to compile our kernel.
-
Before creating a build script, we must determine the compatible compilers we will use to build our kernel.
-
Run
make kernelversioninside the kernel root to check your kernel version.
-
In my case, the kernel version is 5.4, with qualcomm chipset, which is qGKI.
-
You can find full information about choosing the correct compiler for your kernel version here (based on my experience, btw).
-
Keep in mind that you don't need to manually download any of these toolchains since my build scripts handle everything for you :)
-
Next, go to build_scripts, choose the appropriate script, download it, and place it inside your kernel's root directory.
π‘ Better to Know: A defconfig (default configuration) is like a preset settings file for the kernel.
- It tells the build system which features to enable or disable.
So, Open the build script in a text editor and make these changes:
-
Replace
your_defconfigto your current defconfig which is located inarch/arm64/configs -
In GKI 2.0 kernels, it's normally
gki_defconfig -
But just in case, make sure to check
arch/arm64/configsorarch/arm64/configs/vendor -
If your defconfig is located in the
arch/arm64/configsdirectory, just replaceyour_defconfigwith the name of your defconfig. -
If your defconfig is located in the
arch/arm64/configs/vendordirectory, replaceyour_defconfiglike this:vendor/name_of_the_defconfig- Example patch: here
βIf your device is Samsung Exynos, it doesn't support compiling the kernel in a separated 'out' directory. So, edit your build script like this
β οΈ [IMPORTANT] : If your device is Samsung, it usually uses some device-specific variables in "some" kernels.
-
As an example, in the Galaxy S23 FE kernel source code, we can see they used variables called
TARGET_SOC=s5e9925,PLATFORM_VERSION=12, andANDROID_MAJOR_VERSION=s -
If we didn't export those variables correctly, the kernel failed to build in my case.
-
Don't worry, they usually mention these required variables in their
README_Kernel.txtor their ownbuild_kernel.sh
Refer to this example patch to properly integrate such variables into our build script: here
Note: Just don't overthink it, even if they use values like 12 and S for Platform and Android versions, even if you have a higher Android version.
π΄ If your device has a MediaTek chipset, usually it doesn't support booting a RAW kernel Image. Therefore, you should build a gzip-compressed kernel Image.gz instead.
-
If you find these variables:
REAL_CCorCFP_CCin your "Makefile", remove them from the "Makefile", then Search for "wrapper" in your Makefile. If there's a line related to a Python file, remove that entire line/function as well.- Example patch of removing the wrapper: click here
chmod +x build_xxxx.sh
./build_xxxx.sh
-
When you run the script for the first time, it will begin to install all the necessary dependencies and start downloading the required toolchains, depending on your kernel version.
-
Make sure not to interrupt the first run. If it gets interrupted somehow, delete the
toolchainsfolder from "~/" and try again:rm -rf ~/toolchains
- Additional notes:
- You can completely ignore anything displayed as
warning:- Eg:
warning: ignoring unsupported character '
- Eg:
- You can completely ignore anything displayed as
-
Once the menuconfig appears, you can navigate through it and customize the Kernel in a graphical way as needed.
-
As an example, we can customize the Kernel name, enable new drivers, enable new file systems, disable security features, and more :)
You can navigate the menuconfig using the arrow keys (β β β β) on your keyboard and press y to enable, n to disable or m to enable as a module <M>.
-
I guess no explanation is needed for this:
-
Located in:
General setup ---> Local version - append to kernel release
-
Btrfs is a modern Linux filesystem with copy-on-write, snapshots, and built-in RAID, ideal for reliability and scalability.
-
Located in:
File systems ---> < > Btrfs filesystem support
- CPU governors control how the processor adjusts it's speed.
- You can choose between performance-focused governors (like "performance" for max speed) or battery-saving ones (like "powersave").
- Please note that this may impact your SoCβs lifespan if the device overheats while handling performance-intensive tasks.
Enabling more CPU Governors:
- Located in:
CPU Power Management ---> CPU Frequency scaling --->
Changing the Default CPU Governor:
- Located in:
CPU Power Management ---> CPU Frequency scaling ---> Default CPUFreq governor (performance) --->
- IO schedulers control how your system handles reading and writing data to storage.
- Different schedulers can make your system faster or help it run smoother, depending on what you're doing (like gaming, browsing, or saving battery).
- Located in:
IO Schedulers --->
-
All the changes you've made using menuconfig are saved in a temporary hidden file called
.configinside theoutdirectory.
-
and it resets every time you run the build script.
-
So, we need a permanent method to save our changes, right?
-
In this method, we are going to create a separate
custom.configto store our changes and link it to our build script. -
After that, when we run the build script, it will first use your OEM defconfig to generate the
.configfile, then merge the changes from ourcustom.configinto.configagain.
Refer to these examples to get a basic idea: patch, commit
-
First, We have to find the exact kernel configuration option you want to enable or disable.
-
Example kernel configuration option:
CONFIG_XXXX=yCONFIG_XXXX: The name of the kernel option or feature ( Must begin withCONFIG_)=y: This means "yes" -> the option is enabled and will be included in the kernel.=n: This means "no" -> the option is disabled.
-
You can find the name of the kernel configuration option this way:
-
Run the build script and wait until
menuconfigappears. -
Navigate to the option/feature you want to enable.
-
Press
shift + ?on your keyboard, and an explanation about the option/feature will appear. -
Youβll see the name of the kernel configuration option in the top-left corner of the menuconfig.
-
Copy that name and add it to your
custom.configwith=yor=nto enable or disable it.
-
Note
Bypassing this usually not a good practice, because something like this is used as last effort,
when there's no open source linux driver found. (e.g Proprietary drivers)
But, for newbies or kernel developer that wanna ship their Loadable Kernel Module, this is okay.
-
On some devices, compiling a custom kernel can break system-level functionalities like Wi-Fi, touch, sound, and even cause the system to not boot.
-
The reason behind this is that the device can't load the external kernel modules
(*.ko), due to linux's prebuilt security feature(symversioning, signature)that prevent malicious kernel module to load. -
To fix this issue, use this patch to force the kernel to load those modules.
Even if you don't have such an issue, using this patch is still a good practice.
The reason:
Userspace reads /proc/config.gz and spits out an error message after boot
finishes when it doesn't like the kernel's configuration. In order to
preserve our freedom to customize the kernel however we'd like, show
userspace the stock defconfig so that it never complains about our
kernel configuration.
-
To fix this issue, make a copy of your OEM's Defconfig and rename it to
stock_defconfig.
-
Then, use the patch below to fool Android into thinking that the defconfig was not changed:
- Once you've customized the kernel as you want, simply exit menuconfig.
- After exiting, the kernel will start compiling!
- If you ever encounter any errors during your kernel compilation, jump to fixes and see if your specific issue is mentioned there.
Click here to learn about known issues and their fixes
-
On Android devices, the
kernelimage is usually located inside thebootpartition.
-
So, all we have to do is get the boot image from the stock ROM, unpack it, replace its kernel with our "built" one, repack it, flash it, and enjoy :)
For the unpacking and repacking process, we are going to use Android_boot_image_editor by @cfig :)
-
Download the latest release zip from here and unzip it like this:
Note: Make sure to follow the requirements installation section before using the Android_boot_image_editor
- Extract both the
bootandvbmetaimages from your stock ROM and place them inside theboot_editor_vXX_XXfolder
βοΈ Samsung-only note:
-
On Samsung devices, these images are usually located inside the
AP_XXXX.tar.md5file. -
All you have to do is rename
AP_XXXX.tar.md5toAP_XXXX.tarto remove themd5extension, extractAP_XXXX.tar, and grab theboot.img.lz4andvbmeta.img.lz4files from the extracted folder. -
Then, decompress these lz4 files using the following commands, and you will get your
boot.imgandvbmeta.imglz4 boot.img.lz4 lz4 vbmeta.img.lz4
- Now, run following command to unpack the
boot.img:
-
Keep in mind, this will take some time on the first run since the tool downloads dependencies during its initial execution.
./gradlew unpack
π As you can see in the screenshot above, the original kernel of the unpacked boot.img is located in build/unzip_boot/kernel
- Now, all we have to do is replacing the original
kernellocated inside theboot_editor_vXX_XX/build/unzip_bootwith our custom kernel.
Example:
What did I do?
-
Copied the compiled
Imagefrom thebuildfolder of the Kernel Root toboot_editor_vXX_XX/build/unzip_boot -
Deleted the original
kerneland renamedImagetokernelπ
./gradlew packπ¨ Our new boot image will be located inside the boot_editor_v15_r1 folder with the name boot.img.signed
-
Copy the
boot.img.signedfile to another location and rename it toboot.img -
Now, all you have to do is flash that
boot.imgthrough fastboot mode or Download mode (Samsung)
βοΈ Samsung-only note:
-
You can create an ODIN-flashable
tarfile using the command below:tar -cvf "Custom-Kernel.tar" boot.img -
Then, flash that
tarfile using ODIN's AP slot :)
Written by: @ravindu644 and our contributor(s)
Join Telegram: @SamsungTweaks





















