Guidance Note Version # 0.1 (ARM Cross GCC) Zynq: Using a Custom BareMetal GCC Toolchain in XSDK This document is intended to provide comprehensive guidance on how to use a custom GCC toolchain within Xilinx’s Software Development Kit (XSDK) for standalone software application development, targeting the Zynq®-7000 All Programmable SoC. Substituting the 'included/native' CodeSourcery Lite GCC compiler from Mentor and by example using the Linaro Bare Metal GCC toolchain - However, the principles are directly applicable to any alternative GCC release. There are a variety of reasons this may be desired, by example through observation that the included compiler uses the 'Soft Floating Point' (softfp) ARM Procedure Call Standard (APCS): Whilst such brings flexibility to the compiler when sharing object code across platforms with different pipeline topologies it is not optimal for singular hardware platforms such as the Zynq-7000 family which ALL include 'hardware' Vector Floating Point (vfpv3) and NEON SIMD subsystems per CPU core. By explanation the “softfp” APCS specifically passes floating point values through the integer register file and stack when traversing functions, whilst the ‘hard’ APCS retains in and passes through the NEON floating point register file – this can lead to an improvement in performance for floating point intensive applications. Custom Compilers Numerous commercially packaged GCC toolchains are available for purchase or such could be built from source with suitable guidance, experience and knowledge. However, here we focus on the offerings from Linaro. Linaro - is a not-for-profit engineering organization that works on free and open-source software such as the Linux kernel, the GNU Compiler Collection (GCC), graphics and multimedia interfaces for the ARM family of instruction sets and implementations thereof: thus a good source for an alternative compiler for the Zynq-7000 platform, especially as they support the "hard" float APCS. The following guidelines include use of this alternative APCS: Root Directory Prebuilt Images Status GCC 4.8 Release Windows Maintenance Mode GCC 4.9 Release Windows Active Development Once downloaded simply follow the corresponding installation instructions, ensuring any PATH adjustments are applied to ensure the executable can be invoked from the XSDK command console. Note: At the time of writing this flow has solely been tested on Windows hosts. XILINX INTERNAL Xilinx SDK - Using the Substitute Compiler Eclipse Plug-In: ARM GCC Cross Compiler The eclipse plugins that create the Xilinx aware persona of XSDK were developed with the Xilinx distributed CodeSourcery Lite compiler in mind - thus knowing the default options used by Mentor and similarly where the appropriate include libraries reside. HOWEVER, these obviously don't apply when using a custom compiler. Therefore to use other compilers you need to avoid this implicit association, this necessitates the selection of an alternative tool chain - as detailed below. The GNU ARM Eclipse project offers a solution for the use of various ARM GCC toolchains, such is available as a plugin, namely: "GNU ARM C/C++ GCC Cross Compiler". Available @ http://gnuarmeclipse.sourceforge.net/updates To install, follow the standard plug-in installation process. Accessed through: Help -> Install New Software Workspace – Creation, Customisation and Build Create an XSDK Workspace - Import a Hardware Platform, derive a Bare-Metal BSP and create an Application project exactly as you would for the natively compiled software flow. In Summary, once created you need to do the following Board Support Package Changes Substitute the toolchain and add build switches Remove default build switches for Standalone sources Software Application Migration New Project Creation Customise Build Configuration Miscellaneous – Create Build Spec. Now for the details. XILINX INTERNAL Board Support Package Changes Open "Board Support Package Settings" and modify to the following as shown. archiver arm-none-eabi-ar compiler arm-none-eabi-gcc extra_compiler_flags -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -nostartfiles The default Makefile for the Standalone source within the BSP sets compiler switches which MAY not be required or worse still conflict with those you wish to use with the custom compiler, thus its necessary to conditionally comment them out. Additionally there is a mistake in the compiler invoked so a second change is required. File location: <Workspace Location>\<BSP Project Name>\ps7_cortexa9_?\libsrc\standalone_v5_0\src The required changes are captured below - the left visual is the original Makefile and needs to be modified to match that on the right. For ease of use we propose to modify the installation @ C:\Xilinx\SDK\2015.1\data\embeddedsw\lib\bsp\standalone_v5_0\src\cortexa9\gcc IF you plan to use this flow regularly. (Xilinx shall publish the official change in 2015.2/3) Now you should be able to Build the BSP project to success using the selected toolchain. XILINX INTERNAL Software Application Migration New Project Creation It is recommended to create a new C/C++ Project for your new toolchain and import software sources – either from your development repository or the template application project created earlier. Templates are provided for empty and Hello World examples. Make sure to select the Cross ARM GCC toolchain. If choosing the Hello World examples complete the Basic Settings questions as asked, accepting defaults is fine. Next, choose your selected alternative toolchain from the pulldown list XILINX INTERNAL If such can be found in the path then the install location will be automatically populated. Click Finish. Right Click (Application Project) in the Project Explorer pane and define a Referenced BSP, typically this would be that you created and modified in the previous section. With a reference BSP set the Generate Linker Script option will become available, again accessed through a Right Click (Application Project). The defaults are fine as an initial configuration, click Generate to complete. XILINX INTERNAL Customise Build Configuration Now again, Right Click (Application Project) - C/C++ Build Settings Thus enabling the compiler to be configured for the Zynq-7000 Processor systems specific hardware configuration. COMMON Select ARM family: cortex-a9 FPU type: vfpv3 Float ABI: soft, softfp or hard to match your BSP build settings. These selections are automatically propagated to the Compiler, Linker and Assembler as appropriate. COMPILER Add the Include path for the BSP header file ‘includes’: LINKER Three modification areas are required for the linker, namely: Linker Definition, C- RunTime/Build Configuration and library definition. These changes are detailed in the following three subsections. XILINX INTERNAL Linker Script Select the linker script for your project C-RunTime/Build Configuration As mentioned the native compiler was built with a customised CRT file configuration, this needs to be recreated explicitly for any generic substitute compiler by specifically excluding the ‘included/default’ crt0.o file. In brief overview, the “C RunTime” library fundamentally comprises five files, namely; Filename Description crt0.o This object is expected to contain the _start symbol which takes care of bootstrapping the initial (xil-crt0.S) execution of the program. What exactly that entails is highly libc dependent and as such, the object is provided by the C library and cannot be mixed with other ones. On uClibc/glibc systems, this object initializes very early ABI requirements (like the stack or frame pointer), setting up the argc/argv/env values, and then passing pointers to the init/fini/main funcs to the internal libc main which in turn does more general bootstrapping before finally calling the real main function. crti.o Defines the function prologs for the .init and .fini sections (with the _init and _fini symbols respectively). Which in turn define constructor/destructor .init_array/.fini_array sections and DT_INIT_ARRAY/DT_FINI_ARRAY ELF tags. crtbegin.o GCC uses this to find the start of the constructors. crtend.o GCC uses this to find the start of the destructors. crtn.o Defines the function epilogs for the .init/.fini sections. See crti.o. For custom GCC toolchains the crt0.o needs to be replaced with Xilinx’s customised version, namely xil-crt0.S : part of the processors standalone library and which is archived into libxil.a as part of the BSP build process: Such is achieved by creating a custom build spec and passing to gcc on invocation using the switch -specs=Xilinx.spec This contrasts with the default for many generic GCC toolchains and has the effect of EXCLUDING the ‘inbuilt’ crt0.o object which would normally be mapped as shown here. You can find your toolchains default startfile spec using the command arm-none-eabi-gcc -dumpspecs | grep -A1 *startfile: XILINX INTERNAL For convenience this will be created dynamically using the eclipse pre-build feature, specifics detailed shortly. In addition the following switches are also required: -Wl,--build-id=none -Wl,--start-group,-lxil,-lgcc,-lc,--end-group These remove the build.id tag which is a “default” in many GCC toolchain builds. Whilst the library archive grouping (start-group/end-group) is required because of function/symbol overriding in the Xilinx code – thus enabling recursive searching/resolution. Combined, the build flags and start file overrides should be set as “Miscellaneous -> Other linker flags” as shown. -specs=Xilinx.spec -Wl,--build-id=none -Wl,--start-group,-lxil,-lgcc,-lc,--end-group Build libraries Finally add libraries and the corresponding search path as shown, additionally adding ‘m’ for math depending on code content. Note order is important for library definition (c before xil). XILINX INTERNAL Miscellaneous - Create Build spec To dynamically create the linker build spec detailed earlier add the following Pre-Build Step (echo *startfile: & echo crti%%O%%s crtbegin%%O%%s) > Xilinx.spec Conclusion With the detailed flow the user should be able to successfully build, debug and run compiled code using a selected third party GCC Toolchain on the All Programmable Zynq -7000 SoC platform. XILINX INTERNAL Revision History Version 0.1 Date 12/5/15 Author Simon George Description Migrated to ARM Cross C/C++ plugin from Cross GCC. Error Avoidance NOTE: Only seen on some machine Due to a problem with the discovery options ‘default’ for the GCC Cross Compiler plugin a workspace configuration option needs to be changed. Select Window -> Preferences to access the configuration page Select Display “Discovery Options” page Then disable “Automate discovery of paths and symbols” XILINX INTERNAL