Skip to the content.

Cross-compilation and Simulation for ARM

The EECE7638 SDK provides an environment that allows cross-compilation of SW to the target (ARM). It also provides QEMU, a system simulator that simulates the complete Zynq ARM platform.

Prerequisites:

1. Activating the SDK

In order to use the SDK, activate it by using the alias :

setup-xarm

Your prompt should now indicate the active environment (xarm):

(xarm) bash-4.4$

You can now cross-compile SW for the ARM processor or start simulation with QEMU.

2. Cross-compilation

The cross compiler for the simulator is available as part of the SDK installed. Before cross-compiling, activate the SDK environment as instructed above.

Compile from the command line (of the machine, not the simulator), such as:

(xarm) bash-4.4$ $(CC) helloWorld_user.c -o helloWorld_user

The output binary is not executable on the host as it is an arm binary:

(xarm) bash-4.4$ ./helloWorld_user
bash: ./helloWorld_user: cannot execute binary file
(xarm) bash-4.4$ file helloWorld_user
helloWorld_user: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.2.0, BuildID[sha1]=a8dbfa3fd6e9c40e65fabb055a14b6972937e830, not stripped

3. Simulating System Using QEMU

We have installed an Instruction Set Simulator (ISS) based on QEMU that simulates the ZedBoard and runs the full Linux code. Within the simulator you have root access and can try out user code or your kernel modules. Note that the simulator is a completely separate instance from the host. No files are shared between host and simulator. Any changes inside the simulator are volatile, ie. will be lost at next reboot of the simulator.

To start the simulator, open up a new ssh terminal, activate the sdk and type:

qemu-esl

Booting the simulator takes a few minutes (1.5min - ). This starts the simulator and opens a tty (terminal) to login to the Linux running in the simulator (root / no password).

The boot sequence ends with the following output:

ESL Linux 2022.2 qemu-esl ttyPS0
zedboard-esl login:

The TTY has full access to the simulated machine. This includes CTRL-C for stopping a shell command inside the simulator. However, that does not terminate the simulation.

To terminate the simulation, use CTRL-a x (press CTRL and a simultaneously, then press x alone without CTRL).

Please stop the simulator when not in use. Due to the simulation approach it consumes 2 full cores on the host machine. You can check it out by running top on the host system.

4. Transfer Files to the Simulator

In addition to the console TTY, the simulator implements an SSH server. The setup (Home, COE) made the the simulated ARM instance reachable with the hostname qemu. However, qemu is only reachable on the same host as qemu was started. Hence, initiate ssh from the same machine as you started qemu on.

Upload a file to the QEMU simulator (the first ssh takes >20seconds due to generating ssh keys after start):

scp helloWorld_user qemu:

Be aware of the delay on first connection. In addition, accept the ECDSA key fingerprint on first connection. The fingerprint will change with each start.

The file is uploaded to /home/root/ in the ISS and can now be executed there:

root@zedboard-esl:~# ./helloWorld_user
Hello world in user mode!

5. Debugging an Application running on the Simulator

Binaries within qemu (like the debugread binary uploaded in step 4) can be debuged remotely using gdbserver. You can start a remote debug session using the below instructions.

  1. On the host change directory to sw/ and initiate debugging with gdbserver over port 10024. Note that the below make rule actually runs a remote gdbserver command over ssh to start a gdbserver process inside QEMU:

     make debug
    

    The command will block as the gdbserver (inside QEMU waits for a debug connection).

  2. On the host open a new terminal and start the cross compilation environment setup-xarm.

    Change into the same directory so that the binary to be debugged can be found. Start the debugger specific to our cross compilation arm-esl-linux-gnueabi-gdb (if your system has gdb-multiarch you can use it as well).

     arm-esl-linux-gnueabi-gdb debugread 
    

    Once in the gdb console, connect to the gdb server running inside QEMU using the target command.

     target remote localhost:10024
    

    This isntructs the debugger not to run the local instance of debugread, but connect through TCP to the gdbserver and execute debug read on QEMU.

    On COE systems the debug port is dynamic (as multiple users may debug at the same time). To check the curren port and use this instead of 10024:

     cat ~/.qemu-dbg-port
    

6. VS Code for Cross Development

6.1 Cross Compilation

The Makefile-tools work identically in a cross compilation environment. For this, the SDK environment needs to be activated. See point 3 in the installation instructions. The environment needs to be activated once before starting a build.

6.2 Remote Debugging

For more graphical debugging, you can use VSCode. Note that gdbservers’s API is accessible through Vscode. To enable remote using vscode debugging

  1. Install the Native Debug extension
  2. Add the below json config to your .vscode folder
    {
     "version": "0.2.0",
     "configurations": [{
         "type": "gdb",
         "request": "attach",
         "name": "Attach to gdbserver",
         "executable": "${workspaceFolder}/debugread",
         "target": "localhost:10024",
         "remote": true,
         "cwd": "${workspaceRoot}", 
         "gdbpath": "/usr/bin/gdb-multiarch",
         "autorun": [
                 "make debug"
             ]
     }
     ]
    }
    
  3. Start gdbserver in QEMU
    make debug
    
  4. Start debugging in vscode using the configuration “Attach to gdbserver”

7. Outlook and Next Steps

This section has shown how to simulate ARM code. The next challenge is to simulate both an ARM and custom hardwre. See SystemC Co-simulation for detailed instructions.