Run Debian in QEMU

2 minute read

Published:

One need we recently met was to directly trigger syscalls in QEMU. To achieve this, we have to run Linux with pre-installed dev tools such as vim and gcc, and most importantly, package managers like apt. Thanks to debootstrap, such a subsystem can be setup within minutes.

Prerequisites

$ sudo apt install debootstrap
$ sudo apt install libguestfs-tools

Among the above commands, libguestfs-tools contains the command-line app we need to create the image: virt-make-fs.

Prepare Packages with debootstrap

First, create the root subdirectory and create the rootfs:

$ sudo mkdir /stable-chroot
$ sudo debootstrap stable /stable-chroot http://deb.debian.org/debian

(Optional) Make RootFS for AArch64 Platform

Alternatively, you can make a cross-platform rootfs. Take aarch64 rootfs as an example, we first invoke debootstrap with --arch arm64 and --foreign parameter (for multi-stage building).

$ sudo debootstrap --arch arm64 --foreign stable /stable-chroot http://deb.debian.org/debian

Copy qemu-aarch64-static into rootfs (you may install qemu-user-static package at first):

$ sudo cp -av /usr/bin/qemu-aarch64-static /stable-chroot/usr/bin

Change root and invoke debootstrap for the second stage:

$ sudo chroot /stable-chroot

$ /debootstrap/debootstrap --second-stage
I: Installing core packages...
...
I: Base system installed successfully.

Create Image

Create an image from the rootfs:

$ sudo virt-make-fs --type=ext4 --size=2G /stable-chroot rootfs.img

Boot with QEMU

In this step, boot Debian subsystem with QEMU:

$ qemu-system-x86_64 -smp 4 -m 8G \
  -kernel path/to/linux/arch/x86_64/boot/bzImage \
  -append "nokaslr console=ttyS0 root=/dev/sda rw" \
  -drive file=path/to/rootfs.img,format=raw \
  -nographic -netdev user,id=net0 -device e1000,netdev=net0 \

Among the options:

  • -smp and -m specify the number of vcpu and the size of memory
  • Alternate the path in -kernel option
  • -append specifies the kernel arguments
  • Alternate the path in -drive option
  • -netdev and -device specify the NIC mode and device for guest OS

(Optional) Run in AArch64 QEMU:

In aarch64-based QEMU, we have to make changes to some parameters:

  • Add model and cpu parameter: -M virt -cpu max
  • -append parameter would be "nokaslr console=ttyAMA0 root=/dev/vda rw".

A complete command example:

$ qemu-system-aarch64 -M virt -cpu max -smp 4 -m 8G \
  -kernel linux-6.0.9/arch/arm64/boot/Image.gz -drive file=rootfs.img,format=raw \
  -append "nokaslr console=ttyAMA0 root=/dev/vda rw" \
  -nographic -netdev user,id=net0 -device e1000,netdev=net0 \

Post-Boot Operations

Once you have successfully booted the system, we are almost there.

Enter root as the login account:

IBM5100 login: root

To configure network connections, use dhclient to request ip address:

$ dhclient -v
Internet Systems Consortium DHCP Client 4.4.1
Copyright 2004-2018 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/.

[   80.422178] e1000: enp0s3 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
[   80.423984] IPv6: ADDRCONF(NETDEV_CHANGE): enp0s3: link becomes ready
[   80.425745] ip (225) used greatest stack depth: 12880 bytes left
Listening on LPF/enp0s3/52:54:00:12:34:56
Sending on   LPF/enp0s3/52:54:00:12:34:56
Sending on   Socket/fallback
DHCPREQUEST for 10.0.2.15 on enp0s3 to 255.255.255.255 port 67
DHCPACK of 10.0.2.15 from 10.0.2.2
bound to 10.0.2.15 -- renewal in 39689 seconds. 

running

Inspect your Debian system