Tag Archive : qemu

/ qemu

Debugging Linux Kernel on QEMU Using GDB

March 21, 2016 | Article | No Comments

Kernel is magic. Well, not really. All my experiences involving programming in userland. Could I step up to enter the land of kernel? Sure, but before that I need to arm myself with knowledge. Especially when dealing with kernel debugging.

This article will discuss about kernel debugging. When writing this, I use:

  • Linux Kernel 4.5
  • GDB 7.7.1
  • Qemu 2.5.0
  • Busybox 1.24.2
  • ParrotSec Linux for host

Although in the end we can run minimalistic kernel, this approach is not close to “real world” yet.

Preparation

Download the kernel source code from https://www.kernel.org/ and extract it to /usr/src

wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.5.tar.xz
mv linux-4.5.tar.xz /usr/src
cd /usr/src
tar -xf linux-4.5.tar.xz -C linux

Download busybox and extract it to /usr/src. We will use this for creating initramfs.

wget https://busybox.net/downloads/busybox-1.24.2.tar.bz2
mv busybox-1.24.2.tar.bz2
cd /usr/src
tar -xf busybox-1.24.2.tar.bz2 -C busybox

ParrotSec is debian derivative.

I use latest Qemu, you can read it from here.

Compile Linux Kernel

It’s a bit different to usual routine, we need to enable debug info.

cd /usr/src/linux
mkdir build
make menuconfig O=build

Select “Kernel hacking” menu.

Go to “Compile-time checks and compiler options”.

  • Enable the “Compile the kernel with debug info”
  • Enable the “Compile the kernel with frame pointers”
  • Enable the “Provide GDB scripts for kernel debugging”.

Search for “KGDB: kernel debugger” and make sure it is checked.

Go to the build directory and build from there

cd build
make bzImage -j $(grep ^Processor | wc -l)

Creating Initramfs

We need some kind of environment with basic command line tools. Something that provided by binutils, like: ls, cat, mkdir, etc. It is called initramfs (Initial RAM file system). The idea is to provide a minimal “root file system” as a temporary file system so Kernel can prepare all works before mounting the real file system. We will use Busybox.

cd /usr/src/busybox
mkdir build
make menuconfig O=build

Select “Busybox Settings” > “General Configuration” and uncheck the “Enable options for full-blown desktop systems” and check”. Go back and select “Build Options” and check “Build BusyBox as a static binary (no shared libs).

make && make install

This will create a new directory “_install” and install our busybox there. This _install will be base for initramfs.

Next we create a new “initramfs” directory and create some configuration files inside.

mkdir /usr/src/initramfs
cd /usr/src/initramfs
cp -R /usr/src/busybox/build/_install rootfs
cd rootfs
rm linuxrc
mkdir -p dev etc newroot proc src sys tmp

We don’t need “linuxrc” sine we are going to use initramfs boot scheme.

Create a file etc/wall.txt and fill it:

######################################
#                                    #
#      Kernel Debug Environment      #
#                                    #
######################################

Remember init? Once our kernel is up, we need init to spawn everything necessary. However in our minimalistic system, our init only needed to spawn tty. Now create and populate init file with following content.

#!/bin/sh
dmesg -n 1

mount -t devtmpfs none /dev
mount -t proc none /proc
mount -t sysfs none /sys

cat /etc/wall.txt

while true; do
   setsid cttyhack /bin/sh
done

The cttyhack is a small utility for spawning tty device. This way, we can rest assure that when we execute the “exit” command new shell will be started automatically.

We need to make the init file is executable.

chmod +x init

Next we need to pack initramfs.

cd /usr/src/initramfs/rootfs
find . | cpio -H newc -o | gzip > ../rootfs.igz

Running Kernel on Qemu

Next thing to do is to launch the kernel inside Qemu.

qemu-system-x86_64 -no-kvm -s -S \
-kernel /usr/src/linux/build/arch/x86/boot/bzImage \
-hda /mnt/jessie.ext3 -append "root=/dev/sda"

At this point, we will see a blank QEMU terminal windows.

The -s option is a shorthand for -gdb tcp::1234, i.e. open a gdbserver on TCP port 1234.

The -S option stops the CPU to start at startup. Now QEMU is waiting for kernel to start in debug mode.

Running GDB

The QEMU had launched the kernel and waiting for debugging. The next thing is to launch GDB and do the debugging.

gdb

In our host, we need to load the the same kernel load in QEMU and point our target to QEMU.

file /usr/src/linux/build/arch/x86/boot/bzImage
set architecture i386:x86-64:intel
set remote interrupt-sequence Ctrl-C
target remote :1234

