System emulation using QEMU

[This was last updated 2021-09-23. Please send feedback about this page! See page footer for contact information.]

The qemu project is really cool, and their goal is to support lots of computers, not just PCs.

The PC emulation works well and doesn't suffer from major incompatibility problems from qemu release to qemu release. It is really simple to get started. Create 4GiB disk image:

dd if=/dev/zero of=disk.img bs=1048576 count=4096
Install:
qemu-system-i386 -hda disk.img -cdrom your-favourite-os-install.iso -boot d
Boot the installed system:
qemu-system-i386 -hda disk.img

To instead emulate a 64-bit PC, use qemu-system-x86_64. See also below. Note that the install suggestions below will result in faster systems than these basic examples.

The downside of qemu is lack of documentation, and in particular usage examples. Also, if you try some random GNU/Linux or BSD release for a non-PC with some random qemu release, it will very likely not work as easily as above. Here I try to show one working variant of each base OS. Hopefully these examples will get you started!

If you upgrade a system, do not forget to first bring the system down and make a copy of the old disk image. It might be hard to go back once you've made your disk image unbootable. (The habit of copying disk images is a good one when working with any emulation, and is in fact a key feature of such environments!)

The qemu project relies on code inspection, but they perform limited regression testing. My experience is that regressions are not uncommon with qemu. If you are going to use qemu for something else than fun, you need to keep several builds and choose the one that works reliably for a particular system.

Unfortunately, reporting bugs or posting bug fixes to the qemu project is usually a completely futile exercise. I have never gotten a bug report taken seriously, and as a result some bugs live year after year. I have gotten some fixes in, but only after much haggling and pointing out that their variations on the initial (correct) fix are broken. In the end, my initial fix gets applied, but now with credit taken by some qemu project member.

My motive for this entire exercise is software testing; qemu allows me to test things for systems to which I have no other access. I just need ssh access, and that's exactly what these example installs provide.

FAQ

Q: Do these examples really work? Have they been tested?

A: I have tested exactly what I suggest below in each case. They do work.

Q: What about networking? What's this "tap" thing?

A: If your host is set up to allow network bridging (think of that a simulated Ethernet switch) and if you either configure an IP address manually during guest OS installation, or have a dhcp server, then network should just work. If you don't want to configure the host to allow tap to work, check qemu's documentation about "user" networking and perhaps the hostfwd feature; many people find that easier to get going.

Q: The amount of memory (as specified by -m) varies between these examples, why?

A: There isn't too much science behind that. I tend to give slightly more memory to a 64-bit guest than a 32-bit guest.

Q: The qemu version varies between these examples. Any good reasons for that?

A: Some past versions of qemu have had regressions affecting particular targets. Therefore, I recommend qemu versions that I have made sure works. By all means, try other versions, but my recommendation is to start with exactly my setup and then go from there.

Q: Disks, network, and kernel are specified in varying ways. Why not be more consistent?

A: I believe the variation is mostly well-motivated by limitations in the emulated OS and/or qemu. It is possible that things could be made more consistent, but I have tried to minimize unmotivated variation. Note that Debian is highly inconsistent with kernel naming or downloads and /boot contents ("linux"/"vmlinux"/"vmlinuz", with or without explicit version numbers, with version-number free symlinks or without such symlinks).

Q: Qemu offers several disk formats. In these examples, "raw" format seem to be either understood or explicitly enforced with the format=raw specifier. Reasons?

