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/ 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
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/
$ 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 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


/ {
    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
Now copy 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Ă !

Wednesday, September 7, 2016

NFC improvements in Linux 4.8

Almost 4 years ago, I started to work on the linux-nfc project. I first worked on the implementation of a virtual device driver named nfcsim that was intended to simulate 2 NFC devices on the same host and make them talk to each other through the Logical Link Control Protocol (LLCP), also known as P2P mode.

My next project was the implementation of the NFC Digital Protocol stack. The Digital Protocol layer is usually embedded into the chipsets firmware but this is not the case for all of them. For example, the Sony RC-S380 USB dongle does not have it and I wrote its driver as well, based on the Digital layer.
With this work I was in the top 20 developers (by changed lines) for the Linux 3.13 release.

Here is an overall picture of the Linux NFC stack showing where the Digital Protocol layer fits in.
Linux NFC Stack
Unfortunately, about 2 years ago I had to stop  working on the linux-nfc project because of new priorities set by my former employer and switch to Android platform development.
I had to "abandon-in-place" this work and did not have any spare time to continue, so there was still some missing features and stability issues.

In the meantime, other developers have contributed to the Digital layer, adding support for some of the missing features in the NFC-DEP protocol such as packets chaining.
Also, TI and STM have added drivers for their own chipsets based on the Digital Protocol layer.

But now thanks to my new employer, Collabora, I'm now back to business and I've been offered the opportunity to keep on working the linux-nfc project.

However even with the progress made by other developers in the past years there was still a lot of kernel panics and memory leaks around the Digital layer and RC-S380 driver implementations. My main focus in the last 3 months was fixing these issues to provide a better stability both to Digital layer and RC-S380 implementations.

The upcoming Linux 4.8 release contains 26 patches for the Digital Protocol layer, the port100 driver (port100 is the NFC chip inside the RC-S380), and the nfcsim driver.

I'll talk about all of these components in more details in next posts but what I can say is that now they are rock solid!

Monday, July 25, 2016

First post

Now that I'm a proud Collaboran it's time for me to start my blog. 

Here I'll talk about Linux kernel development, mainly about NFC at first.

Some more interesting posts should land here soon...