Let’s try it, using GDB:

continue
bt

As for now, GDB still not appreciate the size of registers changing. As for our kernel, there is a time when our kernel change from 16 bit to 32 bit (or 64 bit). You might notice that when we run QEMU we specify -S so QEMU will stop at startup. At that time, Linux will change to full 64 bit (or 32 bit) kernel. If you don’t do something, GDB will keep complaining about “remote packet reply is too long”.

To circumvent it, we can just disconnect and then reconnect.

disconnect
set architecture i386:x86-64:intel
target remote :1234

QEMU [Paused]_021  LXTerminal_022

Running Debian MIPS Linux in QEMU

December 11, 2015 | Article | No Comments

Have you ever want to try system other than your PC? MIPS for example.

As a reverse engineer, I sometimes want to run a MIPS Linux system so that I can observe, develop, and testing somethings. However, I don’t have much room for another device, so virtualization might be a solution.

In this article we will try to run MIPS Linux on QEMU. In specific, Debian MIPS Linux, with following materials used:

  1. Slackware64 14.1
  2. QEMU 2.1.50

The article written here should be as generic as possible so I hope it can be used for different setup you use.

Obtain the Materials

Refer to this article to build a QEMU, if you don’t have one: Installing QEMU from Source

Next, we need to download the kernel images and a disk image which has Debian installed there. Go to this site to download. The ‘mips’ directory is for Big Endian MIPS and ‘mipsel’ is for Little Endian one. Choose what you want but in this case I will download both of them. In specific, we will test kernel version 3.2.0 (denoted as vmlinux-3.2.0-4-5kc-malta) with Debian Wheezy (denoted as debian_wheezy_mipsel_standard.qcow2)

At this point, we have (at least):

  1. QEMU installed
  2. Debian kernel
  3. Disk Image with qcow2 format.

Setup Bridged Networking

In order to make QEMU environment connected to the network, we need to do some additional setup.

Now create the two new files, /etc/qemu-ifup and /etc/qemu-ifdown. Make sure you give them executable permission. Also make sure you have right configuration, like GATEWAY and BROADCAST address. Also pay attention to the USER. It is a username you should specify when you want to run qemu.

#!/bin/bash
ETH0IPADDR=192.168.1.100
GATEWAY=192.168.1.1
BROADCAST=192.168.1.255
USER=xathrya
 
# First take eth0 down, then bring it up with IP address 0.0.0.0
/sbin/ifconfig eth0 down
/sbin/ifconfig eth0 0.0.0.0 promisc up
 
# Bring up the tap device (name specified as first argument, by QEMU)
/usr/sbin/openvpn --mktun --dev $1 --user $USER
/sbin/ifconfig $1 0.0.0.0 promisc up
 
# Create the bridge between eth0 and the tap device
/usr/sbin/brctl addbr br0
/usr/sbin/brctl addif br0 eth0
/usr/sbin/brctl addif br0 $1
 
# Only a single bridge so loops are not possible, turn off spanning tree protocol
/usr/sbin/brctl stp br0 off
 
# Bring up the bridge with ETH0IPADDR and add the default route
 
/sbin/ifconfig br0 $ETH0IPADDR netmask 255.255.255.0 broadcast $BROADCAST
/sbin/route add default gw $GATEWAY

and

#!/bin/bash
 
# Bring down eth0 and br0
/sbin/ifconfig eth0 down
/sbin/ifconfig br0 down
 
# Delete the bridge
/usr/sbin/brctl delbr br0
 
# Bring up eth0 in "normal" mode
/sbin/ifconfig eth0 -promisc
/sbin/ifconfig eth0 up
 
# Delete the tap debice
/usr/sbin/openvpn --rmtun --dev $1

To starting network bridge, just invoke

/etc/qemu-ifup tap0

and then invoke

/etc/qemu-ifdown tap0

to stop it.

Running the Debian MIPS

After all preparation we have done, it’s time for actual thing.

Go to the directory where we store kernel and disk image, for example $HOME/debian-mipsel, and then invoke following command:

qemu-system-mips64el -net nic -net tap,ifname=tap0,script=no,downscript=no \
-M malta -kernel vmlinux-3.2.0-4-5kc-malta -hda debian_wheezy_mipsel_standard.qcow2 \
-append "root=/dev/sda1 console=tty0"

We can also create a script to simplify it.

#!/bin/bash

