Building Bootloaders

The USRP E320 boots from a micro-SD card. The E320 ships with an SD card initialized during manufacturing with the standard NI/Ettus UHD design files. This standard design does not support running custom FPGA designs on the E320. The processes below describe how we modified the standard bootloaders and firmware to support our 802.11 FPGA design.


We provide pre-built E320 bootloader files with the 802.11 design. Building the bootloaders from source is not required to use the Mango 802.11 design on the E320. The build processes below are documented for completness and for advanced users who want to further customize the E320 boot process.

This build processes below have been tested on a Ubuntu 18.04 64-bit system. We have not attempted building u-boot or the EC firmware on any other OS.

Zynq First-Stage Boot Loader

The Xilinx Vivado SDK generates the Zynq First-Stage Boot Loader for a given Vivado hardware project. Refer to the Xilinx SDK documentation to create and build the FSBL software project. The 802.11 design does not require any customization of the Zynq FSBL.

u-boot Boot Loader

The E320 uses u-boot as the second stage bootloader. The u-boot executable runs in the Zynq ARM core immediately after the Zynq FSBL. The u-boot configuration implementes two processes:

  • Updates the System Controller (EC) firmware
  • Configures the Zynq PL (logic fabric) with the 802.11 bitstream
  • Reboots the ARM CPU to terminate u-boot

Our u-boot configuration is based from the custom u-boot code and configuration provided by NI for the standard USRP E320 design. The build process below document the changes we made.

Build Environment

  1. Install required Ubuntu packages: sudo apt install git build-essential git bison flex libssl-dev
  2. Download the Xilinx SDK 2018.3 from:
  3. Install the SDK to your preferred directory. The instructions below assume ~/Xilinx/SDK/2018.3
  4. (Optional) During installation de-select all Xilinx devices except the Zynq-7000

u-boot Source Code

First obtain the u-boot v2018.07 source:

  1. git clone
  2. cd u-boot
  3. git checkout v2018.07
Next apply the u-boot pathces from NI to add E320 support:
  1. curl -O
  2. git apply 0001-misc-cros_ec-Add-trivial-support-for-software-sync.patch
  3. curl -O
  4. git apply 0001-ni-zynq-Add-support-for-NI-Project-Neon-Rev2-SDR.patch
The raw Github URLs above work as of August 2019. In case these repositories are reorganized, it should be possible to locate the patches in the repository history. The current file paths in the meta-ettus repository are:
  • /meta-ettus-core/recipes-bsp/u-boot/files/0001-misc-cros_ec-Add-trivial-support-for-software-sync.patch
  • /meta-neon/recipes-bsp/u-boot/files/0001-ni-zynq-Add-support-for-NI-Project-Neon-Rev2-SDR.patch

Next edit the E320 u-boot defconfig:

  1. Edit u-boot/configs/ni_neon_rev2_defconfig

  2. At the end of the file add:


Finally edit the E320 boot commands:

  1. Edit u-boot/include/configs/ni_neon_rev2.h

  2. Find the #define CONFIG_EXTRA_ENV_SETTINGS macro definition on lines 19-46

  3. Replace the entire CONFIG_EXTRA_ENV_SETTINGS macro with this definition:

    #define CONFIG_EXTRA_ENV_SETTINGS        \
        "ec_compat=2\0"                \
        "mboard=neon-rev1\0"        \
        "load_addr=0x2000000\0"                \
        "preboot=load mmc 0 ${load_addr}  uEnv.txt && env import -t ${load_addr} $filesize \0" \
        "sdboot=echo *************; " \
            "echo ERROR: uEnv.txt not loaded from SD card - cannot continue boot; "\
            "echo Save valid uEnv.txt to SD card and reboot; "\
            "echo *************; " \
            "true;\0" \

Building u-boot

The u-boot project includes a full build system which supports cross compiliation of binaries for various platforms. To build a u-boot executable for the Zynq ARM you must use the cross compiler included in the Xilinx SDK. The u-boot build system supports this by default by setting environment variables before running the build.

