Saturday, September 3, 2011

Building your own Nook Color Android kernel

On the last post I told that I'm working on Cypress TrueTouch(tm) touchscreen driver for mainline inclusion.

So to work in a driver first you need to compile a Linux (or Android) kernel. Since I don't have a fully functional Linux kernel for the Nook Color, I'm developing against an Android kernel.

I want to document how to build your own Android kernel for two reasons. First someone could find it useful. Second, I wanted to document the process for myself. I context switch more than I would like and when I comeback to something I didn't do in a few days, I have to remember what are the exact commands to build the uImage, what is the defconfig file I use to build each kernel, etc. This happens even more with my hobbyists projects since I don't work with them on a daily basis.

So these are the steps to build a custom Android kernel for your Nook Color:

1- Installing CyangenMod (CM7) on an SD card:

First you have to decide if you want to install your kernel on your boot partition of your nand memory or using an external SD card. I prefer to only install stable software on my nand so I did an CM7 installation on an SD card and used that for development.

To install a CM7 on your SD card first download and gunzip the generic sd card image.

$ wget http://nook.handhelds.ru/sdimage/generic-sdcard-v1.3.img.gz
$ gunzip generic-sdcard-v1.3.img.gz

Then insert your SD card and copy the image to your SD card:

$ dd if=generic-sdcard-v1.3.img of=/dev/sdX bs=1024

Where X is the block device name for your SD card. To know which block device is associated with your SD card, insert your card and look the kernel log messages with dmesg for example.
After done with writing eject and insert again your SD card on your computer. Download a nightly build of CM7 for the Nook from http://download.cyanogenmod.com/?device=encore I'm using -153 but I guess that a newer or older should work either.
$ wget http://download.cyanogenmod.com/get/cm_encore_full-153.zip

One the file has been downloaded, copy it to the SD card. There should be only one partition on the SD.
$ mount /dev/sdX1 /media/boot
$ cp cm_encore_full-153 /media/boot

That's all, now unmount the SD card, insert it on the Nook and power off. The generic image will find and update file and automatically start CM7 installation. The process will re-partition your SD card and copy all the necessary files in each of them (x-loader MLO, uBoot u-boot.bin, kernel image and ramdisk in the boot partition, binaries and libraries in the rootfs partition, etc).
Once the installation is complete the Nook will power off and you have a fully functional CM7 installation on your SD card. The Nook Color has boot sequence when the SD card has higher precedence than the nand memory. If the SD card is inserted, the Nook will attempt to boot from there. So with the SD inserted, just turn on again the Nook an CM7 will boot from there.
That is, you now have a system to test your newer kernel.

2- Instal a ARM cross-compiling tool-chain

Since the Nook has an ARM processor and it is unlikely that your host machine is ARM base, you will need to install an ARM cross-compiling tool-chain to compile ARM Android images.
You can install different cross tool-chains both from source code and using pre-compiled packages for your host machine distribution. For example to install Linaro's GCC cross tool-chain you can use the following command on Debian and Debian-based distros (such as Ubuntu):
$ apt-get install gcc-arm-linux-gnueabi

3- Obtaining and compiling an Android kernel

Now you need CM7 Android kernel, this can be found in Dalingrin github repository.
$ git clone https://github.com/dalingrin/nook_kernel.git

Now you have to checkout a local branch for your work:
$ cd nook_kernel
$ git checkout -b devel origin/encore-32

Now you have a local branch devel to do your kernel development.
Do all the modifications you wish to the Android kernel and to compile your kernel first generate a .config file from the Nook Color defconfig file:
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-  omap3621_evt1a_defconfig

This will generate a .config file that contains all the symbols needed to compile Nook Color's board file and needed drivers. You can customize the build with:
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-  menuconfig

Once your kernel compilation is customized you can generate the kernel image with the following command:
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-  uImage

Once it finish compiling, the uImage is located in arch/arm/boot/uImage.
The last step is to copy the uImage on the SD card. I prefer to mount the SD boot partition in the Nook Color using ssh or adb commands and copy the uImage using scp, but this setup will be explained in other article. Another option is to remove the SD card from the Nook, insert on your host machine, mounting the boot partition and copy the image:
$ mount /dev/sdX1 /media/boot
$ cp arch/arm/boot/uImage /media/boot

That is, now you can insert the SD card on your Nook Color and boot your customized Android kernel.

Happy Hacking!!

Friday, September 2, 2011

The power of open source

I own an Barnes & Nobles Nook Color e-reader. It is a fantastic device that can be rooted easily and used as a tablet pc.

Besides using with Android I wanted to install Linux on it, but there isn't a fully functional Linux kernel for the Nook. So I contacted Oleg Drokin (a.k.a verygreen) and William Marone (a.k.a wmarone) that were working in porting Nook Color's Android drivers to Linux.

I pick the task to work on the Cypress TrueTouch (tm) touchscreen driver for upstream inclusion. I knew that Kevin McNeely from Cypress submitted a patch-set for a newer and better designed driver for the TrueTouch family. I contacted Kevin asking if I could take that patch-set as a starting point for the driver and what modifications were needed for the driver to be accepted.

Kevin kindly told me that a requirement was to modify the driver to use a different multi-touch protocol type from the one the driver had. So I modified the driver to use the newer multi-touch protocol type B. Kevin also gave me guidance, advice and code when I didn't understand the driver internals.

I posted a patch-set which was reviewed and a few issues were found. Again Kevin point me out what modifications are necessaries to fix these issues.

So that is what I'm working on in my free time. I'll keep modifying the driver and resubmitting the code until the patch is merged or Kevin and the folks from linux-input get tired of me.

This post is now longer than I would like, but I wanted to tell the full story to show the power of open source. I own a hardware that doesn't meet all my needs, I'm able to hack the device, modify it at my will and find help both from hobbyists and companies like Cypress and its engineers.

I think this is the best moment in history to be an engineer, 20 years ago one could only dream of having a modern operating system such as Linux or Android with its complete source code to read, understand and modify.

I know I want to be a FOSS hacker all my life. I don't think there could be a better way to build high quality software such as Linux.