qemu=qemu-system-mips64el
path="$HOME/debian-mipsel/"
hda="$path/debian_wheezy_mipsel_standard.qcow2"
kernel="$path/vmlinux-3.2.0-4-5kc-malta"
iface=tap0

echo "Stopping eth0, starting tap0"

/etc/qemu-ifup tap0 || quit 1 "Failed to start tap0"

echo "Starting Debian MIPS"

$qemu -net nic -net tap,ifname=$iface,script=no,downscript=no \
-nographic -M malta -kernel $kernel -hda $hda -append "root=/dev/sda1 console=tty0"

If everything goes well, you should see Debian is booting and then greeted with sweet login prompt.

Further Configuration

It’s nice to work with QEMU window. But you should admit taht QEMU console is very limiting, so you need SSH connection to do most of your work. You can, by installing OpenSSH inside Debian system using apt:

apt-get update
apt-get install openssh-server

Installing QEMU from Source

December 11, 2015 | Article | 1 Comment

Edit: I had update the article to build from latest package and testing.

You might notice that I had written an article before about building QEMU from source. That one is QEMU KVM (Kernel Virtual Machine).  As per version version 1.3 QEMU-KVM is merged to upstream QEMU project therefore the QEMU-KVM is no longer maintained. It’s been done long time ago, actually.

QEMU is a generic and open source machine emulator and virtualizer.

When used as a machine emulator, QEMU can run OSes and programs made for one machine (e.g. an ARM board) on a different machine. By using dynamic translation, it achieves very good performance.

In this article we will discuss about installing QEMU and use following requirement:

  1. Slackware64 14.0, although any version is OK
  2. latest qemu source code

There are two options for us: building the stable release or building the development code.

Obtain the Source Code

Between the stable release source code and development code, which one is suitable for us?If you want to download the latest stable release, you can obtain it from qemu official site here.

At the time of writing this article, the latest stable version is 2.5.0 (per March 20th 2016). You can download it by direct link here. http://wiki.qemu-project.org/download/qemu-2.5.0.tar.bz2

Once you have done downloading, uncompress it with:

mv qemu-2.5.0.tar.bz2 /usr/src
tar -jxvf qemu-2.5.0.tar.bz2
cd qemu-2.5.0

If you want to download the development code. You can clone the git repository by:

cd /usr/src
git clone git://git.qemu-project.org/qemu.git
cd qemu

For any option we choose, we should have qemu source code now.

Compilation

At this point we are inside the source directory. Qemu support many features. We can list the feature by

./configure --help

For now, we just want a working Qemu with debug enable and install it to /usr. First, create a directory build. This directory will be used for all building process we do.

mkdir build
cd build

Next we do usual chant:

../configure --enable-debug  --prefix=/usr --enable-modules
make -j4

If you want to know my build, here it is:

../configure --enable-debug --prefix=/usr --enable-modules --enable-libusb \
--enable-usb-redir --enable-spice --enable-smartcard

If you like, you can go to next section for testing. If not, you can install QEMU by

make install

Congratulation, you had installed Qemu.

Testing

Testing BIOS

To test if default settings works.

x86_64-softmmu/qemu-system-x86_64 -L pc-bios

Testing KVM

To test if KVM is working

x86_64-softmmu/qemu-system-x86_64 -cpu host --enable-kvm -L pc-bios

To test with Linux image

wget http://wiki.qemu.org/download/linux-0.2.img.bz2
bunzip2 linux-0.2.img.bz2
x86_64-softmmu/qemu-system-x86_64 -cpu host --enable-kvm -display gtk linux-0.2.img

Testing the QEMU

December 9, 2015 | Article | No Comments

QEMU, a popular emulation and simulation application used for simulating most architecture, from embedded processor such as ARM to common x86_64 processor. QEMU is available to various host operating system: Linux, Windows. To test QEMU capability, we can provide it with a testing disk image which has a guest operating system inside.

In this article, we will list all testing disk image available for QEMU. You can download some of the guest image from QEMU website, including a simple 8MB image of a linux distro (which is meant primarily for testing and might lacks some drivers). We will also list other QEMU test disk image we found so far on this site.

You also might interested to basic guide about QEMU disk image:

  1. Mounting QEMU disk image

QEMU Disk Images

Collection of disk images which can be used to test system emulation.

