Sunday, September 20, 2015

Compiling a Permissive Kernel for a Galaxy Tab S 2 9.7

A few days ago I bought a Samsung Galaxy Tab S 2 9.7 (SM-T810) to play with. I needed a way to disable SELinux protections from accessing hardware, so I built my own kernel for it. The documentation I found on the process had some holes, so here is the process from start to finish.

This assumes you already know how to build a Linux kernel, but you don't know how to put one onto your Android device.

Also, if you do this incorrectly, it can render your device unbootable! So be very careful, and make backups of your device before attempting. In particular, make sure the kernel you are building matches the kernel it is replacing! Check the "Build Number" in Settings->About Device and make sure the kernel you download matches your current build.

Acknowledgements

I got a lot of help from these sources:

Getting Started

Prerequisites

First, you need a rooted SM-T810 running Android 5.0.2. If you don't know how to root it, search for "root sm-t810" and you will have it very quickly.

Second, you need ADB installed. The easiest way to get this is to install the Android SDK.

You may need a Samsung driver for the tablet. I searched for "Samsung USB driver for mobile phones" and found a Windows version here: http://developer.samsung.com/technical-doc/view.do?v=T000000117

You need a Linux system or a virtual machine running Linux. I used Ubuntu 14.04 AMD64. You may need to install some packages to build a kernel and run the tools below. The ones I noticed were:

  • build-essential
  • lzop
  • libc6:i386
  • libstdc++6:i386

Getting boot.img

You need to extract the existing kernel from your tablet so you can replace it. First, you have to find the boot image. On the SM-T810, I did:

adb shell
su
cd /dev/block/platform/15540000.dwmmc0/by-name
dd if=BOOT of=/sdcard/orig_boot.img

Then, you can use adb pull or the GUI to copy this file off your device. Save it for later.

Getting the Kernel Source

Point your browser to http://opensource.samsung.com and search for SM-T810. Download the version that best matches the "Build Number" from "Settings -> About Device" on your tablet. For me, this is T810XXU1AOG6.

This archive should have a "README_Kernel.txt" and "Kernel.tar.gz". Make a new directory and unpack Kernel.tar.gz into it, since otherwise it will unpack into the current directory and make a mess.

The kernel unpacks as read-only, so you need to run chmod ug+w * -R in the base directory to fix that.

Making a New Kernel

Disabling SELinux Always Enforce Mode

From the kernel base directory, open security/selinux/Makefile. At the top of the file, find the line that says:

EXTRA_CFLAGS += -DCONFIG_ALWAYS_ENFORCE=true
Change the true to false.

Getting a Cross-Compiler

I had no luck using the Android NDK cross-compiler. In general, you will have a much easier time using the same compiler that Samsung used. For the SM-T810 on Android 5.0.2, you can check this out with git:

git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8

For other versions, you can find tools at android.googlesource.com but make sure the EABI version matches what Samsung used or the kernel won't boot.

Building the Kernel

Now just follow the instructions in README_Kernel.txt to build the kernel:

  • Edit the base kernel Makefile to set up your cross compiler. So for example, if you ran the git command above from your home directory, the cross compiler will be /home/username/arm-eabi-4.8/bin/arm-eabi-
    • Do not use ~ in the path or the build process will fail very close to the end and you'll have to edit this again and rebuild from scratch! Expand this to /home/username yourself.
    • The "eabi" version should match whatever is in Samsung's Makefile.
  • Set the initial config, for example with make ARCH=arm exynos5433-gts210wifi_defconfig
  • Build the kernel with make ARCH=arm
    • You can speed this up with make ARCH=arm -j2 or higher values of -jN, depending on how many cores your system has.

Once the kernel is built, you will have a file called zImage in arch/arm/boot. This is the new kernel image.

Making Boot.img

Building a bootable image is the part that gave me the most trouble. The boot image consists of a kernel, an init ramdisk, and a device tree blob. It also has some kind of security hash, but the boot loader doesn't require this to boot.

You can get these extra files from orig_boot.img that you pulled off your device earlier. But you need a tool called mkboot to unpack and repack them. You can get this from GitHub:

git clone https://github.com/xiaolu/mkbootimg_tools.git

Add this directory to your path and run:

mkboot orig_boot.img boot

This will unpack the boot image into a directory called boot. Now copy your zImage over the file boot/kernel to replace the kernel, then type:

mkboot boot boot.img

to repack the boot image. Then make a tar file:

tar cf boot.tar boot.img

This can be flashed onto your device with Odin or Heimdall.

Turning on Permissive Mode

Once your tablet reboots after refreshing, you can put the kernel in permissive mode by setting

adb shell
su
setenforce 0
getenforce

The last command (get enforce) should print out "Permissive".

Restoring the Original Image

Since you dumped orig_boot.img, you can always put the original kernel back. Just rename it to boot.img, put it into a tar file (tar cf boot.tar boot.img), and flash it to your phone with Odin or Heimdall.

This can also recover your device if your custom kernel doesn't work.

Troubleshooting

If your kernel fails to boot, you can restore the original kernel and look in /cache/recovery/last_kernel and /cache/recovery/last_last_kernel for clues about why booting failed. They will contain logs of the entire boot sequence for the last several boots. Note that you must be root to view these files.

2 comments:

  1. hi can you help me with my samsung galaxy a910f. i follow your step but i am lost at "getting cross-compiler". i am not programmer yet i still learning about custom rom. can you explain a little bit detail for me. thank you

    ReplyDelete
  2. i am sorry i mean i am lost at building the kernel

    ReplyDelete