(2) QEMU (with WSL)

박서경박서경
4 min read

Once the OS is somewhat complete, I plan to create a bootable USB and test it on a real PC.
But during development, I'll use an emulator for quick testing.
Let’s learn about QEMU, a must-have tool for any budget-conscious developer!

✅ What is QEMU?

QEMU (Quick EMUlator) is:

  • A full-system emulator that virtualizes entire hardware platforms in software

  • Or a virtual machine hypervisor

  • It allows you to simulate various operating systems and CPU architectures directly on your PC


✅ What You Can Do with QEMU

FieldExample Use Cases
🧪 OS DevelopmentBoot and test your own OS directly in QEMU
💻 UEFI TestingRun .efi files like BOOTX64.EFI for UEFI experiments
🔧 Kernel DebuggingConnect GDB for real-time kernel-level debugging
🔍 Malware AnalysisAnalyze low-level code without a full sandbox setup
💾 Bootloader DevelopmentExperiment with GRUB, Stage1/Stage2 bootloaders
🧱 Embedded Device EmulationEmulate ARM or RISC-V boards for development

✅ Key Concepts

TermDescription
EmulatorSimulates hardware components like CPU, memory, and disks in software
HypervisorRuns guest code directly on the host CPU for better performance
ImageA virtual disk file (e.g., .img, .iso, .vmdk) used to boot systems
Machine TypeSpecifies the architecture: x86, ARM, RISC-V, etc.
OptionsFlexible runtime flags like -drive, -m, -smp, -bios, -kernel, -nographic, etc.

✅ How to Install QEMU in WSL (Ubuntu-based)

📌 1. Check if you're using Ubuntu in WSL

lsb_release -a

📦 2. Install QEMU Packages

The installation method may vary depending on the version.

In My case,

sudo apt update
sudo apt install qemu-system-x86 qemu-utils ovmf
PackageDescription
qemu-system-x86Includes executables for x86 system emulation (e.g., qemu-system-x86_64)
qemu-utilsTools for creating and converting disk images (e.g., qemu-img)
ovmfProvides UEFI BIOS firmware file (OVMF.fd)

🔍 3. Verify Installation

qemu-system-x86_64 --version

✅ Booting BOOTX64.EFI with QEMU

You are creating a bootable UEFI disk image (disk.img) and copying your custom UEFI executable (BOOTX64.EFI) into the correct location. This image will later be used to test UEFI booting using QEMU.

https://github.com/eumgil0812/OwnOS

You can use first_BOOT64.EFI as BOOTX64.EFI from my git.

We refer to such programs—like BOOTX64.EFI—as UEFI applications.

A UEFI (Unified Extensible Firmware Interface) application is a binary executable that runs in the UEFI environment, before any operating system is loaded. These applications are usually written in C and compiled into PE32+ (Portable Executable) format, similar to Windows executables.


📜 Step-by-step Explanation


qemu-img create -f raw disk.img 200M
  • 🔹 Creates a 200MB raw disk image named disk.img.

  • 🔹 -f raw specifies the format as raw (unstructured, plain disk image).


mkfs.fat -n 'OWN OS' -s 2 -f 2 -R 32 -F 32 disk.img
  • 🔹 Formats the image as a FAT32 filesystem, which is required for UEFI boot.

  • 🔸 -n 'OWN OS': Sets the volume label.

  • 🔸 -s 2: Sets sectors per cluster.

  • 🔸 -f 2: Uses 2 FAT tables.

  • 🔸 -R 32: Reserves space for 32 root directory entries.

  • 🔸 -F 32: Explicitly chooses FAT32 format.


mkdir -p mnt
  • 🔹 Creates a directory named mnt to mount the disk image.

  • 🔹 -p ensures any missing parent directories are created as well.


sudo mount -o loop disk.img mnt
  • 🔹 Mounts the disk image to mnt using a loop device (treats the image as a virtual block device).

sudo mkdir -p mnt/EFI/BOOT
  • 🔹 Creates the standard UEFI boot path EFI/BOOT/ inside the mounted image.

  • 🔹 This is where UEFI looks for the bootloader by default.


sudo cp BOOTX64.EFI mnt/EFI/BOOT/BOOTX64.EFI
  • 🔹 Copies your compiled UEFI application (BOOTX64.EFI) into the boot path.

  • 🔹 This is the default filename that UEFI firmware expects when booting.


sudo umount mnt
  • 🔹 Unmounts the disk image, finalizing it for use with QEMU or real hardware.

The code you've implemented so far can be summarized as follows:

qemu-img create -f raw disk.img 200M

mkfs.fat -n 'OWN OS' -s 2 -f 2 -R 32 -F 32 disk.img

mkdir -p mnt
sudo mount -o loop disk.img mnt

sudo mkdir -p mnt/EFI/BOOT
sudo cp BOOTX64.EFI mnt/EFI/BOOT/BOOTX64.EFI

sudo umount mnt

Finally, let’s run QEMU.

This QEMU command can be interpreted as follows:

qemu-system-x86_64 \
  -drive format=raw,file=disk.img \
  -bios /usr/share/ovmf/OVMF.fd

🔍 Explanation:

  • qemu-system-x86_64: Launches a QEMU virtual machine emulating a 64-bit x86 system.

  • -drive format=raw,file=disk.img: Attaches disk.img as a virtual hard drive in raw format.

  • -bios /usr/share/ovmf/OVMF.fd: Specifies the BIOS firmware to use — in this case, UEFI firmware provided by OVMF.

✅ In short, this command runs QEMU with UEFI firmware to boot the BOOTX64.EFI file inside disk.img.

“Hello world!”

0
Subscribe to my newsletter

Read articles from 박서경 directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

박서경
박서경