\subchapter{Supporting a new board}{Learn how to make Android on new
hardware}

After this lab, you will be able to:
\begin{itemize}
  \item Boot Android on a real hardware
  \item Troubleshoot simple problems on Android
  \item Generate a working build
\end{itemize}

\section{Setup}

Go to the \code{/home/<user>/felabs/android/linaro} directory.

Install the \code{bzr}, \code{python-argparse} and code{python-parted} packages.

\section{Download the source code}

Linaro has been working for some time now on a optimized Android distribution,
available on at least one chip of most of the major ARM vendors. At each release,
Linaro also maintains an Android flavored Linux kernel corresponding to the latest
upstream Linux release.

One of the platforms supported by the Linaro's Android is the BeagleBoard, which
is very similar to the DevKit8000 we use. In particular, both boards have the
same OMAP3530 CPU. Moreover, in the last kernel versions,
the kernel needed for both of these boards have been unified, so we can boot the
exact same kernel on both boards. For these reasons, we will use this
distribution as a starting point for the rest of the labs.

First, we need to download the source code. We will use the 11.11 release, which
is based on Android 2.3 Gingerbread and Linux 3.1.1
\footnote{At the time of this writing, Linaro doesn't support Android 4.0 Ice Cream
Sandwich on the Beagle board, and the port from \href{http://code.google.com/p/rowboat}
{Rowboat project} doesn't seem to be fully stable either. We decided to stick
with the most stable version for our hardware.}.

\begin{verbatim}
mkdir src
cd src
repo init -u git://android.git.linaro.org/platform/manifest.git \
     -b linaro-android-11.11-release
\end{verbatim}

Take a look at the \code{.repo/manifest.xml} file and compare it with
the one in \code{~/felabs/android/aosp/android/}. You can see that Linaro
took full advantage of the capabilities of the manifest file, using multiple
git servers instead of a unique one, and replacing some of the components
(like Dalvik and Bionic, for example) by its own optimized versions.

Now, let's run the big download job:
\begin{verbatim}
repo sync -j4
\end{verbatim}

Once again, even with a fast Internet connection, the \code{repo sync} command can
take more than one hour. Your instructor will keep you busy with other things
during these downloads.

In the mean time, you should also download and extract the associated Linaro toolchain:
\footnote{The original URL is
\url{http://android-build.linaro.org/builds/~linaro-android/toolchain-4.6-2011.11/4/android-toolchain-eabi-linaro-4.6-2011.11-4-2011-11-15_12-22-49-linux-x86.tar.bz2}. We wanted to give you something much shorter
to type.}
\begin{verbatim}
cd ..
wget http://goo.gl/Wn4dM
tar jxf Wn4dM
\end{verbatim}

\section{Build Android for the BeagleBoard}

Get back to the \code{src} directory.

As we said earlier, the DevKit8000 is very similar to the BeagleBoard, so we
will first compile a build for the BeagleBoard. The command to run is:

\code{make TARGET_PRODUCT=beagleboard TARGET_TOOLS_PREFIX=~/felabs/android/linaro/android-toolchain-eabi/bin/arm-eabi- boottarball systemtarball userdatatarball -j8}

Once again, you can expect this build job to take at least one hour to run,
even on a recent and rather fast laptop.

This job will build three tarballs in \code{out/target/product/beagleboard}:
\code{boot.tar.bz2}, \code{system.tar.bz2}, \code{userdata.tar.bz2}, plus the images of Xloader,
U-Boot, Linux kernel and its initramfs (which are also contained in
\code{boot.tar.bz2}).

We then need to put these images on an SD card so that we can boot on this system.

First, take the SD card provided by your instructor, and insert it into an SD card reader slot
in your workstation, or into a USB card reader provided by your instructor too. Then,
using the \code{dmesg} command, find which device your workstation uses for your SD card.
Let's assume that this device is \code{/dev/sdc}. 

Now we can use a \code{linaro-android-media-create} script that Linaro developed,
which takes the three tarballs and aggregates them to produce a ready-to-boot SD card.

You can install this script with the following commands:

\begin{verbatim}
bzr branch lp:linaro-image-tools
sudo ./linaro-image-tools/linaro-android-media-create --mmc /dev/sdc \
     --dev beagle --system out/target/product/beagleboard/system.tar.bz2 \
     --userdata out/target/product/beagleboard/userdata.tar.bz2 \
     --boot out/target/product/beagleboard/boot.tar.bz2
\end{verbatim}

Once this command is over, you can remove the SD card and insert it
into the corresponding slot on the DevKit8000 board.

\section{Setting up serial communication with the board}

To see the board boot, we need to read the first boot messages 
issued on the board's serial port.

Your instructor will provide you with a special serial cable
\footnote{This should be the same cable as for the Beagle and IGEPv2 boards}
for the DevKit8000 board, together with a USB-to-serial adaptor for the connection
with your laptop.

When you plug in this adaptor, a serial port should appear on your workstation:
\code{/dev/ttyUSB0}.

You can also see this device appear by looking at the output of the \code{dmesg}
command.

To communicate with the board through the serial port, install a
serial communication program, such as \code{picocom}:
\footnote{\code{picocom} is one of the simplest utilities to access
a serial console. \code{minicom} looks more featureful, but is also
more complex to configure.}

\begin{verbatim}
sudo apt-get install picocom
\end{verbatim}

Run \code{picocom -b 115200 /dev/ttyUSB0}, to start serial
communication on \code{/dev/ttyUSB0}, with a baudrate of 115200. If
you wish to exit picocom, press \code{[Ctrl][a]} followed by
\code{[Ctrl][x]}.

\section{Booting the board}

Once you inserted the SD card, you can boot the board by 
holding the \code{boot} key while switching the board on. On the
serial port, you should see Android going through its boot process, until
you finally have a shell on the serial link.

However, as you may have seen, the system boots, but you have no display at
all. We are going to fix this.

\section{Fix the blank screen}

The first problem we see is that the display remains blank the whole time. This
is because of the generated U-Boot being targeted for the BeagleBoard and not
for the DevKit8000. In the BeagleBoard product definition, find where the U-boot
config file to use is set and change this configuration to use the default
configuration for the DevKit8000 (\code{devkit8000_config}).

Compile and test your changes. You should now see the display working, while it
has a major glitch: it prints only a portion of the screen.

You can avoid doing a full rebuild by removing the
\code{out/target/product/beagleboard/obj/u-boot} directory.

\section{Fix the resolution}

The actual resolution is set to 640x480 on the screen, while its resolution is
only 480x272. This kind of adjustment is mostly done through the kernel
command line. On the SD card's \code{boot} partition, you will find a file named
\code{boot.txt}, which is a U-Boot script setting all the parameters needed
to boot the board properly, including the kernel command line. Change the
\code{omapdss.def_disp} and \code{omapfb.mode} properties so that it uses the LCD instead of
the DVI output and the correct resolution.

You can find some documentation for these options in the
\code{kernel/Documentation/arm/OMAP/DSS} file, in the \code{Kernel boot arguments} section.

You will then have to generate from this \code{boot.txt} file a \code{boot.scr} file
using the following command:

\code{mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n 'Execute uImage.bin' -d boot.txt boot.scr}
\footnote{This command puts the \code{boot.txt} file contents into a special container,
allowing U-boot to know that the \code{boot.scr} file is a script, and telling it how to handle
this file. All the files handled by U-boot should be put in such a container.}
 
Once this is done, test your changes by booting the board. You should see the
display working correctly now.

\section{Fix the touchscreen}

If you test the touchscreen with the previous Android build you made, you should
see that it is almost unusable, while the system receives some inputs. This mean
that the kernel has the driver for the touchscreen controller, but it returns
bogus values. If you pay attention however, you will find that the touchscreen
doesn't have the same orientation as the display.

Get back to the OMAP DSS documentation to find an option that might address
this problem.

\section{Bring it all together}

These tweaks are not persistent because the \code{boot.scr} file is generated at run
time by the \code{linaro-android-media-create} script. To automate this, modify this
script to add a ``devkit8000'' target device with the right kernel command line.

To do so, you will need to edit the files
\code{linaro_image_tools/media_create/boards.py} and
\code{linaro_image_tools/media_create/android_boards.py} to add \code{class} entries in each
file to specify the right boot command for your board. It should not take more than 10 lines to
add.

Once you have a solution that works, you can ask your instructor to give 
you a URL where Free Electrons' solution is available, and compare it with yours.

You can also add \code{no_console_suspend} to the bootargs as Android by
default suspends the shell on the serial line after a minute or so, making it pretty
hard to use it properly.

\section{Add the Buttons}

If you happen to launch an application, you will find that you cannot
get back to the home screen, as no button is mapped to the \code{back} and \code{home}
keys.

Button mapping is done in two steps. First, in the kernel, the
board should define the available buttons. In this case, we will use
the small black buttons right next to the screen on the
DevKit8000. These buttons are handled by the \code{gpio-keys} driver,
and defined in the devkit8000 board file in the kernel.

If you look into that file, you will see that only one button is
defined, the one corresponding to the button labeled \code{user key}
on the board.

We will map this button to the \code{back} key in Android. In the
\code{gpio_keys_button} structure, there is a \code{code} field. The
value of this field defines the keycode sent to the input
subsystem when you press that button, and will be later dispatched to
the userspace. Replace the keycode used by \code{KEY_EXIT} and look up
its value in the \code{include/linux/input.h} file.

The Android input system loads keymaps and key layouts for each loaded input
driver. To load these properly, it uses the same name as the
input driver, with an extension. In our case, the input driver being
\code{gpio-keys}, we will need to modify the \code{gpio-keys.kl} file.

This file consists of a list of entries, corresponding to what actions
every keycode should trigger in the system. Add a new entry to this file
for the back button, which should be like:
\code{key  <keycode>  BACK}

Once you're done, rebuild the system, boot it, and you should be able
to use the \code{back} key now!
