Building Android KitKat for gem5
The easiest way to build Android for gem5 is to base the system on a the emulated Goldfish device. The main difference between the actual qemu-based Goldfish model and gem5 is a small number of gem5-specific configuration files. These files are mainly related to differences in block device naming and scripts to start use gem5's pseudo-op interface to start experiments.
Follow the directions on Android Open Source to download and build Android. Make sure to create a local mirror (see the download page) to speed up things if you ever need to create a new working directory. The following instructions are based on our experience from bringing up Android 4.4.4r2 (KitKat).
Make sure to quickly read the AOSP build instructions. In particular the section about Java dependencies. KitKat and earlier all depend on particular Sun/Oracle JDK versions. Lollipop and newer seem to be able to build with OpenJDK.
When setting up your build directories, I'd suggest a structure as follows:
- /work/android (or some other directory with plenty of free space)
- .../repos/aosp-mirro - Mirror of the upstream Android repository
- .../aosp - Clone of the Android repository
Build a vanilla AOSP KitKat distribution using the following command:
. build/envsetup.sh lunch aosp_arm-userdebug make -j8
This builds a plain Android for the Goldfish device (an Android specific qemu version). We are going to use this as a base for our gem5 distribution.
|hmm||Show a list of build system commands|
|mm||Build the Android module in the current directory|
|mma||Build the Android module in the current directory and its dependencies|
|emulator||Launch Android in qemu|
The mm command is especially useful since just running make in a directory with an existing build of Android (i.e., make doesn't need to build anything) can take several minutes.
Preparing a filesystem for gem5
First, create an empty disk (this example creates a 2GiB image) image:
dd if=/dev/zero of=myimage.img bs=1M count=2048
As root, hook up the disk image to a loopback device (the following
assumes /dev/loop0 is free).
losetup /dev/loop0 myimage.img
Using fdisk, create the following partitions:
|Part. No||Usage||Approximate Size|
Use common sense when setting up the partitions. The root partition will contain both Android's root file system and the system file system and should be big enough for both of them. The data partition will contain any apps that are not a part of the system (i.e., anything you install).
As root, tell the kernel about the partitions and format them to ext4:
partprobe /dev/loop0 mkfs.ext4 -L AndroidRoot /dev/loop0p1 mkfs.ext4 -L AndroidData /dev/loop0p2 mkfs.ext4 -L AndroidCache /dev/loop0p3
Mount the filesystem and extract the root file system:
mkdir -p /mnt/android mount /dev/loop0p1 /mnt/android cd /mnt/android zcat AOSP/out/target/product/generic/ramdisk.img | cpio -i mkdir cache mkdir -p /mnt/tmp mount -oro,loop AOSP/out/target/product/generic/system.img /mnt/tmp cp -a /mnt/tmp/* system/
At this point, the new disk image is a (mostly) vanilla Goldfish image. Add the gem5 pixie dust by copying all the files in the attached tar-ball into the new root file system and adding an m5 binary (see util/m5 in your gem5 work directory) to /sbin<tt>. This directory contains a gem5-specific init.rc that is based on the original Goldfish device, with additional tweaks. Specifically, it runs <tt>/gem5/postboot.sh when Android has booted. This script is responsible for disabling the screen lock and downloading and executing a run script from gem5.
At this point, everything should just work. Unmount everything and
disconnect the loop back device:
umount /mnt/android losetup -d /dev/loop0
Android systems generally does a lot of initialization (JIT compilation etc.) on the first boot. Since gem5 normally mounts the root file system as CoW and stores the file system differences in memory. To speed up future experiments, make sure to follow the guide in BBench-gem5 to make these changes permanent.
Building the kernel
You will need a recent ARM cross compiler to build the kernel. If
you're using Ubuntu 10.04, install it by running:
sudo apt-get install gcc-arm-linux-gnueabihf
Checkout the gem5 kernel from the following git repository:
Configure and build the kernel using:
make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm vexpress_gem5_defconfig make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm vmlinux -j8
Android Runtime Configuration
Simulation-specific kernel boot options options:
|qemu=1||Enable emulation support|
|qemu.gles=1||Don't use software rendering (usually enables GLES pass through)|
|androidboot.hardware=NAME||Overrides the device's platform name (used to select configuration files at boot)|
A simulated system should normally set qemu=1 on the kernel command line. This enables software rendering and some emulation specific services. In order to load the right boot configuration, set androidboot.hardware to gem5.
Kernel command line to properties mapping:
|Kernel Option||Android Property|
|androidboot.hardware||ro.hardware & ro.boot.hardware|
|*||ro.kernel.* if running in emulation mode|
Emulation Mode Specifics (qemu=1)
OpenGL & Graphics
- Setting the ro.kernel.qemu property forces libGLES_android to be used unless ro.kernel.qemu.gles is also set.
- qemu.sf.lcd_density instead of ro.sf.lcd_density is used to specify display density.