Skip to content
twpedersen edited this page May 3, 2013 · 8 revisions

Overview

Image(wiki:[[QemuAsDevelTarget:sae-qemu-devel.png)]]

Booting a kernel in qemu

1. Install qemu


 apt-get install qemu

2. Create a loop device that will become your target's rootfs


dd if=/dev/zero of=rootfs.img bs=1024 count=1048576
losetup /dev/loop0 rootfs.img
mkfs -t ext3 -m 1 -v /dev/loop0
mkdir /mnt/qemu-rootfs
mount -t ext3 /dev/loop0 /mnt/qemu-rootfs

Don't worry if you don't know what size to choose. If the suggested 1GB is not sufficient you can always ResizeYourQemuImage.

3. Install debian on it


sudo debootstrap sid /mnt/qemu-rootfs http://ftp.debian.org/debian

3.1 Install useful packages


chroot /mnt/qemu-rootfs /bin/bash
apt-get install iw vim sudo make gcc sshfs libnl2 tcpdump

4. Configure a couple of time saving tricks (on target):

4.1 autologin as root via serial console (i.e. the terminal console from which you invoke qemu):

Remove password from root account:

/etc/shadow


- root:x:14483:0:99999:7:::
+ root::14483:0:99999:7:::

Enable serial console with auto login

/etc/inittab


- #T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
+ T0:23:respawn:/sbin/getty -n -l /bin/autologin.sh -L ttyS0 38400 linux

Create /bin/autologin.sh as:


#!/bin/sh
exec /bin/login -f root

And make it executable


chmod 700 /bin/autologin.sh

5. Compile a wireless-testing kernel


git clone \
 git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing
cd wireless-testing
make defconfig
# For mesh development you want to edit your .config and enable
# CONFIG_MAC80211_MESH=y
# CONFIG_MAC80211_HWSIM=m
#
# and maybe some debugging
# CONFIG_CFG80211_DEBUGFS=y
# CONFIG_MAC80211_DEBUGFS=y
# CONFIG_MAC80211_DEBUG_MENU=y
# CONFIG_MAC80211_VERBOSE_MPL_DEBUG=y
# CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG=y
#
# for sshfs support, enable
# CONFIG_FUSE_FS=y
make -j 2

6. Copy kernel modules to your rootfs


INSTALL_MOD_PATH=/mnt/qemu-rootfs make modules_install

From time to time you'll have to install new modules, etc. This is a useful convenience script for that:


LOOPDEV=/dev/loop0
MNTPOINT=/mnt/qemu-rootfs

sudo losetup $LOOPDEV || sudo losetup /dev/loop0 /path/to/your/rootfs.img
sudo killall qemu
sudo mount -t ext3 $LOOPDEV $MNTPOINT
sudo INSTALL_MOD_PATH=$MNTPOINT make modules_install
sudo umount $MNTPOINT

7. Unmount your rootfs


umount /mnt/qemu-rootfs

8. Launch qemu


qemu -kernel arch/i386/boot/bzImage \
  -hda rootfs.img \
  -append "root=/dev/sda console=ttyS0" -nographic

You should be greeted by a login prompt:


Debian GNU/Linux 6.0 phooey ttyS0

phooey login: 

9. Setup networking between guest and host

"is a bit convoluted but avoids running qemu as root. Also, throughout the rest of the doc, the host's tap interface address will be assumed to be 192.168.55.1 and the guest address 192.168.55.2":/cozybit/open80211s/wiki/This

On your host edit the following:

/etc/qemu-ifup:


#!/bin/sh

/sbin/ifconfig $1 192.168.55.1 up

/etc/qemu-ifdown:


# leave this blank.  We'll do the cleanup in our wrapper script

And create this wrapper script to invoke qemu


#! /bin/bash

IFNAME=`sudo tunctl -u javier -b`
sudo /etc/qemu-ifup $IFNAME
qemu -kernel ~/dev/wireless-testing/arch/i386/boot/bzImage  \
  -hda ~/qemu/rootfs.img \
  -append "root=/dev/sda combined_mode=ide console=ttyS0" \
  -nographic -net nic,model=e1000 \
  -net tap,ifname=$IFNAME,script=no
tunctl -d $IFNAME

To get tunctl, install the user mode linux utilities package:


sudo apt-get install uml-utilities

On your guest edit the following:

/etc/network/interfaces


auto eth0
iface eth0 inet static
 address 192.168.55.2
 netmask 255.255.255.0

