BuildArmPackages

Revision 5 as of 2010-03-17 09:20:06

Clear message

Building ARM Packages with QEMU

(Text lifted from Debbie F at Canonical. Thanks Debbie!)

When working on an ARM project, it can be tricky to build and test a package before pushing it because:

  • Since hardware can be quite limited (especially at the beginning of a project), not all developers will have target hardware to work with
  • Even developers that do receive target hardware early, the hardware is often in such early stages that it is difficult to use, unstable, and possibly unable to connect to the network
  • Developing on the target hardware can be inconvenient if the device's image constantly needs to be re-flashed
  • Building on the target hardware can be very slow (though QEMU may not be faster...) and ties up CPU usage so other work on the device is difficult to do
  • On Jaunty, you cannot easily build your package for ARM directly on your (i386) development machine (on Karmic, however, the qemu-arm-static package is available)

Goals:

  • Easily build packages for armel from your Ubuntu environment
  • Easily run armel images from your Ubuntu environment
  • Works on Ubuntu jaunty and later, on i386 and amd64

Running a QEMU ARM image on your development machine may make your life easier. This page discusses how to setup a QEMU ARM image and to build ARM packages with it.

Anyone should feel free to update/correct the information in this Wiki page! This page was started simply as one person's experience building ARM packages with QEMU for an OEM project.

The following links are useful when setting-up/using a QEMU arm image:

Step By Step

The RootfsFromScratch page should serve as your main source of information for creating an ARM rootfs or image for use with QEMU. However, the following may be useful if you are specifically interested in specific steps used to build ARM packages for OEM projects.

Creating and Running ARM Image

If development machine is running Lucid or Karmic

Note: If your development machine is running Karmic, you may be able to just use the qemu-arm-static package to cross-compile an arm package on your i386 machine rather than running a full QEMU ARM VM.

  1. Create a directory for storing the QEMU files. In the steps, we will assume ~/qemuArm has been created for this purpose.

  2. Install qemu packages
    $ sudo apt-get install qemu qemu-kvm-extras
  3. Install debootstrap (version 1.0.10ubuntu3 or newer) if it is not already installed
    $ sudo apt-get install debootstrap
  4. Change into ~/qemuArm

  5. Download the contents of the rootstock bzr branch
    $ bzr branch lp:project-rootstock
  6. Download the qemu versatile cortex a8 kernel to ~/qemuArm

  7. Execute the following:
    $ sudo project-rootstock/rootstock --fqdn ubuntu --login ubuntu --password ubuntu --notarball --imagesize 3G
  8. Wait until rootstock completes. The script will take some time.

  9. The script should produce an image file named something like qemu-armel-<datetime stamp>.img

  10. Make a copy of the resulting image file. This will allow you to have a pristine image file around as well as a descriptive name for an image file you will be modifying. For example:
    $ cp qemu-armel-201001131621.img qemu-foo-arm.img
  11. Run QEMU with the image file that should be modified. Be sure to use the cortex a8 kernel and to set the proper CPU (see bug 437629) for more details.

    $ sudo qemu-system-arm -M versatilepb -cpu cortex-a8 -kernel vmlinuz-2.6.31-rc3versatile1-cortex-a8 -hda qemu-foo-arm.img -m 256 -append "root=/dev/sda mem=256M ro"
  12. QEMU should launch and boot a black screen with terminal output.

If development machine is running Jaunty

  1. Create a directory for storing the QEMU files. In the steps, we will assume ~/qemuArm has been created for this purpose.

  2. Install qemu
    $ sudo apt-get install qemu
  3. Install debootstrap (version 1.0.10ubuntu3 or newer) if it is not already installed
    $ sudo apt-get install debootstrap
  4. Download the build-arm-rootfs script to ~/qemuArm

  5. Download the qemu versatile kernel to ~/qemuArm

  6. Make sure you are in ~/qemuArm and execute:

    $ sudo ./build-arm-rootfs --fqdn ubuntu --login ubuntu --password ubuntu --notarball --imagesize 3G
  7. Wait until build-arm-rootfs completes. The script will take some time.

  8. The script should produce an image file named something like qemu-armel-<datetime stamp>.img

  9. Make a copy of the resulting image file. This will allow you to have a pristine image file around as well as a descriptive name for an image file you will be modifying. For example:
    $ cp qemu-armel-201001131621.img qemu-foo-arm.img
  10. Run QEMU with the image file that should be modified:
    $ sudo qemu-system-arm -M versatilepb -kernel vmlinuz-2.6.28-versatile -hda qemu-foo-arm.img -m 256 -append "root=/dev/sda mem=256M ro"
  11. QEMU should launch and boot a black screen with terminal output. The output should eventually end with a login prompt.