The commands below must be run in the root of the u-boot source folder.

To build the u-boot executable:

  1. Enable the Xilinx SDK tools:

    source ~/Xilinx/SDK/2018.3/
  2. Select cross compilation for Zynq ARM:

    export CROSS_COMPILE=arm-linux-gnueabihf-
    export ARCH=arm
  3. Build u-boot:

    make distclean
    make ni_neon_rev2_defconfig

The build process will take a few minutes. When the build is complete a new ~3.8MB binary file named u-boot will be in the root of the u-boot source folder. Rename this file u-boot.elf and copy it to your 802.11 SDK workspace for use in the Boot Image generation process described below.

Zynq Boot Image

The Xilinx Vivado SDK includes the bootgen utility to package the Zynq FSBL and second-stage bootloader (u-boot here) into a single SD card “boot image”. The output of bootgen is a single boot.bin file which must be copied to the root of the SD card.

The 802.11 FPGA design for the E320 uses a boot.bin with two binaries:

  • Zynq FSBL executable (ELF file compiled by the SDK)
  • u-boot executable (ELF file compiled by u-boot build system)

The bootgen utility uses a boot.bif configuration file which specifies the binary files to pack into boot.bin. The SDK provides a GUI to geneate boot.bif. We use the following:

//arch = zynq; split = false; format = BIN

System Controller (EC) Firmware

The USRP E320 hardware integrates a microcontroller which manages the system’s power supplies, thermal sensors, system-level resets, etc. This microcontroller runs a custom version of the Chromium OS Embedded Controller (EC) software design. The Chromium project has extensive documentation about the EC design and build system.

NI/Ettus maintain a fork of the Chromium OS EC software for use on USRP hardware. As of August 2019 this fork is available via the usrp-firmware repository at

The default EC software for the USRP E320 implements a watchdog routine which hard-resets the Zynq device after a short timeout. The watchdog monitors for periodic I2C transactions which are implemented in the standard Linux image for the USRP E320. This watchdog is only good for applications built on the standard NI/Ettus image. In order to use the USRP E320 with a fully custom FPGA design this watchdog must be disabled.

Disabling the watchdog requires re-flashing the EC microcontroller with custom fimrware.

Customizing EC Firmware Code

  1. Obtain the USRP E320 usrp-firmware source:

    git clone
    cd usrp-firmware
    git checkout neon
  2. Edit /board/neon/power.c:

  1. Replace the IN_GOOD_AP macro definition:

    #define IN_PGOOD_AP (0) /* Disabling monitoring of SYS_PS_PWRON signal */
  2. Modify the wdt_reset_event() function to return immediately:

    void wdt_reset_event(enum gpio_signal signal)
            /* Bypassing AP reset by watchdog timer */

Building EC Firmware

The build process below is based on the Get Started Building EC Images (Quickly) guide from the Chromium OS team.

  1. Install required system packages:

    sudo apt install libftdi-dev libusb-dev libncurses5-dev gcc-arm-none-eabi
  2. Build the EC binary:

    HOSTCC=x86_64-linux-gnu-gcc make BOARD=neon

The build will take a few minutes. When finished the new EC fimrware binary will be in build/neon/RW/ec.RW.bin. Rename this file ec-firmware-no-watchdog.bin and copy it to your SD card.

Flashing EC Fimrware

The NI/Ettus version of u-boot (documented above) supports re-flashing the EC firmware from an SD card on boot. This process is implemented by the crosec swsync command in the u-boot boot arguments.

This process will re-flash the EC if the EC’s current firmware differs from the ec-firmware-no-watchdog.bin file on your SD card. As a result, the first boot using the custom EC firmware will take slight longer (to re-flash / reboot the EC) than subsequent boots.

The u-boot configuration documented above requires the custom EC firmware to be saved at the root of the SD card with filename ec-firmware-no-watchdog.bin.