Search code examples
androidlinuxubuntu-18.04android-kernel

How to flash the kernel image on android device?


I am trying to learn the kernel customization and for this I have target OnePlus 6T device. I am able to compile the kernel source code on my Ubuntu 18 with the following steps:

  • Download latest dtc from https://packages.ubuntu.com/cosmic/a...piler/download and install it.
  • Clone kernel source code: git clone https://github.com/OnePlusOSS/androi...lus_sdm845.git
  • Clone ToolChain: git clone -b linaro-4.9-arm-linux-androideabi https://github.com/ArchiDroid/Toolchain prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-linaro-4.8
  • Open terminal at prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-linaro-4.9 and run: export CROSS_COMPILE=$(pwd)/bin/aarch64-linux-android-
  • Navigate to kernel source code path in the same terminal.
  • export ARCH=arm64 && export SUBARCH=arm64
  • make clean
  • make mrproper
  • mkdir Out
  • make O=Out sdm845_defconfig
  • make O=Out DTC_EXT=dtc CONFIG_BUILD_ARM64_DT_OVERLAY=y DTC_EXT=dtc -j4

Following are the last lines of compilation:

CC drivers/media/platform/msm/broadcast/tspp.mod.o
CC drivers/media/platform/msm/dvb/adapter/mpq-adapter.mod.o
CC drivers/media/platform/msm/dvb/demux/mpq-dmx-hw-plugin.mod.o
GZIP arch/arm64/boot/Image.gz
CC drivers/soc/qcom/llcc_perfmon.mod.o
CC drivers/video/backlight/lcd.mod.o
CC net/bridge/br_netfilter.mod.o
LD [M] drivers/char/rdbg.ko
LD [M] drivers/media/platform/msm/broadcast/tspp.ko
LD [M] drivers/media/platform/msm/dvb/adapter/mpq-adapter.ko
LD [M] drivers/media/platform/msm/dvb/demux/mpq-dmx-hw-plugin.ko
LD [M] drivers/soc/qcom/llcc_perfmon.ko
LD [M] drivers/video/backlight/lcd.ko
LD [M] net/bridge/br_netfilter.ko
CAT arch/arm64/boot/Image.gz-dtb
make[1]: Leaving directory '/home/.../KernelCustomization/android_kernel_oneplus_sdm845/Out'

Now, the next step is to flash the image. I have rooted OnePlus 6T device and I am confused with the three image files generated after successful compilation i.e.

  • arch/arm64/boot/Image.gz-dtb
  • arch/arm64/boot/Image.gz
  • arch/arm64/boot/Image

I need a favour in:

  • What image can I use to flash on android device?
  • Is booting a image with TWRP is enough to flash kernel?

Found Google documentation

https://source.android.com/devices/bootloader/partitions-images

As per following lines from google documentation:


boot: The boot partition contains a kernel image and a RAM disk combined via mkbootimg. In order to flash the kernel directly without flashing a new boot partition, a virtual partition can be used:

kernel: The virtual kernel partition overwrites only the kernel (zImage, zImage-dtb, Image.gz-dtb) by writing the new image over the old one. To do this, it determines the start location of the existing kernel image in eMMC and copies to that location, keeping in mind that the new kernel image may be larger than the existing one. The bootloader can either make space by moving any data following it or abandoning the operation with an error. If the development kernel supplied is incompatible, you may need to update the dtb partition if present, or vendor or system partition with associated kernel modules.


I think I have to use arch/arm64/boot/Image.gz-dtb for flashing the kernel. My understanding is that Image.gz-dtb is a virtual image that can be used to flash only kernel on android.

Still, I am not able to figure out the correct step to flash it. I am wondering if I will do something wrong then I will break my device so I want to be sure before flashing that it will work.

Any help or guidance will be very helpful at this moment.


I found the steps that are needed to flash the custom kernel on android device i.e.

  • First we need to get the boot image of stock firmware we can get it by running following commands:
    • adb shell "ls -la /dev/block/platform/soc/1d84000.ufshc/by-name/" > MoreInfo\msm_partitions.txt
    • Note the boot partition name e.g. boot_a -> /dev/block/sde11 boot_b -> /dev/block/sde39
    • Missing steps to make boot.img with command dd command.
  • Download the latest Android Image Kitchen from this thread.
  • Run the following with the boot image: unpackimg.sh .img
  • Locate the zImage file and replace it with your kernel image (rename it to what came out of the boot image)
  • Run the following to repack: repackimg.sh
  • Flash the new boot image with fastboot or TWRP!

I need some more information on the missing steps. Actually the process written above is working on devices that has only one boot partition. Does any one know how can I flash my single kernel image on a device that has a/b partitioning?


Update:

I searched over the internet for A/B partitioning and I found that these are used for seamless updates i.e. One partition is active at a time and another partition which is inactive can be used to flash the update. On reboot, another partition will become active and One partition will become inactive. More Info: https://www.xda-developers.com/how-a...opment-on-xda/

If my understanding is true then I just need to follow following steps to find the correct image to be used at the first step of flashing the kernel:

  1. fastboot getvar all | grep “current-slot”
  2. dd if="path to boot of active slot" of=/sdcard/boot.img
  3. Continue with boot.img and flash the kernel with above written steps for flashing a kernel.

Anyone who has this knowledge, please confirm. I will be very thankful to you.


Solution

    1. A/B OTA update Firstly, you need to confirm whether your phone is A/B OTA update or not by following command fastboot getvar slot-count If the command returns '2', then your phone supports A/B OTA update which means you have two boot partitions 'boot_a' and 'boot_b', otherwise, there should only be one partition 'boot'
    2. boot image The images you built (Image.gz-dtb) are just kernel images with device tree. They are not enough for flashing to boot partition since there should be ramdisk and boot arguments combined. The ramdisk content contains normal boot binaries for non-A/B OTA system or recovery binaries for A/B OTA system. You need to find official ramdisk images and combine with your kernel image. Normally mkbootimg will be used to create boot image in AOSP android.
    3. Flashing fastboot flash boot boot.img This works on both A/B and non-A/B system since image will be flashed to default active partition (boot_a is by default if you do not have OTA or using 'fastboot set_active' to change it) On A/B system, you can also use 'fastboot getvar current-slot' to get active slot and specific flash partition 'fastboot flash boot_a boot.img' or 'fastboot flash boot_b boot.img' XDA provides scripts to flash kernel images (Image.gz-dtb) with following steps: a. Dump boot.img from your phone b. Extract ramdisk.img from boot.img c. Combine Image.gz-dtb with ramdisk.img to new boot.img d. Flash new boot.img to boot partition

      https://forum.xda-developers.com/oneplus-6t/development/kernel-holydragon-t3878107 provides customized kernel and flash scripts, you should check and find your suitable way to flash your kernel image.