linux-0.2.img.bz2 [ mirror ] Small Linux image containing a 2.6.20 Linux kernel, X11, and various utilities to test QEMU
odin1440.img [ mirror ] FreeDOS floppy disk image from ODIN
small.ffs.bz2 [ mirror ] Small NetBSD Image
minix204.tar.bz2 [ mirror ]
Minix 2.0.4
efi-bios.tar.bz2 [ mirror ]
EFI BIOS for QEMU
sparc-test-0.2.tar.gz [ mirror ]
SPARC Linux 2.6 test kernel and initrd disk image
arm-test-0.2.tar.gz [ mirror ]
ARM Linux 2.6 test kernel and initrd disk image
mips-test-0.2.tar.gz [ mirror ]
MIPS Linux 2.6 test kernel and initrd disk image
mipsel-test-0.2.tar.gz [ mirror ]
MIPS Little Endian Linux 2.6 test kernel and initrd disk image
coldfire-test-0.1.tar.bz2 [ mirror ]
Coldfire Linux 2.6 test kernel and initrd disk image
sh-test-0.2.tar.bz2 [ mirror ]
SH4 Linux 2.6 test kernel and initrd disk image
cris-axisdev88-img-linux2_6_33.tgz [ mirror ]
CRIS AXIS Devboard88 Linux 2.6 test kernel and initrd disk image
mb-s3adsp1800-linux-2_6_34_tgz [ mirror ]
Microblaze S3ADSP1800 Linux 2.6 test kernel and initrd disk image
ppc-virtexml507-linux-2_6_34.tgz [ mirror ]
PPC-440 Virtex-ML507 Linux 2.6 test kernel and initrd disk image
xtensa-dc232b_kernel_rootfs.tgz [ mirror ]
Xtensa Linux 2.6.29 test kernel and initrd disk image

QEMU User Mode Emulation

These executables can be used to test Linux user mode emulation

linux-user-test-0.3.tar.gz [ mirror ]
Distribution of shared libraries and various shell executables for almost all Linux target architecture that QEMU simulates. It is used to make regression tests on the Linux user mode emulation

Dynamic Code Analysis

This includes any test to detect memory leaks, reads of uninitialized memory, buffer overflows, or other forms of illegal memory access. Typically these kind of tests are done using Valgrind on a Linux host. Any of the disk images and executables listed above can be used in such tests.

# Simple i386 boot test (BIOS Only) with Valgrind
valgrind --leak-check=full --track-origin=yes --verbose qemu-system-i386

Testing and debugging an operating system require an environment. Many people prefer to use emulator and virtualization software like QEMU, VMware, or VirtualBox for this job.

If you have read my previous article about mounting QEMU Hard Disk Image, you should note that the partition should already have been formatted with a specific filesystem. This is bad if we just create a fresh QEMU disk image.

This article will discuss about how to format the partition inside QEMU disk image. The assumption made here is the disk image is fresh and no more operation than partitioning it. I assume you have at least one partition (such as FAT32, Linux, etc. Any!).

In this article I use:

  1. Slackware64 14.0 as host system
  2. QEMU 1.4.0

I also provide a small empty raw image for play around (see next section).

Obtain the Materials

You can download an empty disk image here

The compressed image size is 2MB and the extracted (the image itself) is 2GB.

The disk image has two partition (as seen on fdisk):

  1. W95 FAT32, start from 2048 , end on 268287. This will be formatted as FAT32.
  2. Linux, start from 268288, end on 4194303. This will be formatted as EXT4.

There is nothing special about this image. The process I did is common and you can achieve it by yourself:

  1. Create empty qemu image file
    qemu-img create -f raw xath-testsuite-ext3.img 2G

    The image is in raw format. This is important as it is the simple one.

  2. Create the partition using fdisk.

We also need a Linux ISO image. We will use Slackware mini install which can be obtained here. In the rest of this article, we will refer this as minislack.iso.

Process

What we will do are:

  1. Format the hard disk / QEMU disk image using Linux installer.
  2. Interrupt the Linux installer, stop QEMU, mount the QEMU image on Linux and clean it up.

Formatting

Boot the disk with QEMU and Slackware as first boot

qemu-system-i386 xath-testsuite-ext3.img -cdrom minislack.iso -boot d

Once booted, just press enter. Press enter again when you are asked for keyboard layout. You will be brought to a terminal. Login as root with no password.

Our disk image is recognized as /dev/sda. To format a partition as FAT32 use mkfs.vfat and to format it as EXT4 use mkfs.ext4.

We will try the second one and I will leave you with the first one for you to play with 😉

mkfs.ext4 /dev/sda2

Finishing

Now for final touch. Still using the Slackware on QEMU, mount the /dev/sda1 and /dev/sda2. Your goal now is to remove the content. After this point, we can finally say “done!”.

Congratulation!

Emulating Raspberry Pi using QEMU on Windows

