Using qemu syscall emulation with Debian. ----------------------------------------- Bill Allombert version 0.2, 20 avril 2006 ------------------------------------------------------------------------------- Copyright Notice ---------------- Copyright (C)2006 Bill Allombert. This manual is free software; you may redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This is distributed in the hope that it will be useful, but _without any warranty_; without even the implied warranty of merchantability or fitness for a particular purpose. See the GNU General Public License for more details. A copy of the GNU General Public License is available as `/usr/share/common-licenses/GPL' in the Debian GNU/Linux distribution or on the World Wide Web at `http://www.gnu.org/copyleft/gpl.html'. You can also obtain it by writing to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ------------------------------------------------------------------------------- Contents -------- 1. Introduction 2. Software versions used 3. Setting up an environment 3.1. Prerequisite 3.2. Using debootstrap 3.3. Using cdebootstrap 3.4. Testing your qemu installation 4. Going further 4.1. Trouble-shooting 4.2. Installing extra packages ------------------------------------------------------------------------------- 1. Introduction --------------- Qemu is a emulator that can be used as a virtual machine or a syscall emulator. Here I will only be concerned with the syscall emulator mode. I will also restrict myself to the use of the unstable Debian packages of qemu to run softwares provided in Debian packages. I will also not use root priviledge even when they would make things a bit easier, for security reason. Syscall emulation is very different from a virtual machine: syscall are executed by qemu without mangling. This can be sometime surprising: if you emulate a binary that perform the syscall `exec("/bin/ls")', qemu will `exec("/bin/ls")' which will cause the qemu process to be replaced with the native ls code (and not an emulated one). Also hard-coded path in binaries might not point where you want. On the other access to device is not limited by the emulation, in particular network access does not need any set up. The Debian package includes several qemu binaries for syscall emulation. I tested qemu-arm, qemu-ppc, qemu-sparc and qemu-mips. After testing on a x86, it appears that qemu-arm works the best, the others being very limited. Apparently there are architecture-dependent syscalls that are difficult to emulate. Also qemu is only able to emulate a limited number of syscalls. ------------------------------------------------------------------------------- 2. Software versions used ------------------------- The version of the qemu Debian package used was 0.8.0-3. The version 0.8.0-2 does not work well. The version of debootstrap used was 0.3.3 The version of apt was 0.6.43.3 ------------------------------------------------------------------------------- 3. Setting up an environment ---------------------------- 3.1. Prerequisite ----------------- To setup the environment the way I describe, you will need a directory with around 150Mb of free space. However, once you are more experienced with the process you can use much less disk space. On my box, this directory is `/scratch/qemu'. I install a arm environment in `/scratch/qemu/ARM' by running the command below in the `/scratch/qemu' directory. I use the mirrror http://ftp.fr.debian.org/debian. Be sure to pick a mirror that include arm binaries (If you do not specify a mirror, it will use http://ftp.debian.org/debian which do not include the arm binaries) To bootstrap the environment, you can use either `debootstrap' or `cdebootstrap', they are very similar. 3.2. Using debootstrap ---------------------- The command is fakeroot /usr/sbin/debootstrap --arch arm sid ARM http://ftp.fr.debian.org/debian This will download arm debs and unpack them. This should fail with W: Failure trying to run: chroot /scratch/qemu/ARM mount -t proc proc /proc because you are not root. (If you are root this will fail anyway since you cannot execute the binaries). Now, finish to unpack the debs for pkg in ARM/var/cache/apt/archives/*.deb; do \ echo "Extracting $pkg..."; dpkg-deb -x $pkg ARM; done 3.3. Using cdebootstrap ----------------------- The command is fakeroot cdebootstrap --flavour=standard --arch arm sid ARM http://ftp.fr.debian.org/debian This will download arm debs and unpack them. This should fail with E: can't mount proc because you are not root. (If you are root this will fail anyway since you cannot execute the binaries). Now, finish to unpack the debs for pkg in ARM/var/cache/bootstrap/*.deb; do \ echo "Extracting $pkg..."; dpkg-deb -x $pkg ARM; done 3.4. Testing your qemu installation ----------------------------------- Now you can try qemu with qemu-arm -L /scratch/qemu/ARM ARM/bin/ls The `-L' option cause qemu to use an alternative root for finding the dynamic loader and the C library. It requires an absolute pathname. You can also try qemu-arm -L /scratch/qemu/ARM ARM/bin/sh Programs you launch from that shell will be native programs unless you run them through qemu-arm itself. You can check network access with qemu-arm -L /scratch/qemu/ARM ARM/usr/bin/wget www.debian.org ------------------------------------------------------------------------------- 4. Going further ---------------- 4.1. Trouble-shooting --------------------- If qemu-arm fails mysteriously, try to run it under strace. It might tell you if it looks for a file in the wrong place. Note that qemu-arm will not run scripts. This is not really a limitation since script have a hard-coded path to the interpretor which will point to the native version. Current qemu really does not like symlink to directories in the directory pointed by -L. 4.2. Installing extra packages ------------------------------ If you want to install more packages, you can download them with this variant of debget (that I will call debget-arm). #!/bin/bash -e for pkgspec in $*; do version=$(apt-get -q2 -s --reinstall install "$pkgspec" | grep ^Inst | sed -ne '$s/^.*\[\(.*\)\].*$/\1/p') echo "($pkgspec -> $version)" aptdata=$(apt-get -q2 --print-uris --reinstall install "$pkgspec" | tail -1|sed -e "s/_i386\.deb/_arm\.deb/g") url=$(echo "$aptdata" | sed -e "s/^'\([^']*\)'.*$/\1/") file=$(echo "$aptdata" | sed -e "s/^'[^']*' \([^ ]*\).*$/\1/") curl "$url" > "$file" done This script assumes your first apt source is a Debian archive that includes the arm architecture and the packages are in sync on arm. As an example I will try to get pari-gp running: I run mkdir debs; cd debs; ../debget-arm libpari1 libx11-6 libxau6 libxdmcp6 libreadline5 pari-gp cd .. for pkg in debs/*.deb; do \ echo "Extracting $pkg..."; dpkg-deb -x $pkg ARM; done Now, you can try qemu-arm -L /scratch/qemu/ARM/ ARM/usr/bin/gp Reading GPRC: /home/bill/.gprc ...Done. GP/PARI CALCULATOR Version 2.1.7 (released) arm running linux (C portable kernel) 32-bit version (readline v5.0 enabled, extended help available) As a comparaison of performance, runs the PARI/GP benchmark in 17246ms. An Athlon 1800+ running qemu-arm run the benchmark in 13186ms. The native binary run in 1070ms. ------------------------------------------------------------------------------- Using qemu syscall emulation with Debian. Bill Allombert version 0.2, 20 avril 2006