This post begins with a goal to compile and run some assembly programs in AA64 on ARMv8-A architecture for students in a microcontroller course. My prior solution to this was failing so I have came up with the idea to run the ARM FVP (Fixed Virtual Platform) with Linux and use a gdbserver inside the FVP Linux to enable remote debugging with VSCode.
Setup the FVP and Linux
FVP Download
ARM has a few basic FVPs for their ARMv8 architecture available and I am using the Foundation version of it, which gives a much simpler network configuration that will be used for ssh
and gdb
. You can download it from this page here.
Bootloader, Linux kernel, and filesystem disk
In order to let the FVP runs Linux, we will be using a set of tools from Linaro:
- Bootloader and FVP run script: download the
fvp-latest-oe-uboot.zip
archive which contains arun_model.sh
, the Linux kernel, and the device tree file for Foundation FVPfoundation-v8-gicv3.dtb
. - Filesystem image: download and uncompress the
vexpress64-openembedded_lamp-armv8-gcc-4.9_20150620-722.img.gz
archive
Boot up Linux
To boot up Linux, you will need to tell the run_model.sh
where to find the Foundation model, the device tree, and the filesystem.
In the expanded folder of fvp-latest-oe-uboot.zip
, run the following shell commands:
export MODEL=FVP_FOUNDATION_FOLDER//Foundation_Platformpkg/models/Linux64_GCC-9.3/Foundation_Platform
export DTB=./foundation-v8-gicv3.dtb
export DISK=path/to/vexpress64-openembedded_lamp-armv8-gcc-4.9_20150620-722.img
chmod +x run_model.sh
./run_model.sh
Now you should see the FVP model running. If you have xTerm install, the FVP will launch two terminals at start with terminal 0 attached to the Linux. You could also attach to it by using telnet localhost 5000
.

Since the filesystem we choose contains a lot of development tools (LAMP), it might take ~3 min for first time boot up.

Debug with FVP
To debug program within FVP, I choose to use gdbserver that expose connection to the host so that the host debugger can pick it up. To do so, we will need to enable network NAT between FVP and the host.
In the ./run_model.sh
, add this option which launching the FVP: --network=nat --network-nat-ports=8022=22,9234=1234
. This will allow us to ssh into the FVP at localhost:8022
and setup gdbserver at FVP port 1234
and pick it up at host with port 9234
. See this doc from fedora for more details.
Now you could either ssh into the FVP with ssh -p 8022 root@localhost
or connect to it with telnet
. With either way, after you have shell prompt, launch the program within FVP you want to debug with gdbserver :1234 PROG
. Then you could use gdb
at host with command target remote :9234
to start. Note you can use scp
to copy the program from host to FVP and vice versa:
# Copy from host directory to FVP
scp -P 8022 HOST_DIR/from root@localhost:FVP_DIR/to
# Copy from FVP to host
scp -P 8022 root@localhost:FVP_DIR/from HOST_DIR/to
Noted the Linux version on the prebuilt filesystem might be old (GCC 4.9 version installed) and you will mostly want to use the same version of GCC toolchain to compile and debug. You can download them from Linaro release here.


With a little bit of work, you can also get VSCode debugger to work with this FVP. You will need the C/C++
extension from Microsoft, then use the following launch.json
file which will use the Linaro gdb and connect to localhost:9234
. Noted you will need to set the miDebuggerPath
to the Linaro one.
{
"version": "0.2.0",
"configurations": [
{
"name": "FVP Debug",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/lab",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true,
"MIMode": "gdb",
"miDebuggerPath": "${env:HOME}/Desktop/FVP_Linux/gcc-linaro-4.9.4-2017.01-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gdb",
"miDebuggerServerAddress": "localhost:9234",
"setupCommands": [
]
}
]
Future work
Since the FVP could get network access through host, it might be possible to run the FVP as a GitHub self-hosted runner for arm64 tests.