Skip to content
Back to skills

Qemu Embedded Simulation

ASecurity

Use when running ARM or RISC-V bare-metal firmware in QEMU: machine selection, -kernel ELF loading, semihosting, or GDB debugging without hardware. Not for KVM guests: use qemu-kvm.

  • 54 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 20, 2026
ai-agentsgobashdebuggingdocumentation

Works with

  • mcp

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 20, 2026

npx -y skills add OutlineDriven/outline-driven-development --skill qemu-embedded-simulation --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Qemu Embedded Simulation?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Qemu Embedded Simulation
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/outlinedriven-qemu-embedded-simulation-outline-driven-development/badge)](https://www.skillsdirectory.com/skills/outlinedriven-qemu-embedded-simulation-outline-driven-development)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: qemu-embedded-simulation
description: 'Use when running ARM or RISC-V bare-metal firmware in QEMU: machine selection, -kernel ELF loading, semihosting, or GDB debugging without hardware. Not for KVM guests: use qemu-kvm.'
disable-model-invocation: true
---

# QEMU embedded simulation

## Contract

| Field | Bound contract |
|---|---|
| Trigger | Bare-metal or RTOS firmware needs running without a board: Cortex-M on a QEMU STM32 machine, RISC-V on `virt`, a GDB stub session, or semihosting output. |
| Authority | Read-only. Emits analysis and commands for the operator to run; no file writes, no rollback needed. No remote mutation. |
| Side effect | QEMU command lines and a verdict in chat. Nothing is written. |
| Done | The firmware boots under the chosen machine, or the blocking limitation (unmodeled peripheral, wrong machine) is named. |

## Inputs

1. Firmware image (required): an ELF or binary linked for the target machine's memory map.
2. Target machine (required): the MCU or `virt` machine the firmware was built for.
3. Toolchain (required): `qemu-system-arm`, `qemu-system-aarch64`, or `qemu-system-riscv32/64`, plus a matching `*-gdb` for debug sessions.

## Procedure

1. Pick a Cortex-M machine. QEMU models a subset of STM32 boards, per the QEMU STM32 documentation:

   | Machine | MCU | Core |
   |---|---|---|
   | `stm32vldiscovery` | STM32F100RBT6 | Cortex-M3 |
   | `netduino2` | STM32F205RFT6 | Cortex-M3 |
   | `netduinoplus2` | STM32F405RGT6 | Cortex-M4F |
   | `olimex-stm32-h405` | STM32F405RGT6 | Cortex-M4F |

   ```bash
   arm-none-eabi-gcc -mcpu=cortex-m3 -T linker.ld -o firmware.elf main.c startup.s
   qemu-system-arm -machine stm32vldiscovery -kernel firmware.elf \
     -nographic -serial mon:stdio
   ```

   `-kernel` accepts an ELF or a raw binary. List machines with `qemu-system-arm -machine help`. Match `-mcpu` and the linker map to the machine's MCU; `stm32vldiscovery` is an F100, not an F407. Done when: the firmware reaches `main` under the right machine.
2. Use generic `virt` for Cortex-A code.

   ```bash
   qemu-system-aarch64 -machine virt -cpu cortex-a53 -m 128M \
     -kernel firmware.elf -nographic
   ```

   Done when: the image boots on `virt`.
3. Run RISC-V bare metal.

   ```bash
   qemu-system-riscv32 -machine virt -nographic \
     -bios none -kernel firmware.elf
   ```

   `-bios none` starts at the reset vector with no OpenSBI. Done when: the image runs from its reset entry.
4. Debug through the GDB stub.

   ```bash
   qemu-system-arm -machine stm32vldiscovery -kernel firmware.elf \
     -S -gdb tcp::3333 -nographic
   ```

   ```gdb
   arm-none-eabi-gdb firmware.elf
   (gdb) target remote :3333
   (gdb) monitor system_reset        # QEMU monitor command over the stub
   (gdb) load                        # write ELF sections into target memory
   ```

   `-S` halts the CPU at reset so GDB connects before any instruction runs. Done when: GDB controls the emulated target.
5. Enable semihosting when the toolchain supports it.

   ```bash
   qemu-system-arm ... -semihosting-config enable=on,target=native
   ```

   Semihosting routes `printf` and friends to the host through a syscall trap; the C library must be built with semihosting support. Done when: firmware output reaches the console without a UART model.
6. Respect the limitations. Per QEMU's STM32 machine documentation:

   | Gotcha | Reality |
   |---|---|
   | No GPIO | The GPIO controller is not modeled; LED-blink tests need hardware or another machine |
   | No DMA or I2C | Not implemented on the STM32 machines |
   | Partial RCC | Reset and enable only; no full clock tree |
   | Wrong MCU assumed | `stm32vldiscovery` is an F100 Cortex-M3; match CPU flags and linker memory |
   | Timing | Not cycle-accurate against silicon |

   Validate on hardware before sign-off. Done when: the test plan accounts for every unmodeled peripheral the firmware touches.

## Failure and recovery

| Symptom | Cause | Fix |
|---|---|---|
| QEMU exits immediately | `main` returned | End with a loop or `WFI` |
| Wrong entry address | ELF not linked for the machine | Check `readelf -h` entry against the memory map |
| No serial output | Wrong UART model address | Use the machine's UART map or semihosting |
| GDB cannot connect | Missing `-S` or `-gdb` | Add `-S -gdb tcp::3333` |
| HardFault in QEMU | Invalid stack or vector table | Fix startup; see `baremetal-startup` |

## Output

A working QEMU command line for the firmware and machine, the GDB stub session when debugging, and the named list of unmodeled peripherals that force hardware validation.

Files in this skill

  • SKILL.md4.5 KB
  • agents/openai.yaml225 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…