SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: How to get QEMU to run an ARM Thumb binary?
SUBSCRIBE
SoCSoC
Font ResizerAa
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Search
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Have an existing account? Sign In
Follow US
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
© S-O-C.ORG, All Rights Reserved.
Arm

How to get QEMU to run an ARM Thumb binary?

David Moore
Last updated: September 14, 2023 12:22 pm
David Moore 8 Min Read
Share
SHARE

Getting QEMU to run an ARM Thumb binary requires configuring QEMU to emulate an ARM processor in Thumb mode. The key steps are: choosing the right ARM emulator in QEMU, enabling Thumb mode, setting up the memory layout, and specifying the ARM binary to load. With the right settings, QEMU can successfully execute ARM Thumb binaries for testing and development purposes.

Contents
Introduction to ARM ThumbChoosing the ARM Emulator in QEMUEnabling Thumb Mode in QEMUSetting Up Memory LayoutSpecifying the Thumb BinaryLaunching QEMU with Thumb BinaryVerifying Thumb Execution in QEMULimitations of Thumb EmulationConclusion

Introduction to ARM Thumb

Thumb is an instruction set architecture (ISA) variant of the ARM processor architecture. It is more compact (has higher code density) than the standard 32-bit ARM ISA, with 16-bit Thumb instructions instead of 32-bit instructions. This allows better performance in constrained environments where code size matters.

The Thumb ISA is a subset of the ARM ISA. All Thumb instructions have equivalent ARM instructions, but Thumb code is not directly executable on ARM processors without some mode switching. ARM processors since the ARMv4T architecture have support for a Thumb mode which allows seamlessly switching between ARM and Thumb instruction sets.

When compiling code for ARM, the -mthumb compiler switch generates Thumb code instead of ARM code. The resulting binary contains either Thumb or Thumb-2 instructions. Thumb-2 was introduced in ARMv6T2 and has some 16-bit and some 32-bit instructions for better performance while retaining small code size.

Choosing the ARM Emulator in QEMU

QEMU supports emulating a variety of ARM chips. To run Thumb code, you need to choose an ARM emulator in QEMU that supports Thumb instructions. Here are some options:

  • arm926ej-s – ARM9TDMI core with ARMv5TEJ architecture, supports Thumb and Jazelle (for Java acceleration)
  • arm1136-r2 – Cortex-R1136 core with ARMv6 architecture, includes Thumb-2 and VFPv2
  • cortex-a8 – Cortex-A8 core with ARMv7-A architecture, supports Thumb-2 and NEON advanced SIMD
  • cortex-a15 – Cortex-A15 core with ARMv7-A architecture, supports Thumb-2 and NEON

For example, to emulate a Cortex-A8 processor, pass the -M cpu=cortex-a8 option to QEMU: qemu-arm -M cpu=cortex-a8 [other options…]

Enabling Thumb Mode in QEMU

By default, the emulated ARM CPU will start in ARM state and expect ARM instructions. To run Thumb binaries, the CPU’s Thumb state must be enabled first.

There are two ways to do this in QEMU:

  1. Start emulation with semihosting enabled. The semihosting syscall interface will automatically transition the processor into Thumb state.
  2. Modify the CPU’s CPSR register value to change the T bit/Thumb state bit before loading the binary. This can be done using the GDB stub or QEMU monitor.

For example, to enable Thumb mode with semihosting when launching QEMU: qemu-arm [..] -g 1234 -semihosting-config enable=on,target=native [..]

Or to modify the CPSR register to set T bit using the GDB stub: (gdb) target remote :1234 (gdb) set $cpsr = $cpsr | (1 << 5)

Setting Up Memory Layout

The ARM emulator in QEMU loads the binary at address 0x00008000 by default. But Thumb binaries are position-independent code (PIC) and expect to be loaded at address 0x00000000.

