CycloneV: Programming FPGA from U-Boot

I have been using this guide to build an SD Card image to boot Linux on CycloneV.


One of the shortcomings of the guide appears to be that it does not include instructions on how to program the FPGA from u-boot in the CycloneV workflow. I have gotten around this using a boot script and modifying u-boot to run the script before booting the kernel.

echo --- Programming FPGA ---
echo -----Loading image------
# load rbf from FAT partition into memory
fatload mmc 0:1 ${fpgadata} socfpga.rbf;
# program FPGA
echo -----Print filesize-----
printenv filesize;
echo -----Program FPGA-------
fpga load 0 ${fpgadata} ${filesize};
# enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges
echo -----Enabling IFs--------
bridge enable;

I receive the following output during uboot operation before the kernel begins uncompressing and booting

Hit any key to stop autoboot: 0
449 bytes read in 3 ms (145.5 KiB/s)
Executing script at 02000000
— Programming FPGA —
-----Loading image------
7007204 bytes read in 366 ms (18.3 MiB/s)
-----Print filesize-----
filesize=6aebe4
-----Program FPGA-------
Command ‘load’ failed: Error -6
-----Enabling IFs--------
switch to partitions #0, OK
mmc0 is current device

After boot, I look at the fpga manager sysfs utility and see

root@cyclone5:~# cat /sys/class/fpga_manager/fpga0/state
write init

I was wondering if anyone has worked with CycloneV u-boot and might be able to tell what this error means and how to get around it.

Hello @jackfrye11,
Yours script looks right, it has the form that it should have.
The error could happen due to many reasons:

  1. The RBF file is generated in a form which does not corresponde with setting of Your hardware. The switches of the board need to be set in a proper positions. E.g. I use standard non-compressed RBF files, so I have to use FPGA MSEL switches “101011”.

  2. Some U-boot variables used at Your script has got wrong value. Try to get to the U-boot command line and print variables with printenv command.

  3. I have to use

    run bridge_enable_handoff;

    instead of Yours

    bridge enable;

    but it could depends on version of U-boot.

I just recommend to create new U-boot variable with name of target RBF file, e.g.

setenv RBF socfpga_test.rbf

and replace with it static RBF filename at boot script

fatload mmc 0:1 $fpgadata> $RBF

so You will not need to recompile and replace boot-script each time to change content of FPGA. Just change value of the variable. It is very fajn soution :sunny:.
Hope it could help You a bit.
Best wishes,
Yours Jan Konečný.

@JanKonecny

I wanted to address each of your possibilities. I believe only possibility two can be the cause.

  1. The RBF file is generated in a form which does not corresponde with setting of Your hardware. The switches of the board need to be set in a proper positions. E.g. I use standard non-compressed RBF files, so I have to use FPGA MSEL switches “101011”.

I am using a DE1-SoC board from Terasic. According to their user guide

 A brief view on FPGA manager
The FPGA manager in HPS configures the FPGA fabric from HPS. It also monitors the state of
FPGA and drives or samples signals to or from the FPGA fabric. The application software is
provided to configure FPGA through the FPGA manager. The FPGA configuration data is stored in
the file with .rbf extension. The MSEL[4:0] must be set to 01010 or 01110 before executing the
application software on HPS.

I do have a correct configuration, which is MSEL[4:0]=01010. Unless I am misreading this doc or my switches, I think this is not a concern. Perhaps there is a compression vs. non-compression of RBF issue. I do not know how to check whether the RBF is compressed or where to find out whether or not it should be, but this seems like a stretch.

  1. Some U-boot variables used at Your script has got wrong value. Try to get to the U-boot command line and print variables with printenv command.

Well, I tried a printenv on the size of the rbf file and it matches the size listed for the file in Nautilus file view in Ubuntu. What other variables could I print to check?

  1. I have to use

run bridge_enable_handoff;

instead of Yours

bridge enable;

but it could depends on version of U-boot.

Maybe, but that part comes after the FPGA fails to load. I may end up seeing another bug with the interfaces that this will fix, but I am focused on getting that error to go away on FPGA load first.

Any thoughts on debugging steps? How can I check compression of RBF?

I am sorry, but I suppose there is no tool to find out parameters of already generated RBF file at Quartus Prime. One could compare filesizes only but this not give You all the information.
However, the size of Your RBF file is exatly the same as non-compresed RBF file for Cyclone V. So, this variable should be right.
Could You also confirm that FAT partition is really the 1st partition, it contains the file and that $fpgadata is 0x2000000?
I am not sure about it but using curly-brackets should be used at U-boot within variables that are executed with run command, not within parameters of commands, aren’t they?

According to fdisk, this is the way my sdcard is partitioned

