Qemu

Network settings

First, create a bridge device. Edit the script bridge.sh:

#!/usr/bin/ksh

# Configure a bridge device to use with qemu

# Bridged interface
if=eth0

# Bridge name
bridge=br0

# Bridge network
address=192.168.1.7
netmask=255.255.255.0
gateway=192.168.1.1
broadcast=192.168.1.255

case $1 in
  start)
    print "Configure $bridge bridge..."
    brctl addbr $bridge

    print "Add $if on $bridge..."
    brctl addif $bridge $if

    print "Activating promiscuous mode on $if..."
    ip addr flush dev $if
    ip link set $if promisc on
    ip link set up dev $if

    print "IP address on $bridge..."
    ip addr add $address/$netmask broadcast $broadcast dev $bridge 
    ip link set $bridge up

    print "Set default route..."
    ip route add default via $gateway
  ;;
  stop)
    ip link set $bridge down
    brctl delbr $bridge
    ip addr flush dev $if
    ip link set $if promisc off
    ip link set down dev $if
  ;;
  *)
    print -u2 "usage: $0 start|stop"
    exit 1
  ;;
esac

exit 0
        

Run the script to create the bridge:

./bridge.sh start

Then, edit the script that will add the qemu tap device on the bridge (/etc/qemu-ifup):

#!/usr/bin/ksh

tap=$1

bridge=br0

# put the $tap interface up
ip link set up dev $tap

# adding $tap to bridge interface $bridge...
brctl addif $bridge $tap

exit 0
        

You can now run qemu with tap network interfaces.

Running Qemu to test a new kernel

This is the command to launch Qemu with the previous kernel on a x86_64 plateform with a vnc output:

qemu-system-x86_64                                      \
  -snapshot                                             \
  -curses                                               \
  -no-kqemu                                             \
  -hda /dev/sda                                         \
  -kernel /usr/src/linux-2.6.26.5/arch/x86/boot/bzImage \
  -append "root=/dev/hda1"                              \
  -vnc www.gnuwakes.org:0

Explanation:

-snapshot
           Write to temporary files instead of disk image files. In this case,
           the raw disk image you use is not written back.

-hda file
-hdb file
-hdc file
-hdd file
           Use file as hard disk 0, 1, 2 or 3 image.

-vnc d
           Normally, QEMU uses SDL to display the VGA output.  With this
           option, you can have QEMU listen on VNC display d and redirect the
           VGA display over the VNC session.

-kernel bzImage
           Use bzImage as kernel image.

-append cmdline
           Use cmdline as kernel command line
           "root=/dev/hda1" ==> /dev/sda1 (if physical disk is SATA)

-initrd file
           Use file as initial ram disk.
          

To launch Qemu on an x86 compatible architecture without kqemu, on a physical disk image with the newly compiled kernel:

qemu                                                    \
  -no-kqemu                                             \
  -hda /dev/sda                                         \
  -kernel /usr/src/linux-2.6.26.5/arch/x86/boot/bzImage \
  -append "root=/dev/hda1"
          

Pay attention to the file /etc/fstab when trying to boot on a physical partition. The root device with Qemu is always an hda device (ie /dev/hda1), but on your machine it can be something else, like /dev/sda1. Example of /etc/fstab when booting your physical machine:

# cat /etc/fstab
/dev/sda1     /        ext3    errors=remount-ro    0    1
proc          /proc    proc    defaults             0    0
sysfs         /sys     sysfs   defaults             0    0
          

When booting with Qemu, it must seem like this:

# cat /etc/fstab
/dev/hda1     /        ext3    errors=remount-ro    0    1
proc          /proc    proc    defaults             0    0
sysfs         /sys     sysfs   defaults             0    0
          

Running VM as deamon with VNC

To run Qemu with a bridged network and VNC, run:

#!/usr/bin/ksh

root=/wakes/vm

image=$root/devlab.img

pidfile=$root/devlab.pid

memory=128

tap=tap1

vnc=1

mac=52:54:00:12:34:58

case $1 in
  start)
    # with tun/tap network
    /usr/local/bin/qemu -daemonize -M pc -m $memory -hda $image \
      -pidfile $pidfile -net nic,vlan=0,macaddr=$mac \
      -net tap,vlan=0,ifname=$tap,script=/etc/qemu-ifup \
      -boot c -vnc :$vnc -localtime -k fr
  ;;
  stop)
    kill $(cat $pidfile)
    rm $pidfile
  ;;
  console)
    vncviewer :$vnc
  ;;
  install)
    /usr/local/bin/qemu -M pc -m $memory -hda $image -localtime \
      -net nic,vlan=0,macaddr=$mac \
      -net tap,vlan=0,ifname=$tap,script=/etc/qemu-ifup \
      -boot d -cdrom /wakes/iso/wakes.iso -vnc :$vnc -k fr
  ;;