Configuring ARM Image for Project Builds

  1. Now that you have booted-up the ARM image you created, login with user ubuntu and password ubuntu (the username and password were set to ubuntu when calling build-arm-rootfs/rootstock to create the image).

  2. After logging in, you should have a terminal prompt to perform your builds. There is no GUI. Note that we intentionally created a bare minimum image (no GUI) so QEMU would not run prohibitively slow as you try and build ARM packages.
  3. The first time you login, you will need to setup the network. In the QEMU terminal, add the following to the bottom of /etc/network/interfaces:

    auto eth0
    iface eth0 inet dhcp
  4. Now bring-up the eth0 interface:

    $ sudo ifconfig eth0 up
    $ sudo dhclient eth0
  5. You should add to /etc/apt/sources.list additional repositories you will need, if any, and then update the package lists:

    $ sudo apt-get update
  6. You should now download any tools packages that you will use to build your packages (devscripts, pbuilder, quilt, etc.).

NOTE: You only need to configure the network and install a package once. These changes will be permanently stored in the qemu-foo-arm.img file so they will have already been made when you run QEMU with qemu-foo-arm.img in the future.

Configuring ARM Image for Sharing Files Between Host

For more background on these steps, see the "Connect your emulated machine to a real network" section of RootfsFromScratch.

On your host system:

  1. Make sure QEMU is not running
  2. Install bridge-utils package:
    $ sudo apt-get install bridge-utils
  3. Determine what interface your connected network is on (i.e. by using ifconfig). We will assume in the remaining steps that it is on eth0. If your interface is different, replace all instances of eth0 with your interface.

  4. Open /etc/network/interfaces for editing (as root)

  5. Add the following section to /etc/network/interfaces:

    auto br0
    iface br0 inet dhcp
      bridge_ports eth0
      bridge_maxwait 0
  6. Save and close /etc/network/interfaces

  7. Bring-down the eth0 interface
    $ sudo ifconfig eth0 0.0.0.0
  8. Bring-up the br0 interface
    $ sudo ifup br0
  9. Load the tun module (you can add tun to /etc/modules if you want it loaded automatically on boot)

    $ sudo modprobe tun
  10. Make sure /dev/net/tun exists and has 0666 permission

  11. Create a file /etc/qemu-ifup (as root) with the following contents (this script will be executed when QEMU starts)

    echo "Executing /etc/qemu-ifup"
    echo "Bringing up $1 for bridged mode..."
    sudo /sbin/ifconfig $1 0.0.0.0 promisc up
    echo "Adding $1 to br0..."
    sudo /usr/sbin/brctl addif br0 $1
    sleep 2
  12. Make the /etc/qemu-ifup script executable to all

    $ sudo chmod +x /etc/qemu-ifup
  13. When executing qemu-system-arm to launch QEMU with your ARM image, include -net nic,macaddr=00:16:3e:00:00:01 -net tap. For example, on Jaunty you would execute the following (for Karmic, the -kernel parameter would be vmlinuz-2.6.31-rc3versatile1-cortex-a8 instead):

    $ sudo qemu-system-arm -M versatilepb -kernel vmlinuz-2.6.28-versatile -hda qemu-foo-arm.img -m 256 -append "root=/dev/sda mem=256M ro" -net nic,macaddr=00:16:3e:00:00:01 -net tap
  14. Once the QEMU ARM image has loaded, install the openssh-server package in the ARM terminal
    $ sudo apt-get install openssh-server
  15. You should now be able to ssh into or scp to your ARM VM from the host. You can determine the ip address to ssh into or scp to by simply running ifconfig in the ARM terminal.

Note: I have found that the network modfications can cause my network connections to misbehave so have resorted to reverting the changes as soon as I am done using QEMU. I presume there is a better way...