Ajitabh Pandey's Soul & Syntax

Exploring systems, souls, and stories – one post at a time

Tag: QEMU

  • Creating and Using MS DOS Virtual Machine in QEMU

    Create a disk image of desired size. I chose 50 MB

    $ dd if=/dev/zero of=msdos622.img bs=1k count=0 seek=50000
    

    Next boot from the DOS boot media. I had a bootable CD image.

    $ qemu -hda msdos622.img -cdrom DOS6.22_bootdisk.iso -boot d
    

    From the DOS prompt, create a partition on drive C using fdisk

    A:\> fdisk
    

    After the partition is created the machine will be rebooted. Once you get the DOS prompt back format the drive C and make it bootable:

    A:\> format c: /s
    

    The /s option of format command transfers the system to the drive.

    Next create a directory DOS in C:\ and copy all the utilities into it:

    A:\> mkdir c:\dos
    A:\> copy *.* c:\dos
    

    DOS is ready to be used. Now in order to transfer your old games and programs, you need to mount it as loopback device in linux. There is one problem with this. Since the image file has a partition table in it, when I tried to mount it, I got the following errors:

    $ sudo mount msdos622.img /mnt -o loop -t msdos
    mount: wrong fs type, bad option, bad superblock on /dev/loop0,
           missing codepage or helper program, or other error
           In some cases useful info is found in syslog - try
           dmesg | tail  or so
    

    To work this around we need to calculate the offset size of the partition using the fidisk -ul command:

    $ fdisk -ul msdos622.img
    You must set cylinders.
    You can do this from the extra functions menu.
    
    Disk msdos622.img: 0 MB, 0 bytes
    16 heads, 63 sectors/track, 0 cylinders, total 0 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Disk identifier: 0x00000000
    
           Device Boot      Start         End      Blocks   Id  System
    msdos622.img1   *          63       98783       49360+   6  FAT16
    

    To calculate the offset we need to multiply the starting block (63 in our case) by 512. If the image has multiple partitions then the same approach can be used and each partition can be individually mounted on a separate mount point.

    $ sudo mount -o loop,offset=32256 msdos622.img /mnt
    $ ls /mnt
    command.com  dos  drvspace.bin    io.sys    msdos.sys
    

    Now you can copy your old dos games and other files to /mnt.

  • Creating and Using MS DOS Virtual Machine in QEMU

    Being an old DOS user, sometimes there is an urge to go back to college days and recall how we used to do various things in DOS. Using dbase III, in a DOS environment reminds me of some of the great times I used to had in college as a student and later when I started my carrier as a Trainer.

    Today’s Virtualization technology had made it possible to run a DOS environment. Read on to find out how did I manage to set-up a MS-DOS VM using QEMU. Oh by the way I damaged my copy of WordStart 4 and Lotus 123 for DOS, if you happen to have one and don’t mind sharing please upload it to a public place and send me a link.

    Create a disk image of desired size. I chose 50 MB

    $ dd if=/dev/zero of=msdos622.img bs=1k count=0 seek=50000
    

    Next boot from the DOS boot media. I had a bootable CD image.

    $ qemu -hda msdos622.img -cdrom DOS6.22_bootdisk.iso -boot d
    

    From the DOS prompt, create a partition on drive C using fdisk

    A:\> fdisk
    

    After the partition is created the machine will be rebooted. Once you get the DOS prompt back format the drive C and make it bootable:

    A:\> format c: /s
    

    The /s option of format command transfers the system to the drive.

    Next create a directory DOS in C:\ and copy all the utilities into it:

    A:\> mkdir c:\dos
    A:\> copy *.* c:\dos
    

    DOS is ready to be used. Now in order to transfer your old games and programs, you need to mount it as loopback device in linux. There is one problem with this. Since the image file has a partition table in it, when I tried to mount it, I got the following errors:

    $ sudo mount msdos622.img /mnt -o loop -t msdos
      mount: wrong fs type, bad option, bad superblock on /dev/loop0,
      missing codepage or helper program, or other error
      In some cases useful info is found in syslog - try
      dmesg | tail  or so
    

    To work this around we need to calculate the offset size of the partition using the fidisk -ul command:

    $ fdisk -ul msdos622.img
    You must set cylinders.
    You can do this from the extra functions menu.
    
    Disk msdos622.img: 0 MB, 0 bytes
    16 heads, 63 sectors/track, 0 cylinders, total 0 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Disk identifier: 0x00000000
    
    Device Boot      Start         End      Blocks   Id  System
    msdos622.img1   *          63       98783       49360+   6  FAT16
    

    To calculate the offset we need to multiply the starting block (63 in our case) by 512. If the image has multiple partitions then the same approach can be used and each partition can be individually mounted on a seperate mount point.

    $ sudo mount -o loop,offset=32256 msdos622.img /mnt
    $ ls /mnt
    command.com dos  drvspace.bin    io.sys    msdos.sys
    

    Now you can copy your old dos games and other files to /mnt.

  • Interconnecting QEMU and VirtualBox Virtual Machines

    Sometime back I came across VirtualBox, an excellent replacement for commercial Vmware. I installed few OSes in VirtualBox and found the performance pretty good. In my opinion the performance of Windows virtual machines is much better in VirtualBox, perhaps because of the installed guest additions.

    Immediately a thought came into my mind. What if I want to create an internetwork of VirtualBox virtual machines and QEMU virtual machines.

    The default NAT networking in VirtualBox does not solve any purpose. The only useful networking option I found was the “Host Interface”. I went through several documents on VirtualBox website and realise that I needed to use bridging in order to do this. All the documents explained beautifully how to accompalish bridging with the ethernet interface on the host machine, but this is not what I wanted. I wanted the virtual machines to be in an isolated network connected together using VDE Switch as I was doing with QEMU. Searching on google for quite sometime did not help either, so I decided to give it a try.

    Following is what I did to accompalish this. After executing the following –

    1. QEMU virtual machines can talk to VirtualBox virtual machines and vice-versa.
    2. Host can talk to all virtual machines and vice-versa.
    3. All virtual machines can connect to internet via the hostmachine.

    As suggested on the VirtualBox website, in order to use bridging I need the uml-utilities and bridge-utilities packages:

    $ sudo apt-get install uml-utilities bridge-utils
    

    I need to load the tun/tap module and the kqemu module for QEMU

    $ sudo modprobe kqemu
    $ sudo modprobe tun
    

    Next I wanted to make the “tun” device writeable by the users, so I out myself into the “vboxusers” group and gave the group write permission on the device.

    $ sudo chgrp vboxusers /dev/net/tun 
    $ sudo chmod g+rw /dev/net/tun
    

    Then I created couple of persistent tap interfaces owned by an ordinary user:

    $ sudo tunctl -t tap0 -u ajitabhp
    $ sudo tunctl -t tap1 -u ajitabhp
    

    Next I started the VDE Switch connected to the tap0 interface and make the control file world writeable:

    $ vde_switch -tap tap0 -daemon
    $ chmod 666 /tmp/vde.ctl
    

    A bridge then needs to be created:

    $ sudo brctl addbr br0
    

    All interfaces which are connected to network segments to be bridged are to be put into promiscuous mode.

    $ sudo ifconfig tap0 0.0.0.0 promisc
    

    Add the tap0 interface to the bridge and start the DNSMASQ server to listen on br0 interface.

    $ sudo brctl addif br0 tap0
    $ sudo /usr/sbin/dnsmasq --log-queries --user=named --dhcp-leasefile=/var/lib/misc/vbox-dhcpd.leases --dhcp-range=10.111.111.100,10.111.111.199,255.255.255.0,10.255.255.255,8h --interface=br0 --domain=virtual.lan --addn-hosts=/etc/my-host
    

    Next configure the br0 interface with an ip address. This br0 interface will work as the gateway for the virtual machines.

    $ sudo ifconfig br0 10.111.111.254 netmask 255.255.255.0 up
    

    Now add the tap1 interface to the bridge and bring it up.

    $ sudo brctl addif br0 tap1 
    $ sudo ifconfig tap1 up
    

    Enable IP forwarding on the host machine and setup MASQUERADING:

    $ sudo su -
    # echo "1" > /proc/sys/net/ipv4/ip_forward
    $ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    

    Following is how various interfaces look like after finishing this setup.

    $ brctl show br0
    bridge name     bridge id               STP enabled     interfaces
    br0             8000.ae7729b64a80       no              tap0
    							tap1
    $ ifconfig 
    br0       Link encap:Ethernet  HWaddr 6E:EA:39:83:8C:D4  
              inet addr:10.111.111.254  Bcast:10.111.111.255  Mask:255.255.255.0
              inet6 addr: fe80::6cea:39ff:fe83:8cd4/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:106 errors:0 dropped:0 overruns:0 frame:0
              TX packets:82 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0 
              RX bytes:10696 (10.4 KiB)  TX bytes:10165 (9.9 KiB)
    
    eth0      Link encap:Ethernet  HWaddr 00:12:F0:28:6E:C3  
              inet addr:192.168.0.176  Bcast:192.168.0.255  Mask:255.255.255.0
              inet6 addr: fe80::212:f0ff:fe28:6ec3/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:426 errors:32 dropped:32 overruns:0 frame:0
              TX packets:327 errors:0 dropped:0 overruns:0 carrier:1
              collisions:0 txqueuelen:1000 
              RX bytes:356289115 (339.7 MiB)  TX bytes:18085137 (17.2 MiB)
              Interrupt:11 Base address:0xa000 Memory:d0200000-d0200fff 
    lo        Link encap:Local Loopback  
              inet addr:127.0.0.1  Mask:255.0.0.0
              inet6 addr: ::1/128 Scope:Host
              UP LOOPBACK RUNNING  MTU:16436  Metric:1
              RX packets:7425 errors:0 dropped:0 overruns:0 frame:0
              TX packets:7425 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0 
              RX bytes:610482 (596.1 KiB)  TX bytes:610482 (596.1 KiB)
    
    tap0      Link encap:Ethernet  HWaddr 6E:EA:39:83:8C:D4  
              inet6 addr: fe80::6cea:39ff:fe83:8cd4/64 Scope:Link
              UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0 frame:0
              TX packets:81 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:500 
              RX bytes:0 (0.0 b)  TX bytes:10808 (10.5 KiB)
    
    tap1      Link encap:Ethernet  HWaddr B2:03:C1:BE:1E:4E  
              inet6 addr: fe80::b003:c1ff:febe:1e4e/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:106 errors:0 dropped:0 overruns:0 frame:0
              TX packets:46 errors:0 dropped:6 overruns:0 carrier:0
              collisions:0 txqueuelen:500 
              RX bytes:12180 (11.8 KiB)  TX bytes:4978 (4.8 KiB)
    $ sudo iptables -t nat -L
    Chain PREROUTING (policy ACCEPT)
    target     prot opt source               destination         
    
    Chain POSTROUTING (policy ACCEPT)
    target     prot opt source               destination         
    MASQUERADE  0    --  anywhere             anywhere            
    
    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    

    Now start the QEMU virtual machines:

    $ vdeqemu -net vde,vlan=0 -net nic,vlan=0,macaddr=52:54:00:00:EE:01 -m 256 -hda ~/qemu/netbsd.img 1>~/logs/qemu-logs/netbsd.log 2>~/logs/qemu-logs/netbsd.error &
    

    In VirtualBox attach the network interface of all virtual machines to “Host Interface” and then select tap1 as the interface name.