esac

exit 0

          

Running VMs with TAP network

And without VNC:

#!/usr/bin/ksh

root=$(cd $(dirname $(readlink -f $0))/..; pwd)

vm_name=$(basename $0 .sh)

img=$root/vmdisk/$vm_name.img

pidfile=$root/vmdisk/$vm_name.pid

qemu=/usr/kvm/bin/qemu-system-x86_64

mac=$(print $vm_name | md5sum | \
  sed 's/^\(..\)\(..\)\(..\)\(..\).*$/52:54:\1:\2:\3:\4/')

[ ! -f "$img" ] && qemu-img create $img 10G

case $1 in
  install)
    $qemu -boot d -hda $img \
      -cdrom $root/iso/wakes-alpha1-001-i386.iso
  ;;
  start)
    $qemu -boot c -hda $img -pidfile $pidfile \
      -net nic,vlan=0,macaddr=$mac \
      -net tap,vlan=0,ifname=$vm_name,script=/etc/qemu-ifup 
  ;;
  stop)
    kill $(cat $pidfile)
    rm $pidfile
  ;;
  *)
    print -u2 "usage: $0 install|start|stop"
    exit 1
  ;;
esac

exit 0

        

Running Qemu with ncurses library

Comment out the following lines in /scripts/init-top/console_setup in initrd:

if [ -f /etc/console-setup/boottime.kmap.gz ] && type loadkeys >/dev/null; then
       eval loadkeys /etc/console-setup/boottime.kmap.gz $verbose
fi

Ultimate Qemu script with VIRTIO

#!/usr/bin/ksh

root=$(cd $(dirname $(readlink -f $0))/..; pwd)

wakes=/windows/perso/wakes

mem=512

vm_name=$(basename $0 .sh)

img=$wakes/vmdisk/$vm_name.img

pidfile=$wakes/vmdisk/$vm_name.pid

qemu=/usr/kvm/bin/qemu-system-x86_64

cdrom=$wakes/iso/wakes-full-alpha1-???-i386.iso

mac=$(print $vm_name | md5sum | \
  sed 's/^\(..\)\(..\)\(..\)\(..\).*$/52:54:\1:\2:\3:\4/')

[ ! -f "$img" ] && qemu-img create $img 10G

case $1 in
  install)
    $qemu -name $vm_name -boot once=d -hda $img -cdrom $cdrom
  ;;
  start)
    $qemu -name $vm_name -boot c -hda $img -pidfile $pidfile -cdrom $cdrom \
      -net nic,vlan=0,macaddr=$mac -m $mem -vga vmware -k fr \
      -net tap,vlan=0,ifname=$vm_name,script=/etc/qemu-ifup 
  ;;
  stop)
    kill $(cat $pidfile)
    rm $pidfile
  ;;
  ssh)
    xterm -T $vm_name -bg black -fg green -e \
      ssh -Y -o StrictHostKeyChecking=no $vm_name 2> /dev/null &
  ;;
  ncurses_start)
    xterm -geometry 80x25 -title "$vm_name console" -e \
      $qemu -name $vm_name -boot c \
      -drive file=$img,if=virtio,index=0,media=disk,boot=on \
      -pidfile $pidfile -cdrom $cdrom \
      -net nic,vlan=0,macaddr=$mac,model=virtio -m $mem -vga vmware -curses \
      -net tap,vlan=0,ifname=$vm_name,script=/etc/qemu-ifup 2> /dev/null &
  ;;
  failsafe)
    xterm -geometry 80x25 -title "$vm_name console" -e \
      $qemu -name $vm_name -boot c \
      -drive file=$img,if=virtio,index=0,media=disk,boot=on \
      -pidfile $pidfile -cdrom $cdrom \
      -kernel /boot/vmlinuz-failsafe -initrd /boot/initrd-failsafe \
      -append "root=/dev/mapper/rootvg-lvol0" \
      -net nic,vlan=0,macaddr=$mac,model=virtio -m $mem -vga vmware -curses \
      -net tap,vlan=0,ifname=$vm_name,script=/etc/qemu-ifup 2> /dev/null &
  ;;
  *)
    print -u2 "usage: $0 install|start|stop|ncurses_start|ssh"
    exit 1
  ;;
esac

exit 0

Kernel configuration

First, create the allno.config file. This file will be used to compile a Qemu compatible kernel.

cat << EOF > allno.config
# allno.config

