With QEMU you can boot an embedded Linux system directly on your host PC without needing real hardware. For this walkthrough we use Poky, the Yocto Project's reference build system. It is compact, easy to extend and includes all the tools needed to get started building, running and testing Linux images.
The steps shown here are not limited to Poky — they transfer directly to your own images, for example on SoC platforms like i.MX. The workflow for building, booting and testing stays essentially the same; only the target machine and additional layers differ.
These characteristics make Poky an ideal starting point for gaining hands-on experience with emulators and integrating automated tests into the development process. This article covers the full workflow: from downloading the sources, through the image build, to booting in QEMU and running tests.
Prerequisites
- A Linux host system (e.g. Ubuntu or Fedora)
- git, tar and standard build tools (gcc, make, python3, etc.)
- At least 50 GB of free disk space
Step 1: Clone the Poky Repository
git clone git://git.yoctoproject.org/poky
cd poky
Optionally, check out a stable branch, e.g. scarthgap:
git checkout scarthgap
Step 2: Initialise the Build Environment
source oe-init-build-env
This creates the build/ directory. Settings in conf/local.conf can be adjusted, for example the number of parallel jobs:
BB_NUMBER_THREADS = "8"
PARALLEL_MAKE = "-j 8"
Step 3: Build the Image
A minimal image:
bitbake core-image-minimal
Depending on your hardware the build can take several hours. The output is located at:
build/tmp/deploy/images/qemux86-64/
Step 4: Boot the Image in QEMU
Poky ships a launch script:
runqemu qemux86-64
This boots a virtual system via QEMU. A login shell appears (default user: root, no password).
Step 5: Run Tests
The Yocto Project supports a test infrastructure (oeqa). Custom tests can be added as Python test cases under meta/lib/oeqa/runtime/. Here is an example ping test:
from oeqa.runtime.case import OERuntimeTestCase
from oeqa.core.decorator.oetimeout import OETimeout
class PingTest(OERuntimeTestCase):
@OETimeout(60)
def test_ping(self):
status, output = self.target.run("ping -c 3 8.8.8.8")
self.assertEqual(status, 0, msg="Ping failed:\n%s" % output)
Step 6: Failure Analysis
If tests fail:
- Check
build/tmp/log/oeqa/ - Start QEMU interactively with
runqemu - Inspect log files in
build/tmp/work/.../temp/log.do_*
Conclusion
QEMU provides a flexible way to boot embedded Linux images quickly and independently of real hardware. Developers can use it to trace the boot process, verify functionality and run automated tests. Poky is used here purely as an example for image creation — the same workflow applies equally to custom or board-specific builds, such as for i.MX.
This makes QEMU a valuable tool in embedded development: for early prototyping, continuous testing and stable release processes.

