Android KitKat

From gem5
Revision as of 06:30, 5 August 2015 by Andysan (talk | contribs) (Preparing a filesystem for gem5)
Jump to: navigation, search

Building Android KitKat for gem5

Overview

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.

Build Instructions

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
    • .../gem5kitkat/
      • .../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.

Useful commands:

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
1 / 500MB
2 /data 1GB
3 /cache 500MB

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. This directory contains a gem5-specific init.rc that is based on the original Goldfish device, with additional tweaks. Specifically, it runs /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:

git://linux-arm.org/linux-linaro-tracking-gem5.git


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:

Kernel Option Function
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.* ro.boot.*
androidboot.serialno ro.serialno
androidboot.mode ro.bootmode
androidboot.baseband ro.baseband
androidboot.bootloader ro.bootloader
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.

Resources

NoMali

TBD