CONFIG_BINFMT_ELF=y
CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y
CONFIG_HAVE_IDE=y
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDE_GENERIC=y
CONFIG_VIDEO_SELECT=y
CONFIG_EXT3_FS=y
CONFIG_MPENTIUMII=y
CONFIG_SYSVIPC=y
CONFIG_TMPFS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_NET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_PACKET=y
CONFIG_NETDEVICES=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_MROUTE=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
CONFIG_UDF_FS=y
CONFIG_UDF_NLS=y
CONFIG_BLK_DEV_IDECD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
EOF
          

Then compile the kernel.

make mrproper
make allnoconfig
make 
          

Explanation:

        "make config"      Plain text interface.
        "make menuconfig"  Text based color menus, radiolists & dialogs.
        "make xconfig"     X windows (Qt) based configuration tool.
        "make gconfig"     X windows (Gtk) based configuration tool.
        "make oldconfig"   Default all questions based on the contents of
                           your existing ./.config file and asking about
                           new config symbols.
        "make silentoldconfig"
                           Like above, but avoids cluttering the screen
                           with questions already answered.
        "make defconfig"   Create a ./.config file by using the default
                           symbol values from arch/$ARCH/defconfig.
        "make allyesconfig"
                           Create a ./.config file by setting symbol
                           values to 'y' as much as possible.
        "make allmodconfig"
                           Create a ./.config file by setting symbol
                           values to 'm' as much as possible.
        "make allnoconfig" Create a ./.config file by setting symbol
                           values to 'n' as much as possible.
        "make randconfig"  Create a ./.config file by setting symbol
                           values to random values.

   The allyesconfig/allmodconfig/allnoconfig/randconfig variants can
   also use the environment variable KCONFIG_ALLCONFIG to specify a
   filename that contains config options that the user requires to be
   set to a specific value.  If KCONFIG_ALLCONFIG=filename is not used,
   "make *config" checks for a file named "all{yes/mod/no/random}.config"
   for symbol values that are to be forced.  If this file is not found,
   it checks for a file named "all.config" to contain forced values.
          

In our case, the make allnoconfig variants will check for the file allno.config for symbol values that are to be forced (if the environment variable KCONFIG_ALLCONFIG is not used).

kernel allno.config with sda disk support:

########################################
# Executable file formats / Emulations #
########################################

# Kernel support for ELF binaries
CONFIG_BINFMT_ELF=y

################
# File systems #
################

# Ext3 journalling file system support
CONFIG_EXT3_FS=y

# /proc file system support
CONFIG_PROC_FS=y

# Virtual memory file system support (former shm fs)
CONFIG_TMPFS=y

# Inotify file change notification support
CONFIG_INOTIFY=y

# Inotify support for userspace
CONFIG_INOTIFY_USER=y

# ISO 9660 CDROM file system support
CONFIG_ISO9660_FS=y

###############################
# Processor type and features #
###############################

# Pentium-II/Celeron(pre-Coppermine)
CONFIG_MPENTIUMII=y

# Paravirtualized guest support
CONFIG_PARAVIRT_GUEST=y
# KVM Guest support
CONFIG_KVM_GUEST=y
# KVM paravirtualized clock
CONFIG_KVM_CLOCK=y

#################
# General setup #
#################

# Prompt for development and/or incomplete code/drivers
CONFIG_EXPERIMENTAL=y

# System V IPC
CONFIG_SYSVIPC=y

# Initial RAM filesystem and RAM disk (initramfs/initrd) support
CONFIG_BLK_DEV_INITRD=y

# Optimize for size
CONFIG_CC_OPTIMIZE_FOR_SIZE=y

# Kernel .config support
CONFIG_IKCONFIG=y

# Enable access to .config through /proc/config.gz
CONFIG_IKCONFIG_PROC=y

##########################
# Enable the block layer #
##########################

# Enable the block layer
CONFIG_BLOCK=y

# Deadline I/O scheduler
CONFIG_IOSCHED_DEADLINE=y

######################
# Networking support #
######################

# Networking support
CONFIG_NET=y
# Packet socket
#CONFIG_PACKET=y
# Unix domain sockets
CONFIG_UNIX=y
# TCP/IP networking
CONFIG_INET=y

##########################
# Bus options (PCI etc.) #
##########################

# PCI support
CONFIG_PCI=y

##################
# Device Drivers #
##################

# Block devices
CONFIG_BLK_DEV=y
# Virtio block driver (EXPERIMENTAL)
CONFIG_VIRTIO_BLK=y

# Network device support
CONFIG_NETDEVICES=y
# Ethernet (10 or 100Mbit)
CONFIG_NET_ETHERNET=y
# EISA, VLB, PCI and on board controllers
CONFIG_NET_PCI=y
# RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support
CONFIG_8139CP=y
# PCI NE2000 and clones support (This driver also works for RealTek RTL-8029)
CONFIG_NE2K_PCI=y
# Virtio network driver (EXPERIMENTAL)
CONFIG_VIRTIO_NET=y

