/
TF-M and QEMU 4.0 (Native)

TF-M and QEMU 4.0 (Native)

This guide walks you through the process of buildng TF-M secure and non-secure binaries, merging the outputs into a single file, and running the resulting firmware image in QEMU 4.0.

The tutorial is based on the upstream TF-M code at https://git.trustedfirmware.org/trusted-firmware-m.git/

For system requirements to build TF-M, see `tfm_build_instruction.txt` in the `docs` folder (system setup is out of scope for this guide).

Build TF-M binaries

Test with GNU GCC 7.3.1 (7-2018-q2-update) and TF-M hash `88661e56612d51811b6ea7b14ae6467128967bb2`.

The first step is to build the secure and non-secure binaries using the ConfigRegression project config:

Building TF-M Binaries
$ cd trusted-firmware-m
$ mkdir build && cd build
$ cmake -G"Unix Makefiles" -DPROJ_CONFIG=`readlink -f ../ConfigRegression.cmake` \
-DTARGET_PLATFORM=AN521 -DBL2=false -DCMAKE_BUILD_TYPE=Debug -DCOMPILER=GNUARM ../
$ cmake --build ./

The commands above will build a debug binary with no bootloader (`-DBL2=false`).

If building on OS X, you need to install the coreutils package via `$ brew install coreutils` and replace `readlink` below with `greadlink`.

Merging `tfm_s.axf` and `tfm_ns.axf`

Builds that include the bootloader result in a `tfm_full.bin` file in the build folder, as well as a version signed by `imgtool.py` for use with mcu-boot

When building without the bootloader (`-DBL2=false`), however, we need to merge the secure and normal .axf files ourselves:

Merging .axf files
$ arm-none-eabi-objcopy -O ihex app/secure_fw/tfm_s.axf tfm_s.hex
$ arm-none-eabi-objcopy -O ihex app/tfm_ns.axf tfm_ns.hex
$ srec_cat tfm_s.hex -Intel tfm_ns.hex -Intel -o tfm_full.hex -Intel
$ ls *.hex
-rw-r--r-- 1 kevin staff 918K Jun 10 15:50 tfm_full.hex

If `srec_cat` isn't already available on your system you can install it via `$ sudo apt-get install srecord` on Ubuntu or `$ brew install srecord` on OS X.

QEMU

ARMv8 support was added to QEMU 4.0, along with `machine` support for the Musca and MPS2 development boards.

If you installed qemu via `apt-get` or `brew` you can check the version via:

$ qemu-system-arm --version
QEMU emulator version 4.0.0
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers

If you have an older version, see the appendix in this document on how to build QEMU from source.

Running in QEMU

Tested using qemu 4.0.0 release (required for ARMv8 support), and MPS2 `AN521` as a machine target.

Firmware images built using `-DCMAKE_BUILD_TYPE=Debug` as mentioned earlier in this guide.

$ qemu-system-arm -M mps2-an521 -device loader,file=tfm_full.hex -serial stdio

This should give you the following unit test output:

[Sec Thread] Secure image initializing!

#### Execute test suites for the Secure area ####


Running Test Suite PSA protected storage S interface tests (TFM_SST_TEST_2XXX)...
> Executing 'TFM_SST_TEST_2001'
Description: 'Set interface'
TEST PASSED!

> Executing 'TFM_SST_TEST_2002'
Description: 'Set interface with create flags'
...

Debugging with QEMU

Tested using qemu 4.0.0 release (required for ARMv8 support), and MPS2 `AN521` as a machine target.

Firmware images built using `-DCMAKE_BUILD_TYPE=Debug` as mentioned earlier in this guide.

To debug the binary image with `gdb`, run QEMU with the following parameters:

$ qemu-system-arm -M mps2-an521 -device loader,file=tfm_full.hex -serial stdio -s -S


  • `-serial stdio` redirects any serial output to stdio (facultative)
  • `-s` is an alias for `-gdb tcp::1234`
  • `-S` prevents the MCU from starting until a `continue` command is issued in GDB

`gdb` can then be run in a new terminal instance:

This example loads the symbols from `app/tfm_ns.axf`, but you can alternatively load `app/secure_fx/tfm_s.axf` depending on your requirements.


$ gdb -s app/tfm_ns.axf -ex "target remote tcp:localhost:1234"
(gdb) break main
Breakpoint 1 at 0x10111c: file /Users/kevin/Dropbox/linaro/code/tfm/trusted-firmware-m/app/main_ns.c, line 115.
(gdb) layout asm
(gdb) continue

Appendix: Building QEMU from source (Optional)

Depending on your platform or distro you may need to build QEMU from source.

For Ubuntu 18.04, the following steps are required to build from source:

This build process will take a reasonable amount of time to complete!


$ sudo apt-get install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev
$ sudo apt-get install libnfs-dev libiscsi-dev
$ git clone https://github.com/qemu/qemu.git
$ cd qemu
$ mkdir -p bin/debug/native
$ cd bin/debug/native
$ ../../../configure --enable-debug
$ make
$ cd ../../..
$ bin/debug/native/arm-softmmu/qemu-system-arm --version
QEMU emulator version 4.0.50 (v4.0.0-1170-g185b7ccc11-dirty)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers

You can see a list of support boards for `qemu-system-arm` via the following command, noting `mps2-an521` and `musca-b1`:

$ bin/debug/native/arm-softmmu/qemu-system-arm -M help
...
mps2-an385 ARM MPS2 with AN385 FPGA image for Cortex-M3
mps2-an505 ARM MPS2 with AN505 FPGA image for Cortex-M33
mps2-an511 ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3
mps2-an521 ARM MPS2 with AN521 FPGA image for dual Cortex-M33
musca-a ARM Musca-A board (dual Cortex-M33)
musca-b1 ARM Musca-B1 board (dual Cortex-M33)
...



Related content