Monday, December 5, 2016

Booting a Pixel C tablet with a custom kernel

The Google Pixel C is a tablet running an Android userpsace on top of a ChromeOS kernel.

It is pretty straightforward to build your own AOSP for the Google Pixel C tablet and make it boot by following the steps from the Android Source web site.
You'll need to Download the Pixel C specific drivers (Pixel C binaries for Android 7.0.0), select one of the aosp_dragon-* lunch targets, build it, flash it, and it should run.

Of course, the AOSP provides a binary version of the Pixel C kernel image (device/google/dragon-kernel/Image.fit) used in the boot image you just built.

But if you want to build your own kernel, here are a few tips I had to experiment myself in order to test a few kernel patches on the Pixel C.

For the sake of this post, we'll use the official Android kernel tree for NVIDIA Tegra SoC familly that you can git clone here: 
$ git clone -b android-tegra-dragon-3.18-nougat https://android.googlesource.com/kernel/tegra
The easiest way is to build your kernel while your environment is setup for the AOSP build. You'll have the aarch64 compilers and binutils in your path.
$ source ./build/envsetup.sh
$ lunch aosp_dragon-userdebug
Then go to the kernel root folder and export the cross compilation build variables:
$ export ARCH=arm64
$ export CROSS_COMPILE=aarch64-linux-androidkernel-
Create the kernel config file:
$ make dragon_defconfig
And Build your kernel image:
$ make -jX
The uncompressed kernel image is located here: arch/arm64/boot/Image
This is the image we will use to create the Image.fit file used by the AOSP build. FIT stands for Flattened Image Tree and contains one or more kernel images along with various DTBs (Device Tree Blob). You'll need mkimage from the u-boot-tools package to create the FIT file from an ITS file (Image Tree Source).

The Pixel C bootloader seems to want lz4 compressed images only so we will have to make it:
$ lz4c ./arch/arm64/boot/Image Image.lz4
Now it's time to create the FIT image that will contain the freshly compiled kernel Image and the device tree blob for the Pixel C. The dts files are compiled by the kernel build system and stored in the same folder. The dtb for the Pixel C is arch/arm64/boot/dts/tegra/tegra210-smaug-p1.dtb.

Create the its file (Let's call it Image.its). As it is intended to boot on the Pixel C only, it will contain the image and one ftd entry.

/*
 * Simple U-Boot uImage source file containing a
 * single kernel and FDT blob
 */

/dts-v1/;

/ {
    description = "Simple image with single Linux kernel and FDT blob";
    #address-cells = <1>;

    images {
        kernel@1 {
            description = "Tegra Dragon Linux kernel";
            data = /incbin/("./Image.lz4");
            type = "kernel_noload";
            arch = "arm64";
            os = "android";
            compression = "lz4";
        };
        fdt@1 {
            description = "Flattened Device Tree blob";
            data = /incbin/("./arch/arm64/boot/dts/tegra/tegra210-smaug-p1.dtb");
            type = "flat_dt";
            arch = "arm64";
            compression = "none";
            hash@1 {
                algo = "sha1";
            };
        };
    };
    configurations {
        default = "conf@1";
        conf@1 {
            description = "Boot Linux kernel with FDT blob";
            kernel = "kernel@1";
            fdt = "fdt@1";
        };
    };
};

Build the FIT image:
$ mkimage -f Image.its Image.fit
Now copy Image.fit to AOSP_ROOT/device/google/dragon-kernel and rebuild the bootimage from the AOSP root:
$ make bootimage
Reboot the Pixel C in fastboot mode and flash the boot image:
$ fastboot flash boot
That's it! Reboot your device and voilĂ !

No comments:

Post a Comment