December 9, 2015 | Article | No Comments

Previously, we have discussed installation of various Raspberry Pi‘s Operating System. All have been done on the actual board. But what if we are in situation where we can’t afford the board? Emulation sure is the way to experiment and QEMU open the possibility.

Although emulation can make our life easy, you can’t always rely on emulation. Remember that emulation trying to imitate the real hardware, but can’t be the one.

In this article, we will discuss about how to emulate Raspberry Pi board using QEMU. For this purpose I use:

  1. Windows 8 64-bit as host system
  2. QEMU 1.4.0
  3. Soft-Float Debian Wheezy with version 2013-05-29.
  4. OpenVPN

For Linux machine, you can go to this article instead.

Obtain the Material

Make sure you have QEMU installed. On Windows, you can follow this article.

Next, download the images. As stated above, we will use Soft Float Debian Wheezy. You can download it from Raspberry Pi’s official download page. The version I use is the 2013-05-29 or latest version per August 24th 2013 and can be downloaded here.

We also require linux kernel for QEMU. Download it from here.

Download and install OpenVPN. This will add a TAP 32 network adapter.

The Hardware – Overview

Before we go to next section, it is always a good idea to understand what system we want to work with. In this case, raspberry Pi. You can see the Architecture of Raspberry Pi for detail.

For the system we will create in using QEMU:

  1. ARM1176JZF-S, see the datasheet here
  2. Ethernet

Note that QEMU cannot emulate GPIO and GPU.

Also, to encapsulate network we need TAP network for full networking support. See next section.

Preparing the environment

Create a working directory. In this case, qemu-raspberry.

Extract the disk image and kernel image we have downloaded on previous section.

Now open “Network and Sharing Center” and click “Change Adapter Settings” in the left menu.

Rename the TAP 32 network adapter to just TA32 and double click the adapter. Do the settings like this (adjust with your setting):

Now bridge the adaptor with an active connection with the TAP32 adapter.

Next create a file raspberry.bat and fill with following:

qemu-system-arm.exe -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot \
-serial stdio -append "root=/dev/sda2 panic=1" -hda 2013-05-29-wheezy-raspbian.img \
-net nic -net tap,ifname=TAP32

Booting the disc image

Just double click the rasperry.bat and if you did correctly, you will get similar to this:

Installing Haiku on QEMU

December 9, 2015 | Article | No Comments

If previous article we discuss about installing Haiku on VirtualBox, this time we will discuss about how to install Haiku on QEMU. As proof of concept, I use:

  1. Slackware64 14.0 as host
  2. QEMU 1.4.0.
  3. Haiku iso file

Obtaining the Materials

As said, we will do installation of Haiku on virtual machine using Qemu. Thus you have to make sure Qemu is installed and enable to run properly.

The main material we need is the Haiku ISO itself. Go to Haiku’s download page. The latest version is R1/Alpha 4.1 which is relased on November 14th, 2012. Haiku team provide three way to taste Haiku, which are: Anyboot, ISO, and preloaded image file. As our concern is installation Haiku to VirtualBox, choose the ISO. The iso file itself is archived by zip and xz format. I suggest you to download the iso file from the closest area to you. Whatever format you download, extract the content. There you should get a directory with two files: haiku-r1alpha4.iso and release_notes_r1alpha4.1.txt. Next we will refer the iso as haiku.iso.

Create the Virtual Machine

It would be great if you create a working directory specially made for this purpose. Let’s call it HaikuDir under your home directory. Therefore, we will have ~/HaikuDir.

Haiku will be installed to a dedicated drive image. We will refer it as haiku.img. Approximately, 1000MB space at minimum is sufficient. We will make use of QEMU to create an image for us.

qemu-img create haiku.img 1000M

If you plan to install some application to try under Haiku, greater space is recommended.

Now on our working directory, let’s invoke following command to spawn qemu.

qemu-system-i386 -m 256 -cdrom haiku.iso -hda haiku.img -boot d -localtime -serial file:haiku.log

Notice the “.” on the command. Here we get some arguments.

  • -m 256 means we give 256MB of RAM. If you got plenty of RAM available and don’t mind share some, you can set this value higher.
  • -cdrom haiku.iso will create a cd rom drive to the virtual machine with haiku.iso loaded.
  • -boot d instructs QEMU to boot from the CD-ROM.
  • -localtime means the QEMU VM will use time provided by the host.
  • -serial file:haiku.log will log and catch debug message emitted by QEMU. Valid arguments to -serial include file names, pipes, COM ports, etc.