A: I actually use either lvm partitions or sparse plain files for my guest disks (the latter created with dd's seek operator). These imply minimal host CPU overhead. If you want to use qcow2 or some other setup, that should work fine (but make sure to remove (or adapt) the format=raw specifier).

Q: I want to emulate machine M with CPU C, a combination which I believe qemu supports. How should I do that?

A: The goal of my page here is to allow for testing on various CPU architectures. I realise that not all sub-architectures are covered (e.g., armv4, sparc millennium, mips r6). Also, the machine type is largely ignored. I don't currently have plans to try to make it much more complete, as that would be hard to maintain in the long run. So, I'm afraid I can only wish you luck with machine M emulation.

Q: There is something called qemu user-level emulation, skirting this thing about OS installation. Why don't you give examples of that instead?

A: I intend to do that. In fact, I have a shell script which installs all Debian versions which I can get to work. The main problem here is that the binfmt GNU/Linux feature is poorly designed and that the qemu pattern files which come with most (perhaps all) GNU/Linux dists are pretty buggy.

Current matrix

x86-32 x86-64 mips32 mips64 sparc32 sparc64 ppc32 ppc64 arm32 arm64 s390x alpha
FreeBSD yes1 yes4 ? ? n/a yes10 hangs yes12 ? yes16 n/a
NetBSD yes2 yes5 ? ? yes9 yes10 no n/a ? yes16 n/a
OpenBSD ? ? ? ? yes9 yes10 hangs n/a ? yes16 n/a
GNU/Linux yes3 yes6 yes7 yes8 n/a yes10 yes11 yes13 yes14,15 yes16 yes17 yes18,19
GNU/Hurd yesTBD n/a n/a n/a n/a n/a n/a n/a n/a n/a n/a

Install details

These are rudimentary qemu guest install instructions. They assume the reader knows how to install each OS on real hardware.

You probably want to enable networking both during the install and boot process. You can either use -net tap like below, or -net -user,hostfwd=tcp::PORT-:22 for some adequate PORT number. (What "tap" means and how to do that is beyond the scope of this page, the qemu side of it is described in the qemu man page, the rest is quite system specific. It can be evil to get it right, since advanced networking is not too well designed on all systems.)

I would recommend that you initially do exactly like in these examples, since the system is fragile and even seemingly innocent deviations might lead to failure. When you have something that works, you can always go from there.

If you start several qemu guests at the same time, you might get networking problems since they by default use the same MAC address. The solution is to pass -net nic,macaddr=XX:XX:XX:XX:XX:XX, for some suitable (e.g., random) values of the X'es, different for each running qemu. Each example below uses a different MAC address.

These examples' index numbers correspond to the table above.

  1. X86-32 FreeBSD
    Download: compressed iso image
    Unpack: xz -d FreeBSD-12.2-RELEASE-i386-disc1.iso.xz
    common_args="-drive file=disk.img,if=virtio,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:01,model=virtio -net tap"
    Install:
    qemu-system-i386 $common_args -cdrom FreeBSD-12.2-RELEASE-i386-disc1.iso -boot d
    Boot:
    qemu-system-i386 $common_args
     
  2. X86-32 NetBSD
    Download: iso image
    common_args="-drive file=disk.img,if=virtio,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:02,model=virtio -net tap"
    Install:
    qemu-system-i386 $common_args -cdrom NetBSD-8.2-i386.iso -boot d
    Boot:
    qemu-system-i386 $common_args
     
  3. X86-32 Debian
    Download: iso image
    common_args="-drive file=disk.img,if=virtio,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:03,model=virtio -net tap"
    Install:
    qemu-system-i386 $common_args -cdrom debian-9.12.0-i386-netinst.iso -boot d
    Boot:
    qemu-system-i386 $common_args
     
  4. X86-64 FreeBSD
    Download: compressed iso image
    Unpack: xz -d FreeBSD-12.2-RELEASE-amd64-disc1.iso.xz
    common_args="-drive file=disk.img,if=virtio,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:04,model=virtio -net tap"
    Install:
    qemu-system-x86_64 $common_args -cdrom FreeBSD-12.2-RELEASE-amd64-disc1.iso -boot d
    Boot:
    qemu-system-x86_64 $common_args
     
  5. X86-64 NetBSD
    Download: iso image
    common_args="-drive file=disk.img,if=virtio,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:05,model=virtio -net tap"
    Install:
    qemu-system-x86_64 $common_args -cdrom NetBSD-8.2-amd64.iso -boot d
    Boot:
    qemu-system-x86_64 $common_args
     
  6. X86-64 Debian
    Download: iso image
    common_args="-drive file=disk.img,if=virtio,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:06,model=virtio -net tap"
    Install:
    qemu-system-x86_64 $common_args -cdrom debian-9.12.0-amd64-netinst.iso -boot d
    Boot:
    qemu-system-x86_64 $common_args
     
  7. MIPS32 Debian
    Last Tested with qemu 6.1.0
    Download: kernel and initrd.
    common_args="-M malta -m 256 -drive file=disk.img,if=virtio,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:07,model=virtio -net tap -nographic"
    Install:
    kernel=[...fill in name of downloaded kernel...]
    qemu-system-mipsel $common_args -kernel $kernel -initrd initrd.gz -append "console=ttyS0"
    Follow the instructions in the section Copying out Linux kernel and initrd below.
    Boot (console-less):
    kernel=[...fill in name of copied-out kernel...]
    qemu-system-mipsel $common_args -kernel boot/$kernel -initrd boot/initrd.img -append "root=/dev/vda1 console=ttyS0" -serial null -monitor null
    Notes:
  8. MIPS64 Debian
    Last tested with qemu 6.1.0 (other versions work too, older than 2.2.0 known to not work)
    Download: kernel and initrd.
    common_args="-M malta -cpu 5KEc -m 1024 -drive file=disk.img,if=virtio,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:08,model=virtio -net tap -nographic"
    Install:
    kernel=[...fill in name of downloaded kernel...]
    qemu-system-mips64el $common_args -kernel $kernel -initrd initrd.gz -append "console=ttyS0"
    Follow the instructions in the section Copying out Linux kernel and initrd below.
    Boot (console-less):
    kernel=[...fill in name of copied-out kernel...]
    qemu-system-mips64el $common_args -kernel boot/$kernel -initrd boot/initrd.img -append "root=/dev/vda1 console=ttyS0" -serial null -monitor null
    Notes:
  9. SPARC32 NetBSD
    Last tested with qemu 6.1.0
    Download: iso image
    common_args="-m 256 -drive file=disk.img,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:09 -net tap,script=/etc/qemu-ifup -nographic"
    Install:
    qemu-system-sparc $common_args -cdrom NetBSD-9.2-sparc.iso -boot d
    Boot:
    qemu-system-sparc $common_args
    Notes:
  10. SPARC64 NetBSD
    Last tested with qemu 2,10.2. (With most qeme relases networking fails in different ways; for some interface types qemu supplants the specified macaddr with a hardwired, collision-prone one, other interface types simply fail to transport any data. There are still serious problems with 6.1.0, but the default interface [hme] works OK. Unfortunately, qemu 6.x causes subtle stability problems as so is useless.)
    Download: iso image
    common_args="-m 512 -drive file=disk.img,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:10 -net tap,script=/etc/qemu-ifup -nographic"
    Install:
    qemu-system-sparc64 $common_args -cdrom NetBSD-9.2-sparc64.iso -boot d
    Boot:
    qemu-system-sparc64 $common_args
    Notes:
  11. PPC32 Debian jessie
    Last tested with qemu 3.0.1 (3.1.x through 4.1.x have problems with floating-point arithmetic, 4.2.x might work)
    Download: iso image. Note that this is an obsolete Debian release, jessie. Later Debian releases only support ppc64 (but you might want to try an inofficial Debian iso image).
    common_args="-drive file=disk.img,if=virtio,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:11,model=virtio -net tap -display vnc=:11"
    Install:
    qemu-system-ppc $common_args -cdrom debian-8.11.0-powerpc-CD-1.iso -boot d
    Perform a default install using vncviewer. Note that the boot might hang on input with a screen with minimal contrasts; just hit ENTER to continue to a readable install dialogue.
    Follow the instructions in the section Copying out Linux kernel and initrd below.
    Boot:
    qemu-system-ppc $common_args -kernel boot/vmlinux-3.16.0-4-powerpc -initrd boot/initrd.img-3.16.0-4-powerpc -append "root=/dev/vda3"
    Notes:
  12. PPC64 FreeBSD
    Last tested with qemu 6.1.0
    Download: compressed iso image
    Unpack: xz -d FreeBSD-13.0-RELEASE-powerpc-powerpc64-disc1.iso.xz
    common_args="-M pseries -cpu POWER9 -m 1024 -drive file=disk.img,if=virtio,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:12 -net tap,script=/etc/qemu-ifup -nographic -vga none"
    Install:
    qemu-system-ppc64 $common_args -cdrom FreeBSD-13.0-RELEASE-powerpc-powerpc64-disc1.iso -boot d
    Boot:
    qemu-system-ppc64 $common_args -serial null -monitor null
    Notes:
  13. PPC64 Debian
    Last tested with qemu 3.0.1 (3.1.x through 4.1.x have problems with floating-point arithmetic, 4.2.x might work)
    Download: kernel and initrd. Note that this is an obsolete Debian release, jessie. Later Debian releases lack big-endian PPC64 support (but you might want to try an inofficial Debian iso image).
    common_args="-M pseries -cpu POWER8 -m 512 -drive file=disk.img,if=virtio,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:13,model=virtio -net tap -display vnc=:13"
    Install:
    qemu-system-ppc64 $common_args -kernel vmlinux -initrd initrd.gz
    Perform a normal install using vncviewer.
    Follow the instructions in the section Copying out Linux kernel and initrd below.
    Boot:
    qemu-system-ppc64 $common_args -kernel boot/vmlinux -initrd boot/initrd.gz -append "root=/dev/vda1"
    Notes:
  14. ARM32 Debian ABI:armhf
    Last tested with qemu 4.1.0
    Download: kernel and initrd.
    common_args="-M virt -cpu cortex-a15 -m 256 -drive file=disk.img,if=none,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -netdev type=tap,id=net0 -device virtio-net-device,netdev=net0,mac=52:54:00:fa:ce:14 -nographic"
    Install:
    qemu-system-arm $common_args -kernel vmlinuz -initrd initrd.gz -append "console=ttyAMA0 --"
    Follow the instructions in the section Copying out Linux kernel and initrd below.
    Boot:
    qemu-system-arm $common_args -kernel boot/vmlinuz -initrd boot/initrd.img -append "root=/dev/vda1 rw console=ttyAMA0 --" -serial null -monitor null
  15. ARM32 Debian ABI:armel
    Last tested with qemu 2.11.1 (and many other versions; 2.7.0 causes hangs)
    Download: kernel and initrd
    common_args="-M versatilepb -m 256 -drive file=disk.img,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:15 -net tap -display vnc=:14"
    Install using vncviewer over the network:
    qemu-system-arm $common_args -kernel vmlinuz-3.16.0-6-versatile -initrd initrd.gz
    Follow the instructions in the section Copying out Linux kernel and initrd below.
    Boot:
    qemu-system-arm $common_args -kernel boot/vmlinuz -initrd boot/initrd.img -append "root=/dev/sda1"

  16. ARM64 Debian
    Last tested with qemu 4.1.0
    Download: kernel and initrd.
    common_args="-M virt -cpu cortex-a57 -m 256 -drive file=disk.img,if=none,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -netdev type=tap,id=net0 -device virtio-net-device,netdev=net0,mac=52:54:00:fa:ce:16 -nographic"
    Install:
    qemu-system-aarch64 $common_args -kernel linux -initrd initrd.gz -append "console=ttyAMA0 --"
    Follow the instructions in the section Copying out Linux kernel and initrd below.
    Boot:
    qemu-system-aarch64 $common_args -kernel boot/vmlinuz -initrd boot/initrd.img -append "root=/dev/vda1 rw console=ttyAMA0 --" -serial null -monitor null


    ARM64 FreeBSD
    Last tested with qemu 6.1.0
    Download this firmware and this disk image.
    Unpack: xz -d FreeBSD-13.0-RELEASE-arm64-aarch64.raw.xz
    Then boot this image directly:
    qemu-system-aarch64 -M virt -cpu cortex-a57 -m 256 -drive file=FreeBSD-13.0-RELEASE-arm64-aarch64.raw,if=none,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -netdev type=tap,id=net0 -device virtio-net-device,netdev=net0,mac=52:54:00:fa:de:16 -bios QEMU_EFI.fd -serial telnet::4444,server -monitor null -nographic


    ARM64 NetBSD
    Last tested with qemu 6.1.0
    Download this firmware and this disk image.
    Unpack: gunzip arm64.img.gz
    Then boot this image directly:
    qemu-system-aarch64 -M virt -cpu cortex-a57 -m 256 -drive file=arm64.img,if=none,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -netdev type=tap,id=net0 -device virtio-net-device,netdev=net0,mac=52:54:00:fa:ee:16 -bios QEMU_EFI.fd -serial telnet::4444,server -monitor null -nographic


    ARM64 OpenBSD
    Last tested with qemu 6.1.0

    OpenBSD can also be made to work for ARM64. They don't provide a ready image, so we need to install things in a more standard fashion. Note that virtio devices don't work properly (with OpenBSD 6.9).

  17. S/390 Debian
    Last tested with qemu 2.11.1
    Download: kernel and initrd.
    common_args="-M s390-ccw-virtio -m 512 -drive file=disk.img,if=none,format=raw,id=hd0 -device virtio-blk-ccw,drive=hd0,id=virtio-disk0 -netdev type=tap,id=net0 -device virtio-net-ccw,netdev=net0,mac=52:54:00:fa:ce:17,devno=fe.0.0001 -nographic"
    Install:
    qemu-system-s390x $common_args -kernel kernel.debian -initrd initrd.debian
    Perform a default install using the terminal. This Debian install is somewhat unusual, but you'll be instructed by the installer.
    After installation finishes, follow the instructions in the section Copying out Linux kernel and initrd below.
    Boot:
    qemu-system-s390x $common_args -kernel boot/vmlinuz -initrd boot/initrd.img -append "root=/dev/vda1"
  18. Alpha Debian (obsolete release!)
    Last tested with qemu 2.6.2 (newer probably works too).
    Download: iso, kernel and initrd.
    Uncompress vmlinuz to vmlinux.
    common_args="-m 256 -drive file=disk.img,media=disk,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:18 -net tap -nographic"
    Install:
    qemu-system-alpha $common_args -kernel vmlinux -initrd initrd.gz -drive file=debian-5010-alpha-netinst.iso,if=ide,media=cdrom -append "console=ttyS0"
    Follow the instructions in the section Copying out Linux kernel and initrd below.
    Boot:
    qemu-system-alpha $common_args -kernel boot/vmlinux -initrd boot/initrd.img -append "root=/dev/hda3 console=ttyS0"
  19. Alpha Gentoo
    Last tested with qemu 2.11.1.
    Download: install-alpha-minimal-[DATE1].iso from current-iso and stage3-alpha-[DATE2].tar.bz2 from current-stage3 for suitable values of [DATE1] and [DATE2]. Grab the latest if there is a choice.

    Qemu's Alpha firmware (SRM) is not ready and is probably not yet useful for anything. Therefore, we need to boot a kernel directly.

    I've tried hard to make the kernel use the installation ISO as root image (with and without Gentoo's initrd image gentoo.igz), but the cdrom isn't found and a kernel panic ensues. I therefore use the trick of copying the ISO's contents into a temporary disk image ("inst-disk.img").

    Note that these commands assume a GNU/Linux host (mkfs.ext3 command and loop mount syntax are non-portable). The end result should run under other OSes, though.

    I recommend that you cut-and-paste the commands here and follow the progress of each command. The "set -e" is there should you be tempted to use it as a script; do not issue it to an interactive shell or you will find yourself logged out before long!

    ISO=install-alpha-minimal-[DATE1].iso
    TARG=try1		# Subdir where to put results
    DISK_SIZE=16		# Disk size in GiB, should be >= 6
    
    set -e			# Don't paste this command to an interactive shell!
    
    mkdir $TARG
    cd $TARG
    
    mkdir iso iso_sub targ
    
    mount $ISO iso
    
    # Copy out a useful kernel from ISO
    zcat iso/boot/gentoo >kernel
    touch -r iso/boot/gentoo kernel
    
    # Prepare temporary install image "inst-disk.img".
    mount iso/image.squashfs iso_sub
    truncate --size 2G inst-disk.img
    mkfs.ext3 inst-disk.img
    mount inst-disk.img targ
    cp -a iso_sub/* targ
    
    # Edit inst-disk.img to not scramble the root password.
    sed --in-place="" 's/echo/#echo/' targ/etc/init.d/pwgen
    
    # Edit inst-disk.img password files to make initial root password empty.
    sed --in-place="" 's/^root:[^:]*:/root::/' targ/etc/passwd
    sed --in-place="" 's/^root:[^:]*:/root::/' targ/etc/shadow
    
    # Edit inst-disk.img config to allow root logins (but do not start ssh yet!).
    sed --in-place="" 's/.*PermitRootLogin.*/PermitRootLogin yes/' targ/etc/ssh/sshd_config
    
    umount targ
    umount iso_sub
    umount iso
    
    # Create main disk image.
    truncate --size ${DISK_SIZE}G disk.img
    
    # Clean up
    rmdir iso iso_sub targ
    
    That finishes the disk preparations. Now it is time to boot up the system and continue installation.
    common_args="-smp 4 -m 512 -display vnc=:19 -serial null -monitor null"
    Install:
    qemu-system-alpha $common_args -kernel kernel -drive file=disk.img,media=disk,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:19,model=e1000 -net tap -drive file=inst-disk.img,media=disk,format=raw,index=1 -append "root=/dev/sdb"
    Perform an almost plain Gentoo installation using vnc. Be warned that this is a difficult installation even for being Gentoo, since things are highly inconsistent; commands do not work as suggested or documented, partition numbers and names vary between wrong and dead wrong, etc, etc. Things to consider: Boot:
    qemu-system-alpha $common_args -kernel vmlinux -drive file=disk.img,if=virtio,media=disk,format=raw,index=0 -net nic,macaddr=52:54:00:fa:ce:19,model=virtio -net tap -append "root=/dev/vda"
    Notes:
    As an alternative, download the pre-installed 333 MiB image disk.img.xz. This unpacks into a 10 GiB sparse file.
    sha256: e69bf91c098b8cd54805a09b78e3fc93b18a13bb65cef845c52f0e7817837151 img.xz
    sha256: 63feacbfccc6747603f32d06a1cacd1d87b5fd777edaf90ded33b64e2004ba37 img
    The image can be booted by this sh script which also needs this kernel. CAUTION: The root password is "x". Security experts might consider that to be a tad too short. Therefore, I highly recommend that you comment out the -net line from the boot script, make an initial boot and connect using vncviewer :5919, change the root password to something sensible, halt the system, and then re-instate the -net line before re-booting the system. (If there is access from the Internet to the vnc port, the suggested precaution isn't going to do much good. A vnc password would give some level of protection, though.)

Copying out Linux kernel and initrd

When a boot loader cannot be installed, as in many cases above, one needs to supply a kernel and some initial files via an "initrd". In the case of GNU/Linux, the needed files should be in /boot at the end of installation.

There are several alternative ways one may copy these files to the host file system.

  1. Just before the end of the installation.

    In Debian (and presumably several of its derivatives), just as the Finishing the installation/Installation complete step is performed, choose Go back and then scroll down the menu to Execute a shell. In that shell do:

    mount -t proc proc /target/proc
    mount --rbind /sys /target/sys
    mount --rbind /dev /target/dev
    chroot /target bash
    /etc/init.d/ssh start

    Then, from the host system, do

    ssh -p [arguments] [host] "tar -c -f - --exclude=lost+found /boot" | tar xf -

    where [arguments] should be any required port number and [host] is the IP address or name of the target host, or perhaps "localhost" if port forwarding was used. Note that root logins might not work unless you edit /etc/ssh/sshd_config to allow root login.

    Return to the installation screen, and exit the shell, and choose Finishing the installation.

  2. Let the installation finish, then mount the disk image read-only from the host. This will usually work, but it might be hard if the host system cannot grok the disk label. Typically,

    { echo p; echo q; } | fdisk disk.img

    will work. You should see a list such as:

    disk.img1 *       2048  333823  331776  162M 83 Linux
    disk.img2       333824 3893247 3559424  1.7G 83 Linux
    disk.img3      3895294 4192255  296962  145M  5 Extended
    disk.img5      3895296 4192255  296960  145M 82 Linux swap / Solaris

    You can now mount the partitions. To mount the first partition above on a GNU/Linux host, this should work:

    mount -o loop,ro,offset=$((2048*512)) disk.img /mnt

    If /boot lives in the 2nd partition above, use this instead:

    mount -o loop,ro,offset=$((333824*512)) disk.img /mnt

    Now just copy the files from /mnt. Don't forget to do:

    umount /mnt
    .

  3. Use qemu-nbd. I haven't tried that myself.

Now, point the -kernel and -initrd arguments to the files in just copied-out directory boot. Exact arguments appear in each example above.


Please send corrections and any additional instructions to tg at gmplib dot org