# Serial ATA (prod) and Parallel ATA (experimental)
CONFIG_ATA=y
# ATA SFF support (SFF is the legacy IDE interface)
CONFIG_ATA_SFF=y
# Intel PATA MPIIX support
CONFIG_ATA_PIIX=y

# SCSI device support
CONFIG_SCSI=y
# SCSI disk support
CONFIG_BLK_DEV_SD=y
# SCSI CDROM support
CONFIG_BLK_DEV_SR=y

# Multiple devices driver support (RAID and LVM)
CONFIG_MD=y
# Device mapper support
CONFIG_BLK_DEV_DM=y

##################
# Virtualization #
##################

# Virtualization
CONFIG_VIRTUALIZATION=y

# PCI driver for virtio devices (EXPERIMENTAL)
CONFIG_VIRTIO_PCI=y

With modules support:


# Enable loadable module support
CONFIG_MODULES=y

# Module unloading
CONFIG_MODULE_UNLOAD=y

########################################
# Executable file formats / Emulations #
########################################

# Kernel support for ELF binaries
CONFIG_BINFMT_ELF=y

################
# File systems #
################

# Ext3 journalling file system support
CONFIG_EXT3_FS=m

# /proc file system support
CONFIG_PROC_FS=y

# Virtual memory file system support (former shm fs)
CONFIG_TMPFS=y

# Inotify file change notification support
CONFIG_INOTIFY=y

# Inotify support for userspace
CONFIG_INOTIFY_USER=y

# ISO 9660 CDROM file system support
CONFIG_ISO9660_FS=m

###############################
# Processor type and features #
###############################

# Pentium-II/Celeron(pre-Coppermine)
CONFIG_MPENTIUMII=y

# Paravirtualized guest support
CONFIG_PARAVIRT_GUEST=y
# KVM Guest support
CONFIG_KVM_GUEST=y
# KVM paravirtualized clock
CONFIG_KVM_CLOCK=y

#################
# General setup #
#################

# Prompt for development and/or incomplete code/drivers
CONFIG_EXPERIMENTAL=y

# System V IPC
CONFIG_SYSVIPC=y

# Initial RAM filesystem and RAM disk (initramfs/initrd) support
CONFIG_BLK_DEV_INITRD=y

# Optimize for size
CONFIG_CC_OPTIMIZE_FOR_SIZE=y

# Kernel .config support
CONFIG_IKCONFIG=y

# Enable access to .config through /proc/config.gz
CONFIG_IKCONFIG_PROC=y

##########################
# Enable the block layer #
##########################

# Enable the block layer
CONFIG_BLOCK=y

# Deadline I/O scheduler
CONFIG_IOSCHED_DEADLINE=y

######################
# Networking support #
######################

# Networking support
CONFIG_NET=y
# Packet socket
#CONFIG_PACKET=y
# Unix domain sockets
CONFIG_UNIX=m
# TCP/IP networking
CONFIG_INET=y

##########################
# Bus options (PCI etc.) #
##########################

# PCI support
CONFIG_PCI=y

##################
# Device Drivers #
##################

# Block devices
CONFIG_BLK_DEV=y
# Virtio block driver (EXPERIMENTAL)
CONFIG_VIRTIO_BLK=m

# Network device support
CONFIG_NETDEVICES=y
# Ethernet (10 or 100Mbit)
CONFIG_NET_ETHERNET=y
# EISA, VLB, PCI and on board controllers
CONFIG_NET_PCI=y
# RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support
CONFIG_8139CP=m
# PCI NE2000 and clones support (This driver also works for RealTek RTL-8029)
CONFIG_NE2K_PCI=m
# Virtio network driver (EXPERIMENTAL)
CONFIG_VIRTIO_NET=m

# Serial ATA (prod) and Parallel ATA (experimental)
CONFIG_ATA=m
# ATA SFF support (SFF is the legacy IDE interface)
CONFIG_ATA_SFF=y
# Intel PATA MPIIX support
CONFIG_ATA_PIIX=m

# SCSI device support
CONFIG_SCSI=m
# SCSI disk support
CONFIG_BLK_DEV_SD=m
# SCSI CDROM support
CONFIG_BLK_DEV_SR=m

# Multiple devices driver support (RAID and LVM)
CONFIG_MD=y
# Device mapper support
CONFIG_BLK_DEV_DM=m
##################
# Virtualization #
##################

# Virtualization
CONFIG_VIRTUALIZATION=y

# PCI driver for virtio devices (EXPERIMENTAL)
CONFIG_VIRTIO_PCI=m