Step-by-step Using qemu to Boot an Emulated Odroid
NOTE: This has not been third-party tested yet. You can be the first!
This tutorial is for Linux Developers using Linux hosts. It is really not for Windows hosts -- although you can certainly work through this tutorial on a virtual machine guest.
- 1 Introduction
- 2 Prerequisites
- 3 Overview
- 4 Interesting Links
- 5 Host Setup
- 6 Download Example Files
- 7 Check for any Existing Qemu
- 8 Building Qemu
- 9 Create Root File System Partition Image
- 10 launch-no-bridge
- 11 Networking Setup
- 12 launch
- 13 Launching on Ubuntu
- 14 Further Experiments
If you don't know what qemu is for, look around on Wikipedia.
Is it good for everything? No. Is a hammer good for sawing? Not so much. Consider qemu as another tool for your toolchest.
If you need to develop code for a platform that is not yet available, qemu might help. Also, if you are doing certain kernel work, it can be handy.
Generally, your root file system doesn't care which kernel you use. This tutorial uses a kernel configured for a vexpress-a9 platform (TBD. check that exact name). You can boot root file systems meant for odroid without changes.
It is possible to allocate a large amount of RAM to the emulated machine, and it is possible, but not necessarily faster to emulate multiple cores.
We are going to:
These are some of the good references I used:
Make sure you have the neccessary programs installed
# update the list of available packages # as root: apt-get update sudo apt-get install libpixman-1-dev zlib1g-dev libglib2.0-dev shtool build-essential
Download Example Files
You can use your browser, or use web get to get the example files tarball.
#Create a working folder, and move into it. mkdir odroidu2 cd odroidu2/ # Get the example files wget http://odroid.us/odroid/users/osterluk/qemu-example/qemu-example.tgz tar -xvf qemu-example.tgz
Here are the files we now have:
Check for any Existing Qemu
See if you already have qemu installed:
QEMU PC emulator version 0.12.5 (Debian 0.12.5+dfsg-3squeeze1), Copyright (c) 2003-2008 Fabrice Bellard
See if the cortex-a9 is supported:
qemu-system-arm -cpu ? | grep cortex-a9
OK, we at least have the required CPU. Now check the machine type:
qemu-system-arm -M ? | grep vexpress-a9
On newer releases, there may be a new-enough qemu. I see v2.1.2 is current on Debian Jessie
sudo apt-get install qemu
Did not find a match, we need a newer build of qemu -- and we need to build it from source. See the next section.
First, we need to install some dependant packages
sudo apt-get install libpixman-1-dev zlib1g-dev libglib2.0-dev shtool build-essential
Get the qemu source
Download the source and expand it:
cd $HOME mkdir qemu-build cd qemu-build # note: qemu-2.5.0 is available, but not yet tested for this example wget http://wiki.qemu-project.org/download/qemu-1.4.0.tar.bz2 tar -xvf qemu-1.4.0.tar
Configure and Build
Now configure qemu and build it. If you use the Debian6t VMWare Virtual Machine, you need to allocate 2GB or so of memory. The build will fail otherwise. The default of 384MB and 1GB failed each for me.
Note: If you just want to have qemu-arm-static, so you can run individual ARM binaries or to bootstrap Debian, then you can build a subset of the whole package.
Build statically-linked qemu-arm package like this:
cd $HOME/qemu-build/qemu-1.4.0 ./configure --prefix=/usr/local --static --disable-kvm --target-list=arm-linux-user make sudo make install
See where the qemu-arm binary was installed to: (I see it in /usr/local/bin)
Rename the file to denote that it is statically linked:
# adjust the path depending on where your system installed the qemu-arm binary sudo mv /usr/local/bin/qemu-arm /usr/local/bin/qemu-arm-static
If you are working through this tutorial just to get qemu-arm-static, you can stop now as the remaining sections have to do with emulating a whole ARM system.
Build again to get a dynamically linked qemu-system-arm, the full-system ARM emulator.
cd $HOME/qemu-build/qemu-1.4.0 ./configure --enable-system --prefix=/usr/local --disable-kvm --target-list=arm-linux-user make sudo make install
Check the version to see if we are properly installed:
qemu-1.4.0$ qemu-system-arm --version
QEMU emulator version 1.4.0, Copyright (c) 2003-2008 Fabrice Bellard
OK. Make sure our machine is included:
qemu-system-arm -M ? | grep vexpress
vexpress-a9 ARM Versatile Express for Cortex-A9 vexpress-a15 ARM Versatile Express for Cortex-A15
Nice. There <could> be a machine built for odroid, but so far I haven't heard of one. There is a project going on to build a machine for Rasperry Pi that can run unmodified kernels.
We are done with the build files. They can be deleted.
Create Root File System Partition Image
Yes, there is a distinction between a partition image and a tarball of the partition contents. The kernel will want to mount a filesystem. It doesn't know how to mount just a tarball.
All we need is a small amount of space to hold the buildroot/busybox root file system. 200M is OK. You can change this as needed, of course.
cd $HOME/odroidu2 qemu-img create rootfs-buildroot.ext2 200M
Formating 'rootfs-buildroot.ext2', fmt=raw, size=204800 kB
sudo mkfs.ext2 rootfs-buildroot.ext2
mke2fs 1.41.12 (17-May-2010) rootfs-buildroot.ext2 is not a block special device. Proceed anyway? (y,n) y Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) Stride=0 blocks, Stripe width=0 blocks 51200 inodes, 204800 blocks 10240 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=67371008 25 block groups 8192 blocks per group, 8192 fragments per group 2048 inodes per group Superblock backups stored on blocks: 8193, 24577, 40961, 57345, 73729 Writing inode tables: done Writing superblocks and filesystem accounting information: done
Now loop mount the partition image file
mkdir mnt sudo mount -o loop rootfs-buildroot.ext2 mnt
And expand the root file system image tarball into it
cd mnt sudo tar -xvzf ../rootfs.tar.gz # take a look around, if you like ls cd ../ sudo umount ./mnt
Now try the simplest thing. Launch without setting up a network bridge. Here is a simple script to make things easier:
#! /bin/sh # filename: launch-no-bridge # Set environment variables to make it easier to change export ROOTFS=rootfs-buildroot.ext2 export NETWORK="-net nic -net user" export KERNEL="-kernel zImage " qemu-system-arm -append "root=/dev/mmcblk0 rw physmap.enabled=0 console=ttyAMA0" -M vexpress-a9 $KERNEL -sd $ROOTFS $NETWORK -nographic
Launch it like this:
It looks just like a normal boot. The username is root, no password.
Sorry, but the tutorial is rough from here on. I have other things I should be working on...
If you play with your network settings, be prepared to loose internet connectivity -- you may have to restart networking to get back on the net. A better approach may be to bridge a second network interface to the tap for qemu target. At least you would keep your primary network connection.
The qemu-1.4 "bridge-helper" <should> work, but I'm just stuck finding the right incantations... I used a manual networking setup method.
The command line options will work if you get your host network set up properly. It takes some fiddling. Sorry. (I could use some help here)
This link might help you with the general concepts: http://www.microhowto.info/howto/persistently_bridge_traffic_between_two_or_more_ethernet_interfaces_on_debian.html
I used this on my Mint Maya host:
# This is a here-file, copy and paste into terminal window to create the file cat << EOF >/etc/network/interfacesbridge auto lo iface lo inet loopback auto br0 iface br0 inet dhcp bridge_ports eth0 tap0 bridge_stp off EOF
We need the tunctl and brctl utilities to set up a network bridge to the emulated target
sudo apt-get install uml-utilities bridge-utils
We need some modules loaded
sudo modprobe bridge tun
Or if you like, you can add bridge and tun to /etc/modules
# /etc/modules: kernel modules to load at boot time. # # This file contains the names of kernel modules that should be loaded # at boot time, one per line. Lines beginning with "#" are ignored. lp rtc bridge tun
Create a persistent tunnel, with permissions so you qemu can access it as you start the session
sudo tunctl -u $UID -t tap0
This step will cause the network connection to be dropped. Something to note if you are not on the serial console Add the bridge, and set it up:
sudo brctl addbr br0 sudo ifconfig eth0 0.0.0.0 promisc up sudo brctl addif br0 eth0 sudo brctl addif br0 tap0 sudo dhclient br0 #iptables -F FORWARD
Networking cannot possibly work until the host is set up correctly. Show the bridge configuration. You should see eth0 and tap0 in the bridge. Your indices may be different. I hope this is reasonably clear.
sudo brctl show
bridge name bridge id STP enabled interfaces br0 8000.90e6ba5ccfbf no eth0 tap0
#! /bin/sh # filename: launch # Set environment variables to make it easier to change ROOTFS=rootfs-buildroot.ext2 NETWORK="-net nic,vlan=0 -net tap,vlan=0,ifname=tap0,script=no" KERNEL="-kernel zImage " qemu-system-arm -append "root=/dev/mmcblk0 rw physmap.enabled=0 console=ttyAMA0" -M vexpress-a9 $KERNEL -sd $ROOTFS $NETWORK -nographic
Now you can use udhcpc to bring up the network.
Launching on Ubuntu
You can run the Hardkernel Ubuntu images with this qemu -- Graphics is not going to work, without additional effort. First you need a partition image. If you have one already, good. I'm not talking about an SD Card image -- that would be a disk image with two partitions and other stuff.
You can pull out the rootfs data from the SD-Card image by following these steps: How_to_Mount_SD-Card_Image_to_Extract_Root_File_System
Once you have it rename it to rootfs-ubuntu.ext4 and put it in the same directory as the example files.
Here is the launch-ubuntu script:
#! /bin/sh # filename launch-ubuntu # Set environment variables to make it easier to change ROOTFS=rootfs-ubuntu.ext4 NETWORK="-net nic,vlan=0 -net tap,vlan=0,ifname=tap0,script=no" #NETWORK="-net nic -net user" KERNEL="-kernel zImage " qemu-system-arm -append "root=/dev/mmcblk0 rw physmap.enabled=0 console=ttyAMA0" -M vexpress-a9 $KERNEL -sd $ROOTFS $NETWORK -serial stdio
Do ./launch-ubuntu to bring it up. It will boot with some complaints, but you can fix them by editing /etc/fstab from
# UNCONFIGURED FSTAB FOR BASE SYSTEM UUID=e139ce78-9841-40fe-8823-96a304a09859 / ext4 errors=remount-ro,noatime 0 1 /dev/mmcblk0p1 /media/boot vfat defaults 0 1
# UNCONFIGURED FSTAB FOR BASE SYSTEM /dev/mmcblk0 / ext4 errors=remount-ro,noatime 0 1
Someone who knows the graphics subsystem, could actually get the graphics mode working. Rasberry Pi can do it.
The kernel source I used was linux-3.2.0, right from kernel.org. I included the configuration I used as vexpress_odroid_qemu_defconfig. There is probably some graphics stuff that needs to be included.
There is probably a qemu-system-arm command line option to be figured out as well.I actually see some characters come up in the graphics window, but the fonts are odd and the text disappears