If the above command failed with following error: qemu-system-i386: Can’t open BIOS image bios.bin

Then you should find where bios.bin stored. Invoke following command to search it.

locate bios.bin

Let’s say it is on /usr/local/share/qemu/bios.bin, then invoke this to start up the qemu:

qemu-system-i386 -m 256 -cdrom haiku.iso -hda haiku.img -boot d -localtime \
-serial file:haiku.log -bios /usr/local/share/qemu/bios.bin

If you want to set the sound, go on and set emulation to AC97. To do that, add -soundhw ac97 as argument when calling qemu. You should also install drivers later. Alternatively, you can set the emulation to ES1370 using -soundhw es1370 instead of ac97 one.

If you need network connection, go add -net nic,model=ne2k_pci and -net user switches when calling qemu.

Boot and Install

qemu_haiku1

Run the virtual machine, you should then see something similar to this:

qemu_haiku2

Choose your preferred language. Our goal is again, install Haiku to our machine. Therefore, choose “Run Installer” button. You should get a “warning”. Haiku is alpha software, so you should have acknowledge this 🙂

qemu_haiku3

And then, finally, the simple installation wizard dialog. The installation is quite simple and straightforward.

qemu_haiku4

Because we create this virtual machine from scratch, then the disk has no partition yet. We should create one first. Click on Setup partition button and there should be a new dialog appear.

qemu_haiku6

The DriveSetup window should detect two mediums, one is our CD-Rom drive, and another is a “hard drive” for our virtual machine. Select the hard drive. It is blank (raw) now, therefore we should create a new partition. Navigate to Partitions -> Format -> Be File System. I want to use all the space, so let’s make it. Now we have the disk partitioned.

After finish partitioning, close the DriveSetup dialog. You should notive a square left to DriveSetup. Press it and the dialog now disappear. You should see this dialog clearly.

qemu_haiku7

Make sure the combobox next to Onto is filled with our newly created partition. Click on Begin button to begin the installation.

qemu_haiku8

The installation will took place. It should be quick, but it is also depend on your host system and the resource you give to Haiku. When the installation finished, Haiku will notify us that it need to be restarted. Click on Restart button if you are ready.

qemu_haiku9

Now, this is the tricky part. When we first launch QEMU, we say that qemu should boot the disk first. Thus, when we restarted the machine we will go back to the installation part. Therefore, when you are asked whether install or use live CD, choose live CD. Then you will be brought to Live CD version of Haiku. From this state, turn off Haiku. You can click thing on top-right of desktop and choose shutdown.

Now, whenever you want to boot Haiku, use following command:

qemu-system-i386 -m 256 -hda haiku.img -localtime -serial file:haiku.log

Once Haiku is restarted, you will see Haiku desktop with some icons there. Haiku will also adjusting and updating some things inside.

And here we have, Haiku.

qemu_haiku10

Testing ReactOS Using Preloaded QEMU Disk Image

December 9, 2015 | Article | No Comments

If previous article we discuss about installing ReactOS on QEMU from scratch, this time we will discuss about how to use preloaded ReactOS on QEMU. As proof of concept, I use:

  1. Slackware64 14.0 as host
  2. QEMU 1.4.0

I might using Linux for this article, but the preloaded archive itself is made specially for Windows.

Obtaining the Materials

As said, we will do installation of ReactOS on virtual machine using QEMU. Thus you have to make sure QEMU is installed and enable to run properly.

The main material we need is the ReactOS ISO itself. Go to http://reactos.org/, ReactOS’ official site. The latest version is 0.3.15 which is still in alpha version (not feature-complete and is recommended only for evaluation and testing purposes). ReactOS team provide three way to taste ReactOS, which are: Installation CD in iso format, Live CD, and preloaded image file. As our concern is installation ReactOS to QEMU, choose the Preloaded with QEMU. Upon finish downloading, extract the content which you will get a directory named ReactOS-0.3.15-QEMU. We will refer this iso as ROSdir

On the Directory

Go to ROSdir and let’s inspect what are inside. If you want to skip this section, go to next section for actual testing.

There are three items on the root: Readme.txt, boot.bat, and directory files. Basically this is specially prepared for Windows. The boot.bat is Windows batch script to invoke QEMU. All the materials are inside files directory. Go to files and here we see bunch of files. Basically these are all the materials.

There are some interesting files there:

  1. bios.bin: the PC BIOS which is used by QEMU to emulate x86_64 machine
  2. pxe-ne2k_pci.bin: Ethernet driver
  3. vgabios-cirrus.bin: driver for VGA
  4. SDL.dll: Dynamic Link Library (DLL) for SDL. This is used by QEMU.
  5. qemu.exe: the QEMU itself.
  6. qemu-img.exe: QEMU tools for manipulating disk image.

