Once we have U-Boot ready for the goldfish platform, we can use it to boot the Linux kernel in the Android emulator. Ideally, the boot process starts from nonvolatile memory (such as flash memory). Many kind of storage devices can be used in an embedded system, though NOR and NAND flash devices are the most popular options. In this chapter, we will build a goldfish Linux kernel first. We then explore how to boot Android from NOR flash and NAND flash using U-Boot and this kernel.
Building the Goldfish Kernel
Ideally, we might like to build everything on our own—from the bootloader, to the kernel, to the file system. Except for Google-specific applications, everything in Android is hosted in a project called Android Open Source Project (AOSP). However, we will lose our focus if we go into too much detail about every aspect of the build process right now. We will discuss AOSP builds in Part III of this book. If you want to learn how to build AOSP from scratch, the book Embedded Android by Karim Yaghmour is a good reference. In addition, the Internet provides plenty of articles that explain how to work on AOSP.
To build the kernel, we need two things: a prebuilt toolchain and goldfish kernel source code. The recommended option is to use the prebuilt toolchain from AOSP, which can be downloaded from the Google source git repository. Other prebuilt toolchains can be used as well. For example, we could use a prebuilt toolchain from a vendor such as Mentor Graphics (i.e., Sourcery CodeBench).
If you already have an AOSP source tree, you can use the prebuilt toolchain from AOSP directly. If you don’t have an AOSP source tree, the instructions in this chapter explain how to download this toolchain. If you installed your toolchain using the script install.sh introduced in Appendix A, you should have the toolchain from CodeBench Lite. In this case, you can skip the steps for downloading AOSP toolchain given in this chapter.
We will use the file system included with the Android SDK to boot up our kernel. When an Android virtual device is created, a corresponding file system is created as well. We will use the virtual device hd2 that we created in Chapter 2 in this chapter. The file system image for hd2 can be found at ~/.android/avd/hd2.avd.
You might wonder why we want to build the kernel ourselves instead of using the original kernel in the Android SDK to demonstrate the boot-up process. The reason is that we may not be able to boot up the Linux kernel as smoothly as we think. Actually, this process will most likely fail when we first attempt it. Thus we need a debug build to debug the boot process.
The porting of U-Boot actually includes two steps. First, we must add the necessary hardware support so that we can run U-Boot until the command-line prompt becomes available. Second, we must change U-Boot to prepare the proper environment for the Linux kernel so that control can be transferred to the kernel and the kernel can be started normally. In the second step, if we don’t have a debug version of kernel, it will be very difficult for us to debug U-Boot itself. We will demonstrate how to debug both U-Boot and the Linux kernel at the source code level in this chapter.