Zynq Application Development and Debug


This page outlines the process of creating a "hello world" application and debugging it with gdb command line.


This page assumes that a qemu environment is setup (root filesystem, compiled kernel, installed qemu). It also assumes that a copy of the Xilinx Code Sourcery Toolchain is installed and added to the PATH.

Writing Hello World

Create a file named "hello.c" containing the following:

#include <stdio.h>
void main () 
    printf("Hello World!\n");

Compiling the application

Compile the application using the Xilinx CodeSourcery ARM cross compiler with the following command:

bash> arm-xilinxa9-linux-gnueabi-gcc hello.c -g -o hello

Copying files to the Virtual Target

To copy files to the target use ftp. When running QEMU make sure that the ftp port is redirected to an open port on the host machine. Make sure the QEMU command line includes "-redir tcp:10021::21" for example.

There are multiple tools that can be used to upload a file.

If the host machine has curl installed simply issuing the following command will upload the file to the root folder. Before running the command below make sure the environment variables HTTP_PROXY, FTP_PROXY, http_proxy, and ftp_proxy are not set.

bash> curl -T hello -P - ftp://root@localhost:10021/root/

If curl is not available a safe fallback is to use the standard ftp command. The steps to upload with ftp are as follows:

bash> ftp localhost 10021
Name (localhost:devel): root
ftp> cd root
ftp> put hello
ftp> quit

Keep in mind that when the target is shutdown any changes to the root filesystem will be lost since this is a RAM based filesystem.

Running the first application

Now that the compiled application has been uploaded to the target via ftp, the permissions need to be fixed with chmod. Run the following commands:

zynq> cd /root
zynq> chmod a+x hello

With the permissions set properly the application can be run simply with:

zynq> ./hello

Debugging the first application

In order to debug the application a GDB server must be run on the target machine. Execute the following command to start a GDB server:

zynq> gdbserver HOST:1234 hello

At this point the target shell output should look similar to the following:

Freeing init memory: 132K
Starting rcS...
++ Mounting filesystem
++ Setting up mdev
++ Starting telnet daemon
++ Starting http daemon
++ Starting ftp daemon
++ Starting dropbear (ssh) daemon
rcS Complete
/ # cd root
~ # chmod a+x hello 
~ # ls
~ # ./hello
Hello World!
~ # gdbserver HOST:1234 hello 
Process hello created; pid = 277
Listening on port 1234

Now that the server is running a GDB client can connect to perform debugging:

bash> arm-xilinxa9-linux-gnueabi-gdb hello

Once GDB is running instruct it to connect to a remote server:

(gdb) target remote localhost:1234

Set a breakpoint on "main" and "cont"inue the application:

(gdb) b main
(gdb) cont

At this point the host machine terminal should look similar to the following:

bash> arm-xilinxa9-linux-gnueabi-gdb hello
GNU gdb (Sourcery G++ Lite 2010.09-62)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-xilinxa9-linux-gnueabi".
For bug reporting instructions, please see:
Reading symbols from /home/kkurbjun/test_qemu/hello...done.
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
0x400aa7a0 in ?? ()
(gdb) b main
Cannot access memory at address 0x0
Breakpoint 1 at 0x8434: file hello.c, line 5.
(gdb) cont
warning: Could not load shared library symbols for 3 libraries, e.g. /lib/libgcc_s.so.1.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?

Breakpoint 1, main () at hello.c:5
5        printf("Hello World!\n");

The next line of code "printf("Hello World!\n");" can be run with the "next" or "n" command:

(gdb) n
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License