Chapter2 Zynq SW
Overview
The development of the hardware system is undertaken in the Xilinx Vivado IDE development suite. The designer can sketch out their desired system with blocks originating from an IP library, parameterise the blocks, and design appropriate internal connections and external ports. This process is undertaken using the IP Integrator component of Vivado.
- The layer directly above the Hardware Base System is the Board Support Package (BSP), the set of low-level drivers and functions that are used by the next layer up (the Operating System) to communicate with the hardware.
When creating the software stack, the first design choice is usually to decide on the OS to deploy: this can be a
- Fully-fledged OS such as Linux or Android;
- An embedded OS;
- A Real-Time Operating System (RTOS) for deterministic, time-critical applications;
- Standalone, a ‘light’ OS like busybox which including only the most basic functions.
- No-OS: applications to communicate directly with hardware, and this is often referred to as a bare-metal application.
It is important to note that not all designs require both an Executable Linkable Format (ELF, .elf) file and a BIT (.bit) file to configure the device. The purpose of ELF files is to program the PS, while BIT files are used to program the PL. Therefore, if only one part of the Zynq device is used (PS or PL), then only the corresponding file type is needed.
All of the design tasks may also be undertaken using the industry standard Tool Command Language (TCL) scripting language. This represents a very powerful, repeatable and parameterisable method of driving the design tools.
For legacy design you can map between ISE and Vivado
ISE | Vivado |
---|---|
ISE Project Navigator | Vivado IDE |
PlanAhead | Vivado IDE |
Xilinx Platform Studio(XPS) | IP Integrator |
SDK | SDK |
ucf | xdc(xilinx design constraints) |
The hardware platform used for linux is created with Xilinx Vivado Design Suite. In software, we begin with an SDK project based on the exported hardware design.
Cross Compiler
The cross compile for zynq is included in the SDK, or you can build form the source code
Xilinx maintains a webpage which provide all the needed source code
Background
To build a cross-compiler, you need
A working C compiler ( gcc is generally a good idea ) A C compiler is supplied with most Linux /UNIX-based operating systems. You also need the source code for the various tools used to build the cross-compiler. You can download GNU tools from GNU (http://www.gnu.org)
A copy of the header files for your target platform. For a Linux target, use the generic Linux kernel headers available from Kernel.org (http://www.kernel.org)
The main components of any compiler are:
Parser: The parser converts the raw language source code into assembly language. Because you're converting from one format to another (C to assembly), the parser needs to know the target assembly language.
Assembler: The assembler converts the assembly language code into the bytecode that the CPU executes.
Linker: The linker combines the individual object files that the assembler generates into an executable application. Different operating system and CPU combinations generally use different encapsulation mechanisms and standards. The linker needs to know this target format to work
Standard C library: The core C functions (for example, printf) are provided in a central C library. This library is used in combination with the linker and the source code to produce the final executable, assuming that functions from the C library are used in the application
You thus need to build
binutils: The binutils package includes basic binary utilities such as the assembler, the linker, and associated tools such as Size and Strip. The binary utilities encompass both the core components for building an application and the tools that can be used to build and manipulate the target execution format. For example, the Strip utility removes symbol table, debugging, and other "useless" information from an object file or application, but to do so, the utility needs to know the target format so that it doesn't remove the wrong information
gcc: The gcc is the main component of the compilation process. Gcc encompasses the C preprocessor (cpp) and the translator, which converts the C code into the target CPU assembly language. Gcc also acts as an interface to the overall process, calling cpp, the translator, the assembler, and the linker accordingly
newlib/glibc: This library is the standard C library. Newlib was developed through Redhat and can be slightly more user friendly in cross-compilers designed to be used for embedded targets. You can also use the newlibc ), but I focus on using gcc in the following since it is still the most popular one
GCC is not just a compiler. It’s an open source project that lets you build all kinds of compilers. Some compilers support multithreading; some support shared libraries; some support multilib. It all depends on how you configure the compiler before building it.
y
This guide will demonstrate how to build a cross-compiler, which is a compiler that builds programs for another machine. All you need is a Unix-like environment with a recent version of GCC already installed.
Before started, you must first install a few packages:
$ sudo apt-get install g++ make gawk
By the time we’re finished, we will have built each of the following programs and libraries. First, we’ll build the tools on the left, then we’ll use those tools to build the programs and libraries on the right. We won’t actually build the target system’s Linux kernel, but we do need the kernel header files in order to build the target system’s standard C library.
The compilers on the left will invoke the assembler & linker as part of their job. All the other packages we downloaded, such as MPFR, GMP and MPC, will be linked into the compilers themselves.
The diagram on the right represents a sample program, a.out, running on the target OS, built using the cross compiler and linked with the target system’s standard C and C++ libraries. The standard C++ library makes calls to the standard C library, and the C library makes direct system calls to the AArch64 Linux kernel.
It is somewhat tricky, since it needs bootstrap to resolve chicken and egg problem
Flow
We refer you to look through the detail steps in the link provided For our cross compiler, you can use pre-built gcc from SDK and do the steps in next section
Added Glib-2.0
Here we will provide a flow to add core libraries into gcc, the glibc library is used by many popular software. Unfortuenately, it is not builtin in gcc.
1. Building libffi
libffi is the Portable Foreign Function Interface Library and is a prerequisite for building GLib. It is an interface that allows code written in one language to call code written in another language.
Compiling libffi
./configure --host=arm-xilinx-linux-gnueabi --prefix=/home/simon/local_lib
make
make install
- Glib
You need to add some variables
You can see form official website, it has several params https://developer.gnome.org/glib/stable/glib-cross-compiling.html
echo "glib_cv_stack_grows=no" >config.cache echo "glib_cv_uscore=no" >>config.cache echo "ac_cv_func_posix_getpwuid_r=yes" >>config.cache echo "ac_cv_func_posix_getgrgid_r=yes" >>config.cache
Directly build will introduce errors. The fix I made was to modified the Makefile.in files (from stackoverflow: my installed version of autotools was too low to autoreconf, otherwise I would have modified the Makefile.am files). These modifications were associated with glib-2.34.1 tarball (in other version you may need to use make V=1, J=1 to find the missing link) ```
- gobject/Makefile.in: line 629
progs_LDADD = ./libgobject-2.0.la $(libglib) $(LIBFFI_LIBS)
- gobject/tests/Makefile.in: line 461
LDADD = ../libgobject-2.0.la $(top_builddir) /gthread/libgthread-2.0.la $(top_builddir)/glib/libglib-2.0.la $(LIBFFI_LIBS)
- gio/Makefile.in: I added $(LIBFFI_LIBS) to the end of many *_LDADD definitions
(some of which were likely unnecessary), which were on the following lines: 1292,
1305 (before backslash), 1319, 1327, 1340
gio/tests/Makefile.in: line 1073 (part of a multi-line assignment)
$(top_builddir)/gio/libgio-2.0.la $(LIBFFI_LIBS)
FInally, execute the following bash file
CPPFLAGS="-I/home/simon/local_lib/include \ LDFLAGS="-L/home/simon/local_lib" \ LIBFFI_CFLAGS="-I/home/simon/local_lib/include" \ LIBFFI_LIBS="-L/home/simon/local_lib/lib -lffi" \ ./configure --host=arm-xilinx-linux-gnu --prefix=home/simon/local_lib -C --enable-static make make install DESTDIR=/home/nonoo/common-libs-compiled/arm/glib
### Usuage
To use the cross compiler, set the following variables
setenv INSTALLDIR /misc/Si2_RAID1/si2/100/phonchi/00_Lib/cross_compile/arm setenv PATH $INSTALLDIR/bin:$PATH /opt/Xilinx/SDK/2015.2/gnu/arm/lin/bin:$PATH setenv TARGETMACH arm-xilinx-linux-gnueabi setenv BUILDMACH i686-pc-linux-gnu x86-64 setenv CROSS arm-xinlinx-linux-gnueabi setenv CROSS_COMPILE arm-xinlinx-linux-gnueabi- setenv CC ${CROSS}-gcc setenv LD ${CROSS}-ld setenv AS ${CROSS}-as
export INSTALLDIR=/misc/Si2_RAID1/si2/100/phonchi/00_Lib/cross_compile/arm export PATH=/opt/Xilinx/SDK/2015.2/gnu/arm/lin/bin:$PATH export TARGETMACH=arm-xilinx-linux-gnueabi export BUILDMACH=i686-pc-linux-gnu x86-64 export CROSS=arm-xilinx-linux-gnueabi export CC=${CROSS}-gcc export LD=${CROSS}-ld export AS=${CROSS}-as export CROSS_COMPILE=arm-xilinx-linux-gnueabi-
Now compile your test program:
$CC -Wall -Wextra
check it
file
It may be cumbersome but I highly recommend doing the above for **every** build. That is to say, each time you cross-compile software for ARM do it in a new terminal/tab and begin by setting the environment variables above. In doing so you ensure that your build starts clean.
To run the programs that have been compiled with this cross-compiler you'll need to move some of the libraries and binaries to the file system on your dev board or your custom Linux file system. These are located in sysroot: /cross_compile/arm/sysroot
## Debugging
### Gdb server
### Build stage
1. if you want to see the detial command executed by libtool try
make V=1 J=1
2. Use **file** command to check the apllication type
3. Use the following command to check the intepreter
readelf -l your_executable|grep "program interpreter"
4. To check the size of file use
du -sh *
5. To check the status of mounting device use
df
> when building with libtool which is common in linux, you should note that config.log is quite missleading, it will dump all variables in the end of the file. Try to scroll up to find the root cause
7. QT, In our uvcstreamer v4l2 is natively provided by the kernel, so we don't have to build it.
However, it is worth to record some info about it: Some applications does not require all env variables CC, AR, LD be setting. For instance, to cross compile the qt provided by xilinx, these variables should not be set
## Third party libraries
Before starting to build, you may save the following setting in a bash file
!/bin/
export INSTALLDIR=/opt/Xilinx/SDK/2015.2/gnu/arm/lin export PATH=$INSTALLDIR/bin:$PATH export TARGETMACH=arm-xilinx-linux-gnueabi export BUILDMACH=i686-pc-linux-gnu export CROSS=arm-xilinx-linux-gnueabi export CC=${CROSS}-gcc export LD=${CROSS}-ld export AS=${CROSS}-as export LDFLAGS=-L/home/simon/local_lib/lib export CPPFLAGS=-I/home/simon/local_lib/includ
### GMP
https://gmplib.org/
./configure --prefix=/home/simon/local_lib_new --host=arm-xilinx-linux-gnueabi make make install
https://gmplib.org/manual/Build-Options.html
### PBC
https://crypto.stanford.edu/pbc/files/pbc-0.5.14.tar.gz
./configure --prefix=/home/simon/local_lib_new --host=arm-xilinx-linux-gnueabi make make install
### OpenSSL
https://how-to-build-for-arm.wikispaces.com/openssl
./Configure -DOPENSSL_NO_HEARTBEATS --prefix=/home/simon/local_lib_new
--openssldir=/home/simon/local_lib_new/openssl
shared os/compiler:arm-xilinx-linux-gnueabi-
add -fPIC to CFLAGS
make make install
$AR -x libcrypto.a $CC -shared .o -o libcrypto.so rm .o $AR -x libssl.a $CC -shared .o -o libssl.so rm .o
### CPABE
http://acsc.cs.utexas.edu/cpabe/
When cross compiling the best way seems to be manually modify the Make file
top_srcdir = . prefix = /home/simon/local_lib exec_prefix = ${prefix} bindir = ${exec_prefix}/bin mandir = ${prefix}/share/man
CC = arm-xilinx-linux-gnueabi-gcc CFLAGS = -O3 -Wall \ -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include \ \ -I/home/simon/local_lib/include -I/usr/include/pbc -I/usr/local/include/pbc \ \ -DPACKAGE_NAME=\"cpabe\" -DPACKAGE_TARNAME=\"cpabe\" -DPACKAGE_VERSION=\"0.11\" -DPACKAGE_STRING=\"cpabe\ 0.11\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1 -DHAVE_FCNTL_H=1 -DHAVE_STDDEF_H=1 -DHAVE_STRING_H=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DLSTAT_FOLLOWS_SLASHED_SYMLINK=1 -DHAVE_VPRINTF=1 -DHAVE_LIBCRYPTO=1 -DHAVE_LIBCRYPTO=1 -DHAVE_STRCHR=1 -DHAVE_STRDUP=1 -DHAVE_MEMSET=1 -DHAVE_GMP=1 -DHAVE_PBC=1 -DHAVE_BSWABE=1 LDFLAGS = -O3 -Wall \ -L/home/simon/cross_xilinx/arm-xilinx-linux-gnueabi/libc/usr/lib -lglib-2.0 \ -Wl,-rpath /home/simon/local_lib/lib -lgmp \ -Wl,-rpath /home/simon/local_lib/lib -lpbc \ -lbswabe \ -lcrypto -L/home/simon/local_lib/lib -lcrypto
$ ./cpabe-setup $ ./cpabe-keygen -o sara_priv_key pub_key master_key att1 att2 att3 att4 att5 att6 $ ./cpabe-enc pub_key bbb.txt -k att1 and att2 and att3 and att4 and att5 and att6 (stdin) ^D $ ./cpabe-dec pub_key sara_priv_key bbb.txt.cpabe -k ```