Linux VPS

Emulation vs virtualization: run ARM VMs and binaries on x86 with QEMU

Understand the difference between emulation and virtualization, run an ARM64 VM on an x86 host with QEMU TCG, run foreign binaries with qemu-user and binfmt, and build multi-arch Docker images.

AdvancedLinux hosts2 min read

Virtualization runs guests on the same CPU architecture at near-native speed. Emulation translates instructions from one architecture to another, which is slower but lets you run, for example, ARM software on an Intel or AMD server. This guide shows how to use QEMU emulation to run ARM on x86.

Before you start

  • A Linux machine (a VPS works; emulation does not need KVM).
  • Patience: emulated systems typically run several times slower than native.

Emulation vs virtualization

Virtualization (KVM)Emulation (QEMU TCG)
Guest architectureSame as hostAny supported
SpeedNear nativeMuch slower
Needs VT-x/AMD-VYesNo
UseProduction VMsTesting, cross-builds, legacy systems

See full vs paravirtualization for virtualization techniques.

Run a full ARM64 VM

sudo apt install -y qemu-system-arm qemu-efi-aarch64 qemu-utils

Download an ARM64 cloud image (e.g. Ubuntu's noble-server-cloudimg-arm64.img), then:

qemu-img resize noble-server-cloudimg-arm64.img 20G
qemu-system-aarch64 -M virt -cpu max -smp 2 -m 2048 -bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd -drive if=virtio,file=noble-server-cloudimg-arm64.img -drive if=virtio,format=raw,file=seed.img -nic user,hostfwd=tcp::2222-:22 -nographic

The seed.img is a cloud-init NoCloud disk with your user and SSH key (create it with cloud-localds; see cloud-init user-data). Then ssh -p 2222 user@localhost.

Run single ARM binaries with qemu-user

sudo apt install -y qemu-user-static binfmt-support

binfmt registers handlers so the kernel automatically runs foreign binaries through QEMU. Check:

ls /proc/sys/fs/binfmt_misc/ | grep qemu

Build multi-arch Docker images

With binfmt handlers installed, Docker Buildx can build ARM images on x86:

docker buildx create --use --name multi
docker buildx build --platform linux/amd64,linux/arm64 -t registry.example.com/app:latest --push .

Emulated builds are slow; native ARM builders are faster for large projects.

Troubleshooting

  • "exec format error": binfmt handlers are not registered; reinstall qemu-user-static or run the binfmt setup container.
  • VM hangs at boot with no output: wrong firmware path or missing -nographic/serial console.
  • Extremely slow: expected for emulation; reduce workload or use native hardware.

Frequently asked questions

Can KVM accelerate ARM guests on x86?

No. KVM only accelerates guests of the host's own architecture.

Is Apple's Rosetta the same idea?

It is also binary translation, highly optimised for one direction (x86 to ARM).

Should I run production ARM workloads emulated?

No, rent ARM hardware instead; see ARM servers explained.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.