To load the Thumb binary at the right base address, the memory and code entry point need to be set up properly. This can be done by specifying the -kernel option in QEMU: qemu-arm [..] -kernel my_thumb_binary.elf [..]

This will load the binary at the base address 0x00000000 as needed for Thumb PIC code.

Alternatively, a simple bootloader can be used to load the Thumb binary into the correct memory location. The bootloader code runs in ARM state, copies the Thumb binary to address 0x00000000, enables Thumb state, and jumps to the entry point to begin Thumb execution.

Specifying the Thumb Binary

Finally, the compiled Thumb binary must be passed to QEMU to load into the emulated ARM machine.

For an ELF formatted Thumb binary, use the -kernel option: qemu-arm [..] -kernel my_thumb_binary.elf [..]

For a raw binary, load it using the -mtdblock option: qemu-arm [..] -mtdblock my_thumb_binary.bin [..]

Make sure to compile your ARM program to target Thumb, for example with gcc: $ gcc -mthumb -o my_thumb_binary.elf mycode.c

Launching QEMU with Thumb Binary

Putting all of this together, a typical QEMU launch command to run an ARM Thumb binary would be: qemu-arm -M cpu=arm926ej-s -m 256 -kernel my_thumb_binary.elf -semihosting-config enable=on,target=native -g 1234

This emulates an ARM926EJ-S core with 256MB RAM, loads the Thumb ELF binary using the -kernel option, enables semihosting to start in Thumb state, and opens port 1234 for GDB debugging.

Verifying Thumb Execution in QEMU

To verify the ARM emulator is actually running Thumb code correctly, we can check the value of the CPSR register as well as watch Thumb-specific instructions being executed.

In the GDB session, CPSR will show the Thumb state bit enabled: (gdb) info reg cpsr cpsr 0x000000d3 219

Single stepping through instruction execution with stepi should show 16-bit Thumb instructions like push, pop, mov, cmp etc. This confirms the CPU is decoding and running Thumb binary instructions.

Limitations of Thumb Emulation

QEMU’s emulated ARM CPU may have some limitations or deviations when running Thumb code compared to real hardware. A few things to watch out for:

  • Timing – Instruction timings may not exactly match a real chip
  • Undocumented opcodes – Behavior of illegal instruction exceptions may differ
  • CP15/CP14 differences – Thumb EE state handling may not be fully emulated
  • No Thumb-2 support – Only basic Thumb instruction set is implemented

For more thorough testing, real ARM hardware or an FPGA prototype is recommended. QEMU is best suited for general software development and experimentation with Thumb.

Conclusion

QEMU is capable of emulating ARM processors in Thumb execution state, allowing ARM Thumb binaries to be run. Key steps are choosing the right ARM emulator, enabling Thumb mode, configuring the memory layout, and loading the Thumb binary. With the proper configuration, the powerful ARM emulation capabilities of QEMU can be leveraged for working with Thumb code.

Some limitations exist compared to real hardware, so care must be taken when testing corner cases. But overall, running ARM Thumb programs on QEMU is a useful development tool for software targeting the Thumb ISA and embedded ARM processors.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article What is the instruction set of the Cortex-M0?
Next Article How to start ARM Cortex programming using embedded C?
Leave a comment Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

2k Followers Like
3k Followers Follow
10.1k Followers Pin
- Sponsored-
Ad image

You Might Also Like

What is bootloader in ARM?

A bootloader is a small program that runs when an…

8 Min Read

ARM Cortex-M7 Boot Sequence

The ARM Cortex-M7 is a high-performance processor core designed for…

7 Min Read

Workarounds for GNU-ARM Compiler Inefficiencies on Cortex-M0/M1

The GNU ARM compiler (arm-none-eabi-gcc) is a widely used toolchain…

6 Min Read

Interfacing ARM Cortex-M1 and Altera Virtual JTAG on FPGAs

Connecting an ARM Cortex-M1 processor to an Altera FPGA using…

8 Min Read
SoCSoC
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
Welcome Back!

Sign in to your account