Command (m for help): p
Disk /dev/mmcblk0: 14.5 GiB, 15590227968 bytes, 30449664 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xe8c97bd9

Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 2048 206848 204801 100M b W95 FAT32
/dev/mmcblk0p2 206849 821249 614401 300M 83 Linux
/dev/mmcblk0p3 821250 841730 20481 10M a2 unknown

I am not sure if this is right. I used the Python script mentioned in the guide in my first post to load the files onto the sd card and format it. In actuality, I had to find an updated script compatible with a newer Python version. That script can be found here.

https://raw.githubusercontent.com/rsarwar87/altera-soc-rootfs/master/make_sdimage2.py

Perhaps the script is improperly formatting the partitions. I appear to have run this command
$ sudo ./make_sdimage.py -f -P u-boot-with-spl.sfp,num=3,format=raw,size=10M,type=A2 -P sdfs/*,num=1,format=vfat,size=100M -P rootfs/*,num=2,format=ext3,size=300M -s 512M -n sdcard_cv.img
but I am not sure how the rbf got onto the sdcard.

Does the partitioning format look right or are there issues there?

Hello @jackfrye11,
well FAT partition is the 1st one, it is OK.
The script make_sdimage.py is usefull but to comperhand what it does I recommend You to create SD card manuály accroding to this great tutorial:


As far as You do not know, how RBF file got onto SD card, are You really really sure that it is placed there? Just insert SD card into Your desktop or notebook and look at the FAT partition (i.e. that disk which is 100 MB).
I am sorry, I still could not find where the error codes of U-Boot commands are placed.

@JanKonecny
I tried reformatting my SD Card according to the guide you posted. Instead of putting preloader-mkpimage.bin on the A2 then u-boot.img on the VFAT partition, I simply placed u-boot-with-spl.sfp on A2. ( u-boot-with-spl.sfp contains both preloader and uboot per this guide) https://rocketboards.org/foswiki/Documentation/BuildingBootloader#C._Prepare_SD_Card_Image

I only went up to step 7 and had a couple differences based on the files I generated from the first guide.

I got the following output when I booted.

U-Boot SPL 2019.04-00246-g0c3e6f623d-dirty (Dec 27 2019 - 13:35:52 -0500)
Trying to boot from MMC1

U-Boot 2019.04-00246-g0c3e6f623d-dirty (Dec 27 2019 - 13:35:52 -0500)

CPU: Altera SoCFPGA Platform
FPGA: Altera Cyclone V, SE/A5 or SX/C5 or ST/D5, version 0x0
BOOT: SD/MMC Internal Transceiver (3.0V)
Watchdog enabled
DRAM: 1 GiB
MMC: dwmmc0@ff704000: 0
Loading Environment from MMC… *** Warning - bad CRC, using default environment

In: serial
Out: serial
Err: serial
Model: Altera SOCFPGA Cyclone V SoC Development Kit
Net:
Warning: ethernet@ff702000 (eth0) using random MAC address - a2:77:81:44:49:7a
eth0: ethernet@ff702000
Hit any key to stop autoboot: 0
309 bytes read in 4 ms (75.2 KiB/s)

Executing script at 02000000

— Programming FPGA —
7007204 bytes read in 363 ms (18.4 MiB/s)
Command ‘load’ failed: Error -6
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1…
28016 bytes read in 6 ms (4.5 MiB/s)
starting USB…
USB0: scanning bus 0 for devices… 2 USB Device(s) found
scanning usb for storage devices… 0 Storage Device(s) found
ethernet@ff702000 Waiting for PHY auto negotiation to complete… TIMEOUT !
Could not initialize PHY ethernet@ff702000
missing environment variable: pxeuuid
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/00000000
ethernet@ff702000 Waiting for PHY auto negotiation to complete… TIMEOUT !

The issue is clearly not how the SD Card is formatted. I would think the issue has to do with either

  1. The format of the RBF
  2. How U-Boot is attempting to load the RBF into the Cyclone V FPGA portion
  3. Differences between u-boot-with-spl.sfp and u-boot.img/preloader-mkpimage.bin

Do you agree? What could be my next step for debug? If you find the u-boot source with the error codes, please let me know. I tried surfing the github, but could not find it with searches.

Well, I think that I have found it. The list of error codes is at file

{Quartus Project folder}/software/spl_bsp/uboot-socfpga/include/asm-generic/errno.h

Error -6 means “No such device or address”.

One more note: Preloader and U-Boot should be compiled and placed at SD card together (preloader compiled as the first one, U-boot as the second one). Mixing versions (means different hardware configurations) of preloader and U-Boot could cause very strange problems such as Yours.
I am sorry I could not help You in a better way.

@JanKonecny
I will try various hardware images and see what happens. I wonder if it is a compatibility issue with some combination of

  1. Quartus
  2. SOC EDS (generates the preloader)
  3. uboot-socfpga

Is there somewhere (or some combination of versions/branches) you have used with Cyclone V with success?