\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{Download the source code}

Go to the directory holding the Android source code (either
\code{/opt/android} or \code{$HOME/android-labs/source}).

While still using AOSP, we will use the configuration done in
TI-flavored Android build named \emph{rowboat}. This should make most
of the port mostly ready to use, and only a few things here and there
will be needed.

\code{repo} allows to manage your Android source tree in a smart way,
downloading only the differences between the new manifest we would
give it and the current code we have. In order to integrate these
additions nicely, the first thing we need is to add rowboat's
configuration repo to the manifest.

To do so, create a local manifest to add the repository
\code{git://github.com/bootlin/android-training-vendor-ti-beagleboneblack},
at revision \code{rowboat-jb-4.3-fe}, and store it to
\code{device/ti/beagleboneblack}

Once done, you can run \code{repo sync -c} again. It will download the
new git tree we just added and add it to our source code.
Note that you may have to use \code{repo sync --force-sync kernel} to
force syncing over the previously fetched kernel sources.

\section{Build the kernel}

Obviously, the Beaglebone Black needs a kernel of its own. The way
it's usually done in Android is by first compiling the kernel, and
then configuring the build system to use that binary.

So, the first step is to download the kernel. Once again, we can use
repo for that. Make it fetch the kernel from
\code{https://gitlab.com/ozgurkeles/bbb-kernel}, at revision
\code{rowboat-am335x-kernel-3.2}, in the \code{kernel} directory.

Once done, make \code{repo} download it, and we can start building our
kernel. This time, you'll need to use the \code{am335x_evm_android}
default configuration.

You can then start the compilation.

Once the compilation is over, we need to make the build system aware
of the image we just compiled.

To do so, we need a few things. First we need to move the
\code{zImage} we just compiled to our device folder.

Then, we need to tell Android that it will need to generate a
\code{boot.img} with the brand new kernel we have. This is done
through the \code{TARGET_NO_KERNEL} variable. Obviously, this will
need to be disabled. You can find where this variable is defined using
\code{grep}.

In order for Android to be able to properly generate the boot image,
it also needs to know to which base address and which command line it
needs. This is done by the \code{BOARD_KERNEL_BASE} and
\code{BOARD_KERNEL_CMDLINE} variables. You can see that
\code{BOARD_KERNEL_BASE} is already set, while
\code{BOARD_KERNEL_CMDLINE} isn't. In order for Android to show its
boot traces on the serial link, we need to set it to

\begin{verbatim}
console=ttyO0,115200n8 androidboot.console=ttyO0
\end{verbatim}

You also need to change \code{BOARD_KERNEL_BASE} to \code{0x80008000}.

Finally, we need to inform the Android build system of where our
actual image is. The \code{mkbootimg} tool is actually looking for a
file called \code{kernel} in the build directory, and it's up to the
device configuration to copy it there. Fortunately, the
\code{PRODUCT_COPY_FILES} macro is doing just that, so we'll need to
add our kernel copying to list of files to copy, with the syntax:

\begin{verbatim}
<path/to/source/image>:kernel
\end{verbatim}

And we should be done for now.

\section{Build Android for the BeagleBone Black}

No, we have gained support for the BeagleBone Black we're using. To
compile Android for it, we have to use lunch, in the same way we did
previously:

\begin{verbatim}
source build/envsetup.sh
lunch beagleboneblack-eng
\end{verbatim}

Make sure we are using \code{ccache}:

\begin{verbatim}
export USE_CCACHE=1
export CCACHE_DIR=$HOME/android-labs/ccache
\end{verbatim}
or, depending on your setup,
\begin{verbatim}
export CCACHE_DIR=/opt/ccache
\end{verbatim}

Then, we can start the compilation:

\begin{verbatim}
make -jX
\end{verbatim}

Once again, you can expect this build job to take quite a long time
(an hour or so) to run, even on a recent and rather fast laptop.

This job will build four images in
\code{out/target/product/beagleboneblack}: \code{cache.img},
\code{boot.img} \code{ramdisk.img}, \code{system.img} and
\code{userdata.img}.

We just generated bootable images that we will use on our device, we
can now run them on our boards.

\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 for the
Beaglebone, that is basically a USB-to-serial adapter 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 install picocom
\end{verbatim}

You also need to make your user belong to the \code{dialout} group to be
allowed to write to the serial console:

\begin{verbatim}
sudo adduser $USER dialout
\end{verbatim}

{\bf You need to {\em completely} log out of your session and log in again
for the group change to be effective.}

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 \code{picocom}, press \code{[Ctrl][a]} followed by
\code{[Ctrl][x]}.

You should then be able to access the serial console.

\section{Flashing and Booting the Images}

To flash the images we previously generated, we will use
\code{fastboot}.

The first thing you need to do is power up the board, and stop the
bootloader automatic boot. To do so, press a key in the \code{picocom}
terminal whenever the U-boot countdown shows up. You should then see
the U-Boot prompt:
\begin{verbatim}
U-Boot>
\end{verbatim}

You can now use U-Boot. Run the \code{help} command to see the
available commands. To switch to fastboot mode, the only thing you
need to do is type the command \code{fastboot} in this prompt.

The device will then wait for fastboot communications on its USB port.

\subsection{Configure USB access on your machine}

Your instructor will now give you a USB to mini-USB cable. Connect
the mini-USB connector to your board, and the other connector to your
computer.

We will use this connection for fastboot and, later on, adb.

If you execute any command right now, you are very likely to have an
error, because fastboot can't even detect the device. This is because
the USB device associated to the BeagleBone doesn't have the right
permissions to let you open it.

We need to make sure that \code{udev} sets the right permissions so
that we can access it as a user. To do so, create the file
\code{/etc/udev/rules.d/51-android.rules} and copy the following line:

\code{SUBSYSTEM=="usb", ATTR{idVendor}=="<VendorId>", ATTR{idProduct}=="<ProductID>", MODE="0600", OWNER="<username>"}

You can retrieve the vendor and product IDs to use when by using the
\code{lsusb} command, and looking at the line with \code{Texas
Instrument, Inc.}. You should see on this line the IDs to use, with
the format
\code{ID <VendorID>:<ProductID>}.

Now, unplug the USB cable and plug it again. You should now be able to
use \code{fastboot} from your user account, with the command
\code{fastboot devices} showing the board properly.

\subsection{Flashing}

On your workstation, first start by formatting the device

\begin{verbatim}
fastboot oem format
\end{verbatim}

Then, you can flash each images independently by using the commands

\begin{verbatim}
fastboot flash <partition>
\end{verbatim}

It will retrieve the matching images from the \code{out} folder, and
will flash them using fastboot. Be sure you flash the \code{boot},
\code{cache}, \code{system} and \code{userdata} partitions.

Once this is done, reboot using \code{fastboot reboot}, and you should
see Android booting.

However, you'll see that a process keeps crashing. If you use the
\code{logcat} command, you'll see that the crashing process is
\code{zygote}, and more specifically when starting a component called
\code{SurfaceFlinger}.

This component is Android's window manager, and it keeps crashing
because we haven't installed the GPU drivers yet.

\section{Adding the GPU drivers}

GPU drivers are most of the time implemented using a bunch of
user space libraries and kernel modules implemented provided by the GPU
vendor.

This is often a real pain to integrate, since it's tied to a
particular kernel version. There's several options to integrate them,
ranging from wrapping the Android build system invocations into a
custom script that will build the driver every time you run it, until
rewriting the whole driver Makefile to hook nicely into the build
system.

The solution we're going to use is probably one of the easiest, while
remaining one of the less evil.

The way we're going to proceed is, just like what we did for the
kernel, we're going to build the libraries and modules, and store them
in our device folder.

We're then going to add to the device configuration that the build
system has to copy these files into the images at compilation time.

The first thing to do is to download the SGX drivers source code from
rowboat. Modify your local manifest to download them from
\code{https://github.com/bootlin/android-training-hardware-ti-sgx},
at revision \code{ti_sgx_sdk-ddk_1.10-jb-4.3-fe}, and store it in
\code{hardware/ti/sgx}.

Once done, open up a new terminal, download it using \code{repo}. Now,
set up the path to use the Android toolchain.

\begin{verbatim}
export PATH=$(pwd)/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin:$PATH
\end{verbatim}

Then, go to the \code{sgx} folder, and compile it using the following
commands:

\begin{verbatim}
export TARGET_PRODUCT=beagleboneblack
export ANDROID_ROOT_DIR=<path/to/android/source>

make OMAPES=4.x W=1
make OMAPES=4.x install
\end{verbatim}

Now, if you look into the folder \code{device/ti/beagleboneblack/sgx},
you should see some folders with libraries and kernel modules that
have been installed by the SGX Makefile.

If you have some spare time, you can take a look at the file
\code{device-sgx.mk} in the beaglebone black device folder to see how
we install everything.

Now, you can recompile your images, flash the boot and system images,
and you should see the Android splash screen when rebooting!

\section{Fix the blank screen}

After the android logo, the screen will turn black. This is actually
the backlight turning almost off.

You can find the controls for the backlight in
\code{/sys/class/backlight}. Play with these controls until you find
the values that are working.

To make these changes permanently, you will have to edit the kernel
code. The used PWM is defined is the \code{am335xevm} board file, in
the \kdir{arch/arm/mach-omap2} folder. The PWM work by switching on
and off at a fast pace the power supply to be able to adjust the
average voltage delivered between 0 and the actual voltage of the
line. Increase the period by a factor of 100.

Once you're done, rebuild the kernel, boot it, and you should be able
to read the screen now!

