Sunday, November 8, 2015

Configuring the Cyclone V FPGA SoC Boot loader on a DE0-Nano-SoC board

Understanding the boot loader on a computer system is probably the most important aspect of security. Most computer systems have multiple boot loaders that run in sequence immediately after a power reset is applied to the processor on the computer system.  This applies to embedded, desktop, and server systems.

So I picked up a couple of Altera FPGA SoC boards a few weeks ago and immediately pulled up all of the documentation that I could find on the Cyclone V SoC.  The Cyclone V SoC has an FPGA and a Hard Processor System (HPS) woven into a single processor package.  The HPS is a dual core ARM Cortex A9. Building everything from scratch is the best way to figure out how the system works.

The boot sequence on a Cyclone V HPS works like this:

The On-chip ROM (for which source code is not provided) loads the preloader (1st stage bootloader). The preloader then loads U-boot. U-boot then loads the kernel and root file system.

There are two well thought out options for the preloader according to the Cyclone V boot guide.  The two options are licensed differently depending on how you build the source code.  One is licensed under a BSD license and the other under GPL v2 with U-Boot.

Building a pre-loader image for the DE0-Nano-SoC board was straightforward.  Altera provides the bsp-editor utility for customizing the preloader configuration and generating the BSP HPS preloader source code, after which, make is used to build the sources using the Mentor ARM cross toolchain.
The preloader settings directory can be found on the DE0-Nano-SoC CD in the DE0_NANO_SOC_GHRD subdirectory.

The preloader load address can be set via the bsp-editor so that the on chip ROM either loads the preloader from an absolute zero address on the sdcard or from a fat partition with id equal to a2 on the sdcard.  These are the options for booting from the sdcard.

After the sources are generated and the preloader image is built using the Makefile, U-boot must be compiled. An Altera port of U-Boot is available on github for the Cyclone V FPGA SoC. U-Boot is built using the Linaro ARM cross toolchain.

There's quite a bit you can do with the Cyclone V FPGA SoC boot configuration.  FPGA images can be loaded from U-boot.  The jumpers on the board can be configured to boot from the on-board serial flash (QSPI), bare metal applications can be loaded from the preloader, the FPGA can be configured from serial flash, and the list goes on.  The HPS SoC Boot Guide for the Cyclone V SoC  is a valuable reference and contains all of the boot configuration information.


  1. Did you use QSPI of DE0-Nano? I can not boot from QSPI of DE0-Nano, it seems has no NOR

  2. On the Rockboards site I found instructions to build an Angstrom distro. That may be OK but I'd like to build a RT kernel and I don't see instructions to do this for the DE0-Nano-SoC.

    On the Altera open source Github there are linux-socfpga and angstrom-socfpga repositories.

    What's a bit confusing is that my board came with something advertising as "Yocto Project 1.3 Poky 8.0". I'm new to Yocto but I understand it is a distro builder not a distro in and of itself. Not sure what Poky is exactly.

    1. Have you tried the socfpga-4.1.22-ltsi-rt branch of linux-socfpga for building a real-time kernel?

      Poky is the Yocto reference build. When you pull the Poky repository, you get the build tools, demo reference images for booting on QEMU, and support for a few select boards. If you want to build an image with Xorg and networking support to boot on QEMU, then you can pull the Poky layer. However; you'll most likely need more. Run the following commands on Linux and then take a look at the contents of the two sub directories - meta-openembedded/ and poky/
      As you will notice, the meta-openembedded directory contains a bunch of new layers that are available to you. The poky subdirectory contains the core layers and the build tools for building images. I would suggest merging the two directories into one afterwards.

      $ curl > ~/bin/repo
      $ chmod a+x $HOME/bin/repo
      $ echo "PATH=$PATH:$HOME/bin" >> $HOME/.bashrc
      $ source $HOME/.bashrc
      $ cd $HOME
      $ mkdir src
      $ cd src
      $ git clone git:// -b krogoth
      $ git clone git:// -b krogoth

      Last, the image that you burned to the uSD card for the De0-Nano-SoC board contains U-Boot and the kernel. An entire image, including U-Boot can be built from Poky after you pull the appropriate layers.

      The Terasic De0-Nano-SoC image that you booted from the uSD card on the De0-Nano-Soc board contains the u-boot boot loader image, device tree database, linux kernel, and root file system image - all of which were built and then packed into a uSD card image from Poky.
      BOARD : Terasic DE0_Nano_SoC Version-A Board
      U-Boot 2013.01.01 (Dec 30 2014 - 12:07:34)
      Poky 8.0 (Yocto Project 1.3 Reference Distro) 1.3


    2. Thanks for the reply. I've learned some things since I posted. There is a fork of meta-altera:

      I cloned poky and checked out krogoth (as you suggested). Then I cloned meta-alera in to that cloned directory and checked out its krogoth branch. Then modified conf/local.conf to choose the real-time kernel. After this it was, effectively:

      $ bitbake virtual/bootloader
      $ bitbake virtual/kernel
      $ bitbake core-image-minimal

      I also

      $ bitbake meta-toolchain

      One issue I ran into was that a shell script failed building RPM packages. There was a regular expression that was failing:

      DEBUG: Executing shell function BUILDSPEC
      error: line 4: invalid tag value("^[A-Za-z0-9+._]+$") Release: Release: r2015.11-2

      I changed local.conf to use .deb instead and everything built. Now I'm about to try the SD card.

      What confused me was that I didn't realize that the cyclone5 kernel only required the DTB for de0-nano-soc support (which is produced when the kernel is built).

      Hats off to the Yocto crowd and to you for replying. It's a little rough the first time through.