remove udev net rules, we'll be using one interface per guest:


rm /etc/udev/rules.d/70-persistent-net.rules

Now boot and you should be able to ping from guest to host and vice versa.

10. Set up sshfs

Generate a passphrase-less private key on guest and copy public key to host to automate login. Could be pretier, but adding the line below to /etc/rc.local on guest works.


sshfs -o allow_other -o idmap=user [email protected]:/path/to/remote/dir \
  /local/mount/point

virtfs as root

It is also possible to mount external directories from within qemu using virtio. The full instructions can be found here, but here is a brief overview.

The distro11s qemu config already has the correct kernel config settings. You will probably have to build qemu with virtio support which is automatically enabled if you run configure with libattr1-dev installed. USB pass-through is a nice feature to have, and you might as well enable it now. The newest libusb can be found at http://libusbx.org/.

NOTE: you can also try installing your distribution's qemu source package. The rebuild then shouldn't require a new libusb-1.0-dev.

rebuilding qemu

  1. uninstall any existing qemu package
  2. git clone http://git.qemu.org/git/qemu.git
  3. cd qemu && /configure '--enable-libusb' '--target-list=x86_64-softmmu' '--enable-debug' '--enable-kvm'
  4. make && sudo make install

mounting virtfs target as root

This could be useful for launching multiple qemu instances using the same rootfs, and there is no need to rebuild the rootfs image after every change. However, in a benchmark involving boot and running 10 hwsim tests, the current ext3fs img approach was over 2x faster in both cases, so this is still the default.

# virtfs rootfs
       -append "root=root rw rootflags=rw,trans=virtio,version=9p2000.L rootfstype=9p combined_mode=ide console=ttyS0" \
       -fsdev local,id=root,path=${STAGING},security_model=none \
       -device virtio-9p-pci,fsdev=root,mount_tag=/dev/root \

Bob Copeland suggested a compromise, where the rootfs would still be contained in a filesystem image, but the module and hwsim test paths would be virtfs mounts. We can then do away with the SSHFS_AUTOMOUNT complexity currently needed for accessing the hwsim tests.

# selective virtfs mounts
        -fsdev local,id=modules,path=${STAGING}/lib/modules,security_model=mapped-xattr \
        -fsdev local,id=home,path=/home,security_model=mapped-xattr \
        -device virtio-9p-pci,fsdev=modules,mount_tag=modules \
        -device virtio-9p-pci,fsdev=home,mount_tag=home \

Then in the rootfs image, you have to enter the right fstab parameters:


home	/home	9p	trans=virtio,version=9p2000.L 0	0
modules /lib/modules 9p trans=virtio,version=9p2000.L 0 0

This is now the default.

We could take this further and have a separate external /cozy_usr as the installation target for any custom packages such as iw, authsae, etc. and then mount this to /usr inside qemu.

Differences with MacOS/FreeBSD

  1. losetup does not exist. just create the filesystem and double-click to mount it

  2. sudo port install e2fsprogs to get mkfs

TODO: Finish this section

More Tasks

QemuKernelDebug

Troubleshooting

Can't enable kernel virtualization (on Thinkpad T400)

Symptom: In dmesg, kvm: disabled by bios

Solution: enable VT and VT-d in CPU page of bios, then power cycle your machine.

Disk Write errors

Symptom:


[   37.498636] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0

Solution: Make sure rootfs.img has the appropriate readwrite permissions, duh

udev can't write to /run


/etc/init.d/udev: 1: cannot create /run/udev//root-link-rule: Read-only file system

That also causes other failures like no serial console.
Deleting /run on your guest filesystem did the trick.

udev spawns too many net.agents which never exit, slowing down my qemu

we don't need them anyway, edit /lib/udev/net.agent like so:



-        ppp*|ippp*|isdn*|plip*|lo|irda*|ipsec*)
+        ppp*|ippp*|isdn*|plip*|lo|irda*|ipsec*|mesh*)

to disable spawning of net.agents for mesh interfaces. If the net.agents still persist after that edit, add 'exit 1' near the beginning of /lib/udev/net.agent:



         ./lib/udev/hotplug.functions

+        exit 1

         if [ -z "$INTERFACE" ]; then

Links

http://www.cryptosystem.org/archives/2005/03/kernel-development-with-qemu http://www.coreboot.org/QEMU_Build_Tutorial#Creating_a_hard_disk_image http://www.walkernews.net/2007/07/01/create-linux-loopback-file-system-on-disk-file/

Clone this wiki locally