Using qemu syscall emulation with Debian. ----------------------------------------- Bill Allombert version 0.0, 1 mars 2005 ------------------------------------------------------------------------------- Copyright Notice ---------------- Copyright (C)2005 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. Setting up an environment 3. Going further 3.1. Trouble-shooting 3.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 include three qemu binaries for syscall emulation. qemu-arm, qemu-ppc and qemu-sparc. After testing on a x86, it appears that qemu-arm work the best, qemu-ppc has some issues and qemu-sparc is 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. Setting up an environment ---------------------------- 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. fakeroot /usr/sbin/debootstrap --arch arm sid ARM This will download arm debs and unpack them. This should fail with /usr/lib/debootstrap/functions: line 524: chroot: command not found 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 since you cannot use chroot(2), all hard-coded paths to binaries you have installed might be a problem. In particular, edit the file `ARM/lib/ld-linux.so.2' to replace the string to something that does not exists like . Be careful to not change the length of the string, else the offset will be wrong and the ELF file will be invalid. 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. You can also try qemu-arm -L /scratch/qemu/ARM ARM/bin/sh Programs you launch from that shell will be native program 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 ------------------------------------------------------------------------------- 3. Going further ---------------- 3.1. Trouble-shooting --------------------- If qemu-arm fails mysteriously, try to run it under strace. It might tell you if it look 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. 3.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") echo $aptdata url=$(echo "$aptdata" | sed -e "s/^'\([^']*\)'.*$/\1/") file=$(echo "$aptdata" | sed -e "s/^'[^']*' \([^ ]*\).*$/\1/") echo $url echo $file curl "$url" > "$file" done This script assume your first apt source is a Debian archive that include 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 libreadline4 pari-gp cd .. for pkg in debs/*; do \ echo "Extracting $pkg..."; dpkg-deb -x $pkg ARM; done To access libraries in ARM/usr/X11R6/lib, you need to change your `LD_LIBRARY_PATH' variable: export LD_LIBRARY_PATH=/scratch/qemu/ARM/usr/X11R6/lib Now, you can try qemu-arm -L /scratch/qemu/ARM ARM/usr/bin/gp GP/PARI CALCULATOR Version 2.1.6 (released) arm running linux (C portable kernel) 32-bit version As a comparaison of performance, runs the PARI/GP benchmark in 17246ms. A Athlon 1800+ running qemu-arm run the benchmark in 14730ms. The native binary run in 1340ms. ------------------------------------------------------------------------------- Using qemu syscall emulation with Debian. Bill Allombert version 0.0, 1 mars 2005