Boot and Testing

Back to ROSdir.

Now on our working directory, let’s invoke following command to spawn qemu.

qemu-system-i386 -m 256 -hda files/ReactOS.vmdk -net nic,model=ne2k_pci -net user \
-serial file:files/ReactOS.log

Notice the “.” on the command. Here we get some arguments.

  • -m 256 means we give 512MB of RAM. If you got plenty of RAM available and don’t mind share some, you can set this value higher.
  • -hda files/ReactOS.vmdk: ReactOS team provide us with vmdk file, which is VMware virtual disk format
  • -net nic,model=ne2k_pci: We will make use of networking using pxe-ne2k_pci driver
  • -serial file:files/ReactOS.log will log and catch debug message emitted by QEMU. Valid arguments to -serial include file names, pipes, COM ports, etc.

If the above command failed with following error: qemu-system-i386: Can’t open BIOS image bios.bin

Then you should find where bios.bin stored. Invoke following command to search it.

locate bios.bin

Let’s say it is on /usr/local/share/qemu/bios.bin, then invoke this to start up the qemu:

qemu-system-i386 -m 256 -cdrom ReactOS.iso -hda ReactOS.img -boot d -localtime \
-serial file:ReactOS.log -bios /usr/local/share/qemu/bios.bin

If you want to set the sound, go on and set emulation to AC97. To do that, add -soundhw ac97 as argument when calling qemu. You should also install drivers later. Alternatively, you can set the emulation to ES1370 using -soundhw es1370 instead of ac97 one.

Now, here is the screenshot:

qemu_react14

Testing and debugging an operating system require an environment. Many people prefer to use emulator and virtualization software like QEMU, VMware, or VirtualBox for this job. However, testing a software build for that OS which run on top of virtualization require a method to copy files between host and the guest system. Software such as VirtualBox and VMware have a feature which enable user to activate shared directory. However not every operating system can do this because this feature act as device driver or kernel module. Moreover, QEMU doesn’t have this. The best and practical way to copy file on QEMU is copy all files into .iso images which is accessible by internet. Another way is mount the virtual hard disk or the disk image, which we will do in this article.

As the title suggested, we will discuss the way in various host operating system. Therefore, materials I use are:

  1. Slackware64 14.0 (Linux)
  2. Windows 7 32 bit (Windows)
  3. QEMU 1.4.0

Linux

Most linux distribution allow virtual disk mounting using mount command. The disk image should be mounted into a specific directory, let’s say /media/MyOS. Most of the operation need root privilege, so acquire root privilege before we do.

mkdir /media/MyOS

Make sure your virtual image file is in RAW format. If you think your disk image is in another format, use following command:

qemu-img convert <image-file> -O raw <image-file.raw>

Mounting the disk image is simple thing, as simple as mounting another storage device. Note that the actual partition start from offset 32256, after some structure on the disk such as MBR, partition table, etc. The following example assume you are using FAT as file system.

mount -o loop,offset=32256 <image-file> /media/MyOS -t vfat

The 32256 comes from the start of the very first partition * the size of a block. This is because before the first partition there are some data such as MBR. So if your first partition start from block 2048, multiplying it will result in 1048576. Of course the partition should have been formatted with the preferred format.

If the disk has several partition, and you want to mount specific partition (not the first) then you should change the offset to the start of the partition.

To unmount is even easier.

umount /media/MyOS

Windows

Basically, Windows doesn’t provide such powerful tools like Linux does. However, we can always use third party’s software. Like in Linux section, in this section our goal is to mount raw images.

OSFMount

OSFMount allow local disk image mounting in Windows with a drive letter (E:/, F:/, G:/, etc). You can download OSFMount here.

P2 eXplorer

Another tool which can be downloaded here. Note that it is not free product, but you can always use the demo version.

Configuring TAP Bridge Network for QEMU

December 7, 2015 | Article | No Comments

In this article we will discuss about how to create TAP bridge network for QEMU. In this article I use Slackware64 14.0 as my host machine. I also use QEMU as described in this article.

What is Bridge?

By definition, bridge is action taken by network equipment (can be router, switch, or even our machine) to allow two or more communicative networks, or two or more network segments to create an aggregate network. It is different from routing which allows the networks to communicate independently as separate networks. A bridge is a network device that connects more than one network segment and acts in the first two layers of OSI (physical and datalink).

Bridging Concept for QEMU

In this case, bridging is not something specific for QEMU and actually the bridge functionality is provided by LInux kernel, not QEMU.

QEMU supports tap device (“-net tap” instead of “-net user” when starting QEMU). TUN/TAP devices is a “virtual ethernet driver”. On the official document of tuntap.txt, it is said that: “TUN/TAP provides packet reception and transmission for user space programs. It can be seen as a simple Point-to-Point or Ethernet device, which, instead or receiving packets from physical media, receives them from user space program and instead of sending packets via physical media writes them to the user space program.”

In basically QEMU runs on our machine as a program and have capability to write packets to the TAP devices. Thus, QEMU can simply write all the virtual computer generated packets to the TAP device and forward packets to the virtual computer. But is only sufficient if our virtual computer wants to talk to the real computer it runs on ONLY. Once the packets from the virtual computer reaches the TAP device Linux doesn’t know where to send the packets as it is not part of TAP device functionality.

So, here bridge play the role.

The bridge is (sort of) the most reliable way of connecting your virtual computer to the real network. There is no need to configure IP for TAP device for the bridge to work. No IP forwarding involved but routing instead. In this sytem, packets are forwarded at Ethernet level (layer 2 / datalink on OSI layer), bridge does not even care about IP.

Now let’s see the real implementation. Suppose we have 2 (or more) NIC (Network Interface Card), one NIC connected to one Ethernet and the other to the second Ethernet. The bridge then joins the Ethernets together to become one. The good use of bridge for example is connecting a 1GBps Ethernet with a 10MBps Ethernet. Bridge keep them separate but connect them with a with one tunnel so they can talk to each other while not bother each other that much.

Note that once the bridge started, we cannot manipulate eth0 or whatever real NIC device in our machine anymore. Since the bridge is at level 2, it needs to be able to tell where a packet is going by the MAC address in the packet. If we manipulate the eth0 device, the packet is going out to the real network directly and the bridge will not have access to the packet. Hence, it breaks the bridge.

Let’s get back to our example of 1GBps network and 10MBps network. If we request a DHCP IP address on our eth0 – which is our 1GBps network – the DHCP server has to be on the 1GBps network or it won’t be able to get an IP address. In this situation, we will have to have two DHCP servers, one on 1GBps and other on 10MBps. We will either create two segments of dynamic IPs or find a way to synchronize two DHCP servers leases.

Since the IP layer is on Layer 3 of OSI (network layer), it is built on top of the bridge which runs on datalink layer and we will have to start our IP stack on top of the bridge instead of our real NIC.

Start Bridging Step

Before we did bridging of course we need to create the TAP device. The creation

First release IP address assigned to real NIC. Then rename eth0 to reth0 (means RealETH0) and then create bridge with name “eth0”.

Create a bridge, add two NIC (one is the real NIC and the other is the TAP device).

Re-acquire a DHCP lease with the bridge interface (which is eth0 now).

Here is the complete commands:

# 1st, release all DHCP address and remove all IP address associated with the original eth0
 /sbin/dhcpcd -k
 /sbin/ip addr flush eth0
# then take the interface down so we can rename it
 /sbin/ip link set eth0 down
# now rename the original eth0 to reth0 (Real ETH0)
 /sbin/nameif -r reth0 eth0
# OK, bring the interface back up
 /sbin/ip link set reth0 up
# 2nd let's create a bridge called eth0 so other programs think they are talking to the same old interface
 /sbin/brctl addbr eth0
# then add both original eth0 and tap1 device to the bridge
 /sbin/brctl addif eth0 tap1
 /sbin/brctl addif eth0 reth0
 /sbin/brctl showmacs eth0
# 3rd, we need to bring the newly created bridge UP
 /sbin/ip link set eth0 up
# 4th, renew the DHCP address if possible
 /sbin/dhcpcd -n
 /sbin/ip addr show

Please note, there are other ways of connecting your virtual computer to the real network with TAP device: you can configure routing on your real computer (I don’t see a reason why I want to do that – if you use NAT, why don’t you use the “-net user” instead which is much simpler; if you use real world IP, why don’t you use bridge? To configure routing for the TAP, you need to start IP stack on the TAP device and start ip forwarding on the real Linux – unnecessarily complex for my environment).

Another good option is VDE (Virtual Distributed Ethernet). It is a very good solution, in some case, it maybe better than bridge. The best feature is you don’t need the brief down time as the bridge solution. I found the description of VDE is much better than bridge and hence I will skip this part.

Social media & sharing icons powered by UltimatelySocial