← All technical notes FIELD NOTES / Microkit / Debugging

Debugging Microkit in QEMU: A Working Checklist

A repeatable approach to isolating toolchain, image-generation, and boot failures.

2 min read

The first time a Microkit image boots in QEMU, the console output is satisfying. The next challenge is making failures easy to diagnose.

This note builds on the toolchain walkthrough and organizes debugging around the stages of the build rather than guessing at a single cause.

Separate the Stages

I divide the path into four checkpoints: compile a protection domain, link its ELF, generate the Microkit loader image, and boot that image in QEMU.

A compiler error is not an emulator problem. A missing ELF is not a capability problem. Keeping those boundaries clear saves time.

Record the Environment

Start by capturing the tool versions and SDK selection:

uname -m
cat "$MICROKIT_SDK/VERSION"
"$MICROKIT_SDK/bin/microkit" --help
qemu-system-aarch64 --version

On macOS and Ubuntu, the cross-compiler names may differ. Record the actual compiler used by your build and verify that the resulting ELF targets AArch64.

file build/*.elf
ls -lh build/loader.img build/report.txt

The file utility's description is a useful quick check, but it is not a substitute for validating the ELF and linker configuration.

Read the First Useful Error

For compilation failures, check include paths and target flags. For linker failures, check the selected board library and linker script. For image-generation failures, inspect the system description and the Microkit diagnostic.

For a boot that appears silent, verify the QEMU machine, CPU, guest memory, loader address, and console options against the versioned manual. Avoid changing several variables at once.

Make the Experiment Repeatable

Save the exact command line, tool versions, and relevant console output alongside each result. A short record of what changed between two runs is often more useful than a large undifferentiated log.

The goal is not to claim a successful test I have not run. It is to make the